diff options
-rw-r--r-- | base58.h | 402 | ||||
-rw-r--r-- | bignum.h | 1050 | ||||
-rw-r--r-- | bugs.txt | 2 | ||||
-rw-r--r-- | build-msw.txt | 228 | ||||
-rw-r--r-- | build-osx.txt | 434 | ||||
-rw-r--r-- | build-unix.txt | 166 | ||||
-rw-r--r-- | db.cpp | 1474 | ||||
-rw-r--r-- | db.h | 808 | ||||
-rw-r--r-- | headers.h | 254 | ||||
-rw-r--r-- | init.cpp | 1356 | ||||
-rw-r--r-- | init.h | 14 | ||||
-rw-r--r-- | irc.cpp | 648 | ||||
-rw-r--r-- | irc.h | 16 | ||||
-rw-r--r-- | json/LICENSE.txt | 48 | ||||
-rw-r--r-- | json/json_spirit.h | 36 | ||||
-rw-r--r-- | json/json_spirit_error_position.h | 108 | ||||
-rw-r--r-- | json/json_spirit_reader.cpp | 274 | ||||
-rw-r--r-- | json/json_spirit_reader.h | 124 | ||||
-rw-r--r-- | json/json_spirit_reader_template.h | 1224 | ||||
-rw-r--r-- | json/json_spirit_stream_reader.h | 140 | ||||
-rw-r--r-- | json/json_spirit_utils.h | 122 | ||||
-rw-r--r-- | json/json_spirit_value.cpp | 16 | ||||
-rw-r--r-- | json/json_spirit_value.h | 1068 | ||||
-rw-r--r-- | json/json_spirit_writer.cpp | 190 | ||||
-rw-r--r-- | json/json_spirit_writer.h | 100 | ||||
-rw-r--r-- | json/json_spirit_writer_template.h | 490 | ||||
-rw-r--r-- | key.h | 336 | ||||
-rw-r--r-- | license.txt | 38 | ||||
-rw-r--r-- | locale/pt/LC_MESSAGES/bitcoin.po | 1614 | ||||
-rw-r--r-- | locale/readme.txt | 10 | ||||
-rw-r--r-- | main.cpp | 6248 | ||||
-rw-r--r-- | main.h | 2846 | ||||
-rw-r--r-- | makefile.mingw | 152 | ||||
-rw-r--r-- | makefile.osx | 130 | ||||
-rw-r--r-- | makefile.unix | 146 | ||||
-rw-r--r-- | makefile.vc | 214 | ||||
-rw-r--r-- | net.cpp | 2848 | ||||
-rw-r--r-- | net.h | 2104 | ||||
-rw-r--r-- | rpc.cpp | 1972 | ||||
-rw-r--r-- | rpc.h | 12 | ||||
-rw-r--r-- | script.cpp | 2268 | ||||
-rw-r--r-- | script.h | 1284 | ||||
-rw-r--r-- | serialize.h | 2350 | ||||
-rw-r--r-- | setup.nsi | 312 | ||||
-rw-r--r-- | sha.cpp | 1108 | ||||
-rw-r--r-- | sha.h | 354 | ||||
-rw-r--r-- | strlcpy.h | 168 | ||||
-rw-r--r-- | ui.cpp | 5090 | ||||
-rw-r--r-- | ui.h | 758 | ||||
-rw-r--r-- | ui.rc | 30 | ||||
-rw-r--r-- | uibase.cpp | 2146 | ||||
-rw-r--r-- | uibase.h | 844 | ||||
-rw-r--r-- | uint256.h | 1514 | ||||
-rw-r--r-- | uiproject.fbp | 12664 | ||||
-rw-r--r-- | util.cpp | 1430 | ||||
-rw-r--r-- | util.h | 1092 | ||||
-rw-r--r-- | xpm/addressbook16.xpm | 556 | ||||
-rw-r--r-- | xpm/addressbook20.xpm | 564 | ||||
-rw-r--r-- | xpm/check.xpm | 82 | ||||
-rw-r--r-- | xpm/send16.xpm | 556 | ||||
-rw-r--r-- | xpm/send16noshadow.xpm | 556 | ||||
-rw-r--r-- | xpm/send20.xpm | 564 |
62 files changed, 32876 insertions, 32876 deletions
@@ -1,201 +1,201 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
-
-
-//
-// Why base-58 instead of standard base-64 encoding?
-// - Don't want 0OIl characters that look the same in some fonts and
-// could be used to create visually identical looking account numbers.
-// - A string with non-alphanumeric characters is not as easily accepted as an account number.
-// - E-mail usually won't line-break if there's no punctuation to break at.
-// - Doubleclicking selects the whole number as one word if it's all alphanumeric.
-//
-
-
-static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
-
-
-inline 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
- 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 string
- string str;
- 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 string to big endian
- reverse(str.begin(), str.end());
- return str;
-}
-
-inline string EncodeBase58(const vector<unsigned char>& vch)
-{
- return EncodeBase58(&vch[0], &vch[0] + vch.size());
-}
-
-inline bool DecodeBase58(const char* psz, 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
- 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;
-}
-
-inline bool DecodeBase58(const string& str, vector<unsigned char>& vchRet)
-{
- return DecodeBase58(str.c_str(), vchRet);
-}
-
-
-
-
-
-inline string EncodeBase58Check(const vector<unsigned char>& vchIn)
-{
- // add 4-byte hash check to the end
- vector<unsigned char> vch(vchIn);
- uint256 hash = Hash(vch.begin(), vch.end());
- vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4);
- return EncodeBase58(vch);
-}
-
-inline bool DecodeBase58Check(const char* psz, vector<unsigned char>& vchRet)
-{
- if (!DecodeBase58(psz, vchRet))
- return false;
- if (vchRet.size() < 4)
- {
- vchRet.clear();
- return false;
- }
- 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);
- return true;
-}
-
-inline bool DecodeBase58Check(const string& str, vector<unsigned char>& vchRet)
-{
- return DecodeBase58Check(str.c_str(), vchRet);
-}
-
-
-
-
-
-
-static const unsigned char ADDRESSVERSION = 0;
-
-inline string Hash160ToAddress(uint160 hash160)
-{
- // add 1-byte version number to the front
- vector<unsigned char> vch(1, ADDRESSVERSION);
- vch.insert(vch.end(), UBEGIN(hash160), UEND(hash160));
- return EncodeBase58Check(vch);
-}
-
-inline bool AddressToHash160(const char* psz, uint160& hash160Ret)
-{
- vector<unsigned char> vch;
- if (!DecodeBase58Check(psz, vch))
- return false;
- if (vch.empty())
- return false;
- unsigned char nVersion = vch[0];
- if (vch.size() != sizeof(hash160Ret) + 1)
- return false;
- memcpy(&hash160Ret, &vch[1], sizeof(hash160Ret));
- return (nVersion <= ADDRESSVERSION);
-}
-
-inline bool AddressToHash160(const string& str, uint160& hash160Ret)
-{
- return AddressToHash160(str.c_str(), hash160Ret);
-}
-
-inline bool IsValidBitcoinAddress(const char* psz)
-{
- uint160 hash160;
- return AddressToHash160(psz, hash160);
-}
-
-inline bool IsValidBitcoinAddress(const string& str)
-{
- return IsValidBitcoinAddress(str.c_str());
-}
-
-
-
-
-inline string PubKeyToAddress(const vector<unsigned char>& vchPubKey)
-{
- return Hash160ToAddress(Hash160(vchPubKey));
-}
+// Copyright (c) 2009-2010 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + + +// +// Why base-58 instead of standard base-64 encoding? +// - Don't want 0OIl characters that look the same in some fonts and +// could be used to create visually identical looking account numbers. +// - A string with non-alphanumeric characters is not as easily accepted as an account number. +// - E-mail usually won't line-break if there's no punctuation to break at. +// - Doubleclicking selects the whole number as one word if it's all alphanumeric. +// + + +static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; + + +inline 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 + 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 string + string str; + 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 string to big endian + reverse(str.begin(), str.end()); + return str; +} + +inline string EncodeBase58(const vector<unsigned char>& vch) +{ + return EncodeBase58(&vch[0], &vch[0] + vch.size()); +} + +inline bool DecodeBase58(const char* psz, 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 + 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; +} + +inline bool DecodeBase58(const string& str, vector<unsigned char>& vchRet) +{ + return DecodeBase58(str.c_str(), vchRet); +} + + + + + +inline string EncodeBase58Check(const vector<unsigned char>& vchIn) +{ + // add 4-byte hash check to the end + vector<unsigned char> vch(vchIn); + uint256 hash = Hash(vch.begin(), vch.end()); + vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4); + return EncodeBase58(vch); +} + +inline bool DecodeBase58Check(const char* psz, vector<unsigned char>& vchRet) +{ + if (!DecodeBase58(psz, vchRet)) + return false; + if (vchRet.size() < 4) + { + vchRet.clear(); + return false; + } + 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); + return true; +} + +inline bool DecodeBase58Check(const string& str, vector<unsigned char>& vchRet) +{ + return DecodeBase58Check(str.c_str(), vchRet); +} + + + + + + +static const unsigned char ADDRESSVERSION = 0; + +inline string Hash160ToAddress(uint160 hash160) +{ + // add 1-byte version number to the front + vector<unsigned char> vch(1, ADDRESSVERSION); + vch.insert(vch.end(), UBEGIN(hash160), UEND(hash160)); + return EncodeBase58Check(vch); +} + +inline bool AddressToHash160(const char* psz, uint160& hash160Ret) +{ + vector<unsigned char> vch; + if (!DecodeBase58Check(psz, vch)) + return false; + if (vch.empty()) + return false; + unsigned char nVersion = vch[0]; + if (vch.size() != sizeof(hash160Ret) + 1) + return false; + memcpy(&hash160Ret, &vch[1], sizeof(hash160Ret)); + return (nVersion <= ADDRESSVERSION); +} + +inline bool AddressToHash160(const string& str, uint160& hash160Ret) +{ + return AddressToHash160(str.c_str(), hash160Ret); +} + +inline bool IsValidBitcoinAddress(const char* psz) +{ + uint160 hash160; + return AddressToHash160(psz, hash160); +} + +inline bool IsValidBitcoinAddress(const string& str) +{ + return IsValidBitcoinAddress(str.c_str()); +} + + + + +inline string PubKeyToAddress(const vector<unsigned char>& vchPubKey) +{ + return Hash160ToAddress(Hash160(vchPubKey)); +} @@ -1,525 +1,525 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
-
-#include <stdexcept>
-#include <vector>
-#include <openssl/bn.h>
-
-
-
-
-
-class bignum_error : public std::runtime_error
-{
-public:
- explicit bignum_error(const std::string& str) : std::runtime_error(str) {}
-};
-
-
-
-class CAutoBN_CTX
-{
-protected:
- BN_CTX* pctx;
- BN_CTX* operator=(BN_CTX* pnew) { return pctx = pnew; }
-
-public:
- CAutoBN_CTX()
- {
- pctx = BN_CTX_new();
- if (pctx == NULL)
- throw bignum_error("CAutoBN_CTX : BN_CTX_new() returned NULL");
- }
-
- ~CAutoBN_CTX()
- {
- if (pctx != NULL)
- BN_CTX_free(pctx);
- }
-
- operator BN_CTX*() { return pctx; }
- BN_CTX& operator*() { return *pctx; }
- BN_CTX** operator&() { return &pctx; }
- bool operator!() { return (pctx == NULL); }
-};
-
-
-
-class CBigNum : public BIGNUM
-{
-public:
- CBigNum()
- {
- BN_init(this);
- }
-
- CBigNum(const CBigNum& b)
- {
- BN_init(this);
- if (!BN_copy(this, &b))
- {
- BN_clear_free(this);
- throw bignum_error("CBigNum::CBigNum(const CBigNum&) : BN_copy failed");
- }
- }
-
- CBigNum& operator=(const CBigNum& b)
- {
- if (!BN_copy(this, &b))
- throw bignum_error("CBigNum::operator= : BN_copy failed");
- return (*this);
- }
-
- ~CBigNum()
- {
- BN_clear_free(this);
- }
-
- CBigNum(char n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
- CBigNum(short n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
- CBigNum(int n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
- CBigNum(long n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
- CBigNum(int64 n) { BN_init(this); setint64(n); }
- CBigNum(unsigned char n) { BN_init(this); setulong(n); }
- CBigNum(unsigned short n) { BN_init(this); setulong(n); }
- CBigNum(unsigned int n) { BN_init(this); setulong(n); }
- CBigNum(unsigned long n) { BN_init(this); setulong(n); }
- CBigNum(uint64 n) { BN_init(this); setuint64(n); }
- explicit CBigNum(uint256 n) { BN_init(this); setuint256(n); }
-
- explicit CBigNum(const std::vector<unsigned char>& vch)
- {
- BN_init(this);
- setvch(vch);
- }
-
- void setulong(unsigned long n)
- {
- if (!BN_set_word(this, n))
- throw bignum_error("CBigNum conversion from unsigned long : BN_set_word failed");
- }
-
- unsigned long getulong() const
- {
- return BN_get_word(this);
- }
-
- unsigned int getuint() const
- {
- return BN_get_word(this);
- }
-
- int getint() const
- {
- unsigned long n = BN_get_word(this);
- if (!BN_is_negative(this))
- return (n > INT_MAX ? INT_MAX : n);
- else
- return (n > INT_MAX ? INT_MIN : -(int)n);
- }
-
- void setint64(int64 n)
- {
- unsigned char pch[sizeof(n) + 6];
- unsigned char* p = pch + 4;
- bool fNegative = false;
- if (n < (int64)0)
- {
- n = -n;
- fNegative = true;
- }
- bool fLeadingZeroes = true;
- for (int i = 0; i < 8; i++)
- {
- unsigned char c = (n >> 56) & 0xff;
- n <<= 8;
- if (fLeadingZeroes)
- {
- if (c == 0)
- continue;
- if (c & 0x80)
- *p++ = (fNegative ? 0x80 : 0);
- else if (fNegative)
- c |= 0x80;
- fLeadingZeroes = false;
- }
- *p++ = c;
- }
- unsigned int nSize = p - (pch + 4);
- pch[0] = (nSize >> 24) & 0xff;
- pch[1] = (nSize >> 16) & 0xff;
- pch[2] = (nSize >> 8) & 0xff;
- pch[3] = (nSize) & 0xff;
- BN_mpi2bn(pch, p - pch, this);
- }
-
- void setuint64(uint64 n)
- {
- unsigned char pch[sizeof(n) + 6];
- unsigned char* p = pch + 4;
- bool fLeadingZeroes = true;
- for (int i = 0; i < 8; i++)
- {
- unsigned char c = (n >> 56) & 0xff;
- n <<= 8;
- if (fLeadingZeroes)
- {
- if (c == 0)
- continue;
- if (c & 0x80)
- *p++ = 0;
- fLeadingZeroes = false;
- }
- *p++ = c;
- }
- unsigned int nSize = p - (pch + 4);
- pch[0] = (nSize >> 24) & 0xff;
- pch[1] = (nSize >> 16) & 0xff;
- pch[2] = (nSize >> 8) & 0xff;
- pch[3] = (nSize) & 0xff;
- BN_mpi2bn(pch, p - pch, this);
- }
-
- void setuint256(uint256 n)
- {
- unsigned char pch[sizeof(n) + 6];
- unsigned char* p = pch + 4;
- bool fLeadingZeroes = true;
- unsigned char* pbegin = (unsigned char*)&n;
- unsigned char* psrc = pbegin + sizeof(n);
- while (psrc != pbegin)
- {
- unsigned char c = *(--psrc);
- if (fLeadingZeroes)
- {
- if (c == 0)
- continue;
- if (c & 0x80)
- *p++ = 0;
- fLeadingZeroes = false;
- }
- *p++ = c;
- }
- unsigned int nSize = p - (pch + 4);
- pch[0] = (nSize >> 24) & 0xff;
- pch[1] = (nSize >> 16) & 0xff;
- pch[2] = (nSize >> 8) & 0xff;
- pch[3] = (nSize >> 0) & 0xff;
- BN_mpi2bn(pch, p - pch, this);
- }
-
- uint256 getuint256()
- {
- unsigned int nSize = BN_bn2mpi(this, NULL);
- if (nSize < 4)
- return 0;
- std::vector<unsigned char> vch(nSize);
- BN_bn2mpi(this, &vch[0]);
- if (vch.size() > 4)
- vch[4] &= 0x7f;
- uint256 n = 0;
- for (int i = 0, j = vch.size()-1; i < sizeof(n) && j >= 4; i++, j--)
- ((unsigned char*)&n)[i] = vch[j];
- return n;
- }
-
- void setvch(const std::vector<unsigned char>& vch)
- {
- std::vector<unsigned char> vch2(vch.size() + 4);
- unsigned int nSize = vch.size();
- vch2[0] = (nSize >> 24) & 0xff;
- vch2[1] = (nSize >> 16) & 0xff;
- vch2[2] = (nSize >> 8) & 0xff;
- vch2[3] = (nSize >> 0) & 0xff;
- reverse_copy(vch.begin(), vch.end(), vch2.begin() + 4);
- BN_mpi2bn(&vch2[0], vch2.size(), this);
- }
-
- std::vector<unsigned char> getvch() const
- {
- unsigned int nSize = BN_bn2mpi(this, NULL);
- if (nSize < 4)
- return std::vector<unsigned char>();
- std::vector<unsigned char> vch(nSize);
- BN_bn2mpi(this, &vch[0]);
- vch.erase(vch.begin(), vch.begin() + 4);
- reverse(vch.begin(), vch.end());
- return vch;
- }
-
- CBigNum& SetCompact(unsigned int nCompact)
- {
- unsigned int nSize = nCompact >> 24;
- std::vector<unsigned char> vch(4 + nSize);
- vch[3] = nSize;
- if (nSize >= 1) vch[4] = (nCompact >> 16) & 0xff;
- if (nSize >= 2) vch[5] = (nCompact >> 8) & 0xff;
- if (nSize >= 3) vch[6] = (nCompact >> 0) & 0xff;
- BN_mpi2bn(&vch[0], vch.size(), this);
- return *this;
- }
-
- unsigned int GetCompact() const
- {
- unsigned int nSize = BN_bn2mpi(this, NULL);
- std::vector<unsigned char> vch(nSize);
- nSize -= 4;
- BN_bn2mpi(this, &vch[0]);
- unsigned int nCompact = nSize << 24;
- if (nSize >= 1) nCompact |= (vch[4] << 16);
- if (nSize >= 2) nCompact |= (vch[5] << 8);
- if (nSize >= 3) nCompact |= (vch[6] << 0);
- return nCompact;
- }
-
- void SetHex(const std::string& str)
- {
- // skip 0x
- const char* psz = str.c_str();
- while (isspace(*psz))
- psz++;
- bool fNegative = false;
- if (*psz == '-')
- {
- fNegative = true;
- psz++;
- }
- if (psz[0] == '0' && tolower(psz[1]) == 'x')
- psz += 2;
- while (isspace(*psz))
- psz++;
-
- // hex string to bignum
- static char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 };
- *this = 0;
- while (isxdigit(*psz))
- {
- *this <<= 4;
- int n = phexdigit[*psz++];
- *this += n;
- }
- if (fNegative)
- *this = 0 - *this;
- }
-
- std::string ToString(int nBase=10) const
- {
- CAutoBN_CTX pctx;
- CBigNum bnBase = nBase;
- CBigNum bn0 = 0;
- string str;
- CBigNum bn = *this;
- BN_set_negative(&bn, false);
- CBigNum dv;
- CBigNum rem;
- if (BN_cmp(&bn, &bn0) == 0)
- return "0";
- while (BN_cmp(&bn, &bn0) > 0)
- {
- if (!BN_div(&dv, &rem, &bn, &bnBase, pctx))
- throw bignum_error("CBigNum::ToString() : BN_div failed");
- bn = dv;
- unsigned int c = rem.getulong();
- str += "0123456789abcdef"[c];
- }
- if (BN_is_negative(this))
- str += "-";
- reverse(str.begin(), str.end());
- return str;
- }
-
- std::string GetHex() const
- {
- return ToString(16);
- }
-
- unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const
- {
- return ::GetSerializeSize(getvch(), nType, nVersion);
- }
-
- template<typename Stream>
- void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const
- {
- ::Serialize(s, getvch(), nType, nVersion);
- }
-
- template<typename Stream>
- void Unserialize(Stream& s, int nType=0, int nVersion=VERSION)
- {
- vector<unsigned char> vch;
- ::Unserialize(s, vch, nType, nVersion);
- setvch(vch);
- }
-
-
- bool operator!() const
- {
- return BN_is_zero(this);
- }
-
- CBigNum& operator+=(const CBigNum& b)
- {
- if (!BN_add(this, this, &b))
- throw bignum_error("CBigNum::operator+= : BN_add failed");
- return *this;
- }
-
- CBigNum& operator-=(const CBigNum& b)
- {
- *this = *this - b;
- return *this;
- }
-
- CBigNum& operator*=(const CBigNum& b)
- {
- CAutoBN_CTX pctx;
- if (!BN_mul(this, this, &b, pctx))
- throw bignum_error("CBigNum::operator*= : BN_mul failed");
- return *this;
- }
-
- CBigNum& operator/=(const CBigNum& b)
- {
- *this = *this / b;
- return *this;
- }
-
- CBigNum& operator%=(const CBigNum& b)
- {
- *this = *this % b;
- return *this;
- }
-
- CBigNum& operator<<=(unsigned int shift)
- {
- if (!BN_lshift(this, this, shift))
- throw bignum_error("CBigNum:operator<<= : BN_lshift failed");
- return *this;
- }
-
- CBigNum& operator>>=(unsigned int shift)
- {
- // Note: BN_rshift segfaults on 64-bit ubuntu 9.10 if 2^shift is greater than the number
- if (!BN_rshift(this, this, shift))
- throw bignum_error("CBigNum:operator>>= : BN_rshift failed");
- return *this;
- }
-
-
- CBigNum& operator++()
- {
- // prefix operator
- if (!BN_add(this, this, BN_value_one()))
- throw bignum_error("CBigNum::operator++ : BN_add failed");
- return *this;
- }
-
- const CBigNum operator++(int)
- {
- // postfix operator
- const CBigNum ret = *this;
- ++(*this);
- return ret;
- }
-
- CBigNum& operator--()
- {
- // prefix operator
- CBigNum r;
- if (!BN_sub(&r, this, BN_value_one()))
- throw bignum_error("CBigNum::operator-- : BN_sub failed");
- *this = r;
- return *this;
- }
-
- const CBigNum operator--(int)
- {
- // postfix operator
- const CBigNum ret = *this;
- --(*this);
- return ret;
- }
-
-
- friend inline const CBigNum operator-(const CBigNum& a, const CBigNum& b);
- friend inline const CBigNum operator/(const CBigNum& a, const CBigNum& b);
- friend inline const CBigNum operator%(const CBigNum& a, const CBigNum& b);
-};
-
-
-
-inline const CBigNum operator+(const CBigNum& a, const CBigNum& b)
-{
- CBigNum r;
- if (!BN_add(&r, &a, &b))
- throw bignum_error("CBigNum::operator+ : BN_add failed");
- return r;
-}
-
-inline const CBigNum operator-(const CBigNum& a, const CBigNum& b)
-{
- CBigNum r;
- if (!BN_sub(&r, &a, &b))
- throw bignum_error("CBigNum::operator- : BN_sub failed");
- return r;
-}
-
-inline const CBigNum operator-(const CBigNum& a)
-{
- CBigNum r(a);
- BN_set_negative(&r, !BN_is_negative(&r));
- return r;
-}
-
-inline const CBigNum operator*(const CBigNum& a, const CBigNum& b)
-{
- CAutoBN_CTX pctx;
- CBigNum r;
- if (!BN_mul(&r, &a, &b, pctx))
- throw bignum_error("CBigNum::operator* : BN_mul failed");
- return r;
-}
-
-inline const CBigNum operator/(const CBigNum& a, const CBigNum& b)
-{
- CAutoBN_CTX pctx;
- CBigNum r;
- if (!BN_div(&r, NULL, &a, &b, pctx))
- throw bignum_error("CBigNum::operator/ : BN_div failed");
- return r;
-}
-
-inline const CBigNum operator%(const CBigNum& a, const CBigNum& b)
-{
- CAutoBN_CTX pctx;
- CBigNum r;
- if (!BN_mod(&r, &a, &b, pctx))
- throw bignum_error("CBigNum::operator% : BN_div failed");
- return r;
-}
-
-inline const CBigNum operator<<(const CBigNum& a, unsigned int shift)
-{
- CBigNum r;
- if (!BN_lshift(&r, &a, shift))
- throw bignum_error("CBigNum:operator<< : BN_lshift failed");
- return r;
-}
-
-inline const CBigNum operator>>(const CBigNum& a, unsigned int shift)
-{
- CBigNum r;
- // Note: BN_rshift segfaults on 64-bit ubuntu 9.10 if 2^shift is greater than the number
- if (!BN_rshift(&r, &a, shift))
- throw bignum_error("CBigNum:operator>> : BN_rshift failed");
- return r;
-}
-
-inline bool operator==(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) == 0); }
-inline bool operator!=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) != 0); }
-inline bool operator<=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) <= 0); }
-inline bool operator>=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) >= 0); }
-inline bool operator<(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) < 0); }
-inline bool operator>(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) > 0); }
+// Copyright (c) 2009-2010 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +#include <stdexcept> +#include <vector> +#include <openssl/bn.h> + + + + + +class bignum_error : public std::runtime_error +{ +public: + explicit bignum_error(const std::string& str) : std::runtime_error(str) {} +}; + + + +class CAutoBN_CTX +{ +protected: + BN_CTX* pctx; + BN_CTX* operator=(BN_CTX* pnew) { return pctx = pnew; } + +public: + CAutoBN_CTX() + { + pctx = BN_CTX_new(); + if (pctx == NULL) + throw bignum_error("CAutoBN_CTX : BN_CTX_new() returned NULL"); + } + + ~CAutoBN_CTX() + { + if (pctx != NULL) + BN_CTX_free(pctx); + } + + operator BN_CTX*() { return pctx; } + BN_CTX& operator*() { return *pctx; } + BN_CTX** operator&() { return &pctx; } + bool operator!() { return (pctx == NULL); } +}; + + + +class CBigNum : public BIGNUM +{ +public: + CBigNum() + { + BN_init(this); + } + + CBigNum(const CBigNum& b) + { + BN_init(this); + if (!BN_copy(this, &b)) + { + BN_clear_free(this); + throw bignum_error("CBigNum::CBigNum(const CBigNum&) : BN_copy failed"); + } + } + + CBigNum& operator=(const CBigNum& b) + { + if (!BN_copy(this, &b)) + throw bignum_error("CBigNum::operator= : BN_copy failed"); + return (*this); + } + + ~CBigNum() + { + BN_clear_free(this); + } + + CBigNum(char n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); } + CBigNum(short n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); } + CBigNum(int n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); } + CBigNum(long n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); } + CBigNum(int64 n) { BN_init(this); setint64(n); } + CBigNum(unsigned char n) { BN_init(this); setulong(n); } + CBigNum(unsigned short n) { BN_init(this); setulong(n); } + CBigNum(unsigned int n) { BN_init(this); setulong(n); } + CBigNum(unsigned long n) { BN_init(this); setulong(n); } + CBigNum(uint64 n) { BN_init(this); setuint64(n); } + explicit CBigNum(uint256 n) { BN_init(this); setuint256(n); } + + explicit CBigNum(const std::vector<unsigned char>& vch) + { + BN_init(this); + setvch(vch); + } + + void setulong(unsigned long n) + { + if (!BN_set_word(this, n)) + throw bignum_error("CBigNum conversion from unsigned long : BN_set_word failed"); + } + + unsigned long getulong() const + { + return BN_get_word(this); + } + + unsigned int getuint() const + { + return BN_get_word(this); + } + + int getint() const + { + unsigned long n = BN_get_word(this); + if (!BN_is_negative(this)) + return (n > INT_MAX ? INT_MAX : n); + else + return (n > INT_MAX ? INT_MIN : -(int)n); + } + + void setint64(int64 n) + { + unsigned char pch[sizeof(n) + 6]; + unsigned char* p = pch + 4; + bool fNegative = false; + if (n < (int64)0) + { + n = -n; + fNegative = true; + } + bool fLeadingZeroes = true; + for (int i = 0; i < 8; i++) + { + unsigned char c = (n >> 56) & 0xff; + n <<= 8; + if (fLeadingZeroes) + { + if (c == 0) + continue; + if (c & 0x80) + *p++ = (fNegative ? 0x80 : 0); + else if (fNegative) + c |= 0x80; + fLeadingZeroes = false; + } + *p++ = c; + } + unsigned int nSize = p - (pch + 4); + pch[0] = (nSize >> 24) & 0xff; + pch[1] = (nSize >> 16) & 0xff; + pch[2] = (nSize >> 8) & 0xff; + pch[3] = (nSize) & 0xff; + BN_mpi2bn(pch, p - pch, this); + } + + void setuint64(uint64 n) + { + unsigned char pch[sizeof(n) + 6]; + unsigned char* p = pch + 4; + bool fLeadingZeroes = true; + for (int i = 0; i < 8; i++) + { + unsigned char c = (n >> 56) & 0xff; + n <<= 8; + if (fLeadingZeroes) + { + if (c == 0) + continue; + if (c & 0x80) + *p++ = 0; + fLeadingZeroes = false; + } + *p++ = c; + } + unsigned int nSize = p - (pch + 4); + pch[0] = (nSize >> 24) & 0xff; + pch[1] = (nSize >> 16) & 0xff; + pch[2] = (nSize >> 8) & 0xff; + pch[3] = (nSize) & 0xff; + BN_mpi2bn(pch, p - pch, this); + } + + void setuint256(uint256 n) + { + unsigned char pch[sizeof(n) + 6]; + unsigned char* p = pch + 4; + bool fLeadingZeroes = true; + unsigned char* pbegin = (unsigned char*)&n; + unsigned char* psrc = pbegin + sizeof(n); + while (psrc != pbegin) + { + unsigned char c = *(--psrc); + if (fLeadingZeroes) + { + if (c == 0) + continue; + if (c & 0x80) + *p++ = 0; + fLeadingZeroes = false; + } + *p++ = c; + } + unsigned int nSize = p - (pch + 4); + pch[0] = (nSize >> 24) & 0xff; + pch[1] = (nSize >> 16) & 0xff; + pch[2] = (nSize >> 8) & 0xff; + pch[3] = (nSize >> 0) & 0xff; + BN_mpi2bn(pch, p - pch, this); + } + + uint256 getuint256() + { + unsigned int nSize = BN_bn2mpi(this, NULL); + if (nSize < 4) + return 0; + std::vector<unsigned char> vch(nSize); + BN_bn2mpi(this, &vch[0]); + if (vch.size() > 4) + vch[4] &= 0x7f; + uint256 n = 0; + for (int i = 0, j = vch.size()-1; i < sizeof(n) && j >= 4; i++, j--) + ((unsigned char*)&n)[i] = vch[j]; + return n; + } + + void setvch(const std::vector<unsigned char>& vch) + { + std::vector<unsigned char> vch2(vch.size() + 4); + unsigned int nSize = vch.size(); + vch2[0] = (nSize >> 24) & 0xff; + vch2[1] = (nSize >> 16) & 0xff; + vch2[2] = (nSize >> 8) & 0xff; + vch2[3] = (nSize >> 0) & 0xff; + reverse_copy(vch.begin(), vch.end(), vch2.begin() + 4); + BN_mpi2bn(&vch2[0], vch2.size(), this); + } + + std::vector<unsigned char> getvch() const + { + unsigned int nSize = BN_bn2mpi(this, NULL); + if (nSize < 4) + return std::vector<unsigned char>(); + std::vector<unsigned char> vch(nSize); + BN_bn2mpi(this, &vch[0]); + vch.erase(vch.begin(), vch.begin() + 4); + reverse(vch.begin(), vch.end()); + return vch; + } + + CBigNum& SetCompact(unsigned int nCompact) + { + unsigned int nSize = nCompact >> 24; + std::vector<unsigned char> vch(4 + nSize); + vch[3] = nSize; + if (nSize >= 1) vch[4] = (nCompact >> 16) & 0xff; + if (nSize >= 2) vch[5] = (nCompact >> 8) & 0xff; + if (nSize >= 3) vch[6] = (nCompact >> 0) & 0xff; + BN_mpi2bn(&vch[0], vch.size(), this); + return *this; + } + + unsigned int GetCompact() const + { + unsigned int nSize = BN_bn2mpi(this, NULL); + std::vector<unsigned char> vch(nSize); + nSize -= 4; + BN_bn2mpi(this, &vch[0]); + unsigned int nCompact = nSize << 24; + if (nSize >= 1) nCompact |= (vch[4] << 16); + if (nSize >= 2) nCompact |= (vch[5] << 8); + if (nSize >= 3) nCompact |= (vch[6] << 0); + return nCompact; + } + + void SetHex(const std::string& str) + { + // skip 0x + const char* psz = str.c_str(); + while (isspace(*psz)) + psz++; + bool fNegative = false; + if (*psz == '-') + { + fNegative = true; + psz++; + } + if (psz[0] == '0' && tolower(psz[1]) == 'x') + psz += 2; + while (isspace(*psz)) + psz++; + + // hex string to bignum + static char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 }; + *this = 0; + while (isxdigit(*psz)) + { + *this <<= 4; + int n = phexdigit[*psz++]; + *this += n; + } + if (fNegative) + *this = 0 - *this; + } + + std::string ToString(int nBase=10) const + { + CAutoBN_CTX pctx; + CBigNum bnBase = nBase; + CBigNum bn0 = 0; + string str; + CBigNum bn = *this; + BN_set_negative(&bn, false); + CBigNum dv; + CBigNum rem; + if (BN_cmp(&bn, &bn0) == 0) + return "0"; + while (BN_cmp(&bn, &bn0) > 0) + { + if (!BN_div(&dv, &rem, &bn, &bnBase, pctx)) + throw bignum_error("CBigNum::ToString() : BN_div failed"); + bn = dv; + unsigned int c = rem.getulong(); + str += "0123456789abcdef"[c]; + } + if (BN_is_negative(this)) + str += "-"; + reverse(str.begin(), str.end()); + return str; + } + + std::string GetHex() const + { + return ToString(16); + } + + unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const + { + return ::GetSerializeSize(getvch(), nType, nVersion); + } + + template<typename Stream> + void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const + { + ::Serialize(s, getvch(), nType, nVersion); + } + + template<typename Stream> + void Unserialize(Stream& s, int nType=0, int nVersion=VERSION) + { + vector<unsigned char> vch; + ::Unserialize(s, vch, nType, nVersion); + setvch(vch); + } + + + bool operator!() const + { + return BN_is_zero(this); + } + + CBigNum& operator+=(const CBigNum& b) + { + if (!BN_add(this, this, &b)) + throw bignum_error("CBigNum::operator+= : BN_add failed"); + return *this; + } + + CBigNum& operator-=(const CBigNum& b) + { + *this = *this - b; + return *this; + } + + CBigNum& operator*=(const CBigNum& b) + { + CAutoBN_CTX pctx; + if (!BN_mul(this, this, &b, pctx)) + throw bignum_error("CBigNum::operator*= : BN_mul failed"); + return *this; + } + + CBigNum& operator/=(const CBigNum& b) + { + *this = *this / b; + return *this; + } + + CBigNum& operator%=(const CBigNum& b) + { + *this = *this % b; + return *this; + } + + CBigNum& operator<<=(unsigned int shift) + { + if (!BN_lshift(this, this, shift)) + throw bignum_error("CBigNum:operator<<= : BN_lshift failed"); + return *this; + } + + CBigNum& operator>>=(unsigned int shift) + { + // Note: BN_rshift segfaults on 64-bit ubuntu 9.10 if 2^shift is greater than the number + if (!BN_rshift(this, this, shift)) + throw bignum_error("CBigNum:operator>>= : BN_rshift failed"); + return *this; + } + + + CBigNum& operator++() + { + // prefix operator + if (!BN_add(this, this, BN_value_one())) + throw bignum_error("CBigNum::operator++ : BN_add failed"); + return *this; + } + + const CBigNum operator++(int) + { + // postfix operator + const CBigNum ret = *this; + ++(*this); + return ret; + } + + CBigNum& operator--() + { + // prefix operator + CBigNum r; + if (!BN_sub(&r, this, BN_value_one())) + throw bignum_error("CBigNum::operator-- : BN_sub failed"); + *this = r; + return *this; + } + + const CBigNum operator--(int) + { + // postfix operator + const CBigNum ret = *this; + --(*this); + return ret; + } + + + friend inline const CBigNum operator-(const CBigNum& a, const CBigNum& b); + friend inline const CBigNum operator/(const CBigNum& a, const CBigNum& b); + friend inline const CBigNum operator%(const CBigNum& a, const CBigNum& b); +}; + + + +inline const CBigNum operator+(const CBigNum& a, const CBigNum& b) +{ + CBigNum r; + if (!BN_add(&r, &a, &b)) + throw bignum_error("CBigNum::operator+ : BN_add failed"); + return r; +} + +inline const CBigNum operator-(const CBigNum& a, const CBigNum& b) +{ + CBigNum r; + if (!BN_sub(&r, &a, &b)) + throw bignum_error("CBigNum::operator- : BN_sub failed"); + return r; +} + +inline const CBigNum operator-(const CBigNum& a) +{ + CBigNum r(a); + BN_set_negative(&r, !BN_is_negative(&r)); + return r; +} + +inline const CBigNum operator*(const CBigNum& a, const CBigNum& b) +{ + CAutoBN_CTX pctx; + CBigNum r; + if (!BN_mul(&r, &a, &b, pctx)) + throw bignum_error("CBigNum::operator* : BN_mul failed"); + return r; +} + +inline const CBigNum operator/(const CBigNum& a, const CBigNum& b) +{ + CAutoBN_CTX pctx; + CBigNum r; + if (!BN_div(&r, NULL, &a, &b, pctx)) + throw bignum_error("CBigNum::operator/ : BN_div failed"); + return r; +} + +inline const CBigNum operator%(const CBigNum& a, const CBigNum& b) +{ + CAutoBN_CTX pctx; + CBigNum r; + if (!BN_mod(&r, &a, &b, pctx)) + throw bignum_error("CBigNum::operator% : BN_div failed"); + return r; +} + +inline const CBigNum operator<<(const CBigNum& a, unsigned int shift) +{ + CBigNum r; + if (!BN_lshift(&r, &a, shift)) + throw bignum_error("CBigNum:operator<< : BN_lshift failed"); + return r; +} + +inline const CBigNum operator>>(const CBigNum& a, unsigned int shift) +{ + CBigNum r; + // Note: BN_rshift segfaults on 64-bit ubuntu 9.10 if 2^shift is greater than the number + if (!BN_rshift(&r, &a, shift)) + throw bignum_error("CBigNum:operator>> : BN_rshift failed"); + return r; +} + +inline bool operator==(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) == 0); } +inline bool operator!=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) != 0); } +inline bool operator<=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) <= 0); } +inline bool operator>=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) >= 0); } +inline bool operator<(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) < 0); } +inline bool operator>(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) > 0); } @@ -1,2 +1,2 @@ -Known bugs:
+Known bugs: - Window flickers when blocks are added (problem with repainting?)
\ No newline at end of file diff --git a/build-msw.txt b/build-msw.txt index a3d9de6f75..cdb264f5e7 100644 --- a/build-msw.txt +++ b/build-msw.txt @@ -1,114 +1,114 @@ -Copyright (c) 2009-2010 Satoshi Nakamoto
-Distributed under the MIT/X11 software license, see the accompanying
-file license.txt or http://www.opensource.org/licenses/mit-license.php.
-This product includes software developed by the OpenSSL Project for use in
-the OpenSSL Toolkit (http://www.openssl.org/). This product includes
-cryptographic software written by Eric Young (eay@cryptsoft.com).
-
-
-WINDOWS BUILD NOTES
-===================
-
-Compilers Supported
--------------------
-MinGW GCC (recommended)
-
-MSVC 6.0 SP6: You'll need Boost version 1.34 because they dropped support
-for MSVC 6.0 after that. However, they didn't add Asio until 1.35.
-You should still be able to build with MSVC 6.0 by adding Asio to 1.34 by
-unpacking boost_asio_*.zip into the boost directory:
-http://sourceforge.net/projects/asio/files/asio
-
-MSVC 8.0 (2005) SP1 has been tested. Note: MSVC 7.0 and up have a habit of
-linking to runtime DLLs that are not installed on XP by default.
-
-
-Dependencies
-------------
-Libraries you need to download separately and build:
-
- default path download
-wxWidgets-2.9 \wxwidgets http://www.wxwidgets.org/downloads/
-OpenSSL \openssl http://www.openssl.org/source/
-Berkeley DB \db http://www.oracle.com/technology/software/products/berkeley-db/index.html
-Boost \boost http://www.boost.org/users/download/
-
-Their licenses:
-wxWidgets LGPL 2.1 with very liberal exceptions
-OpenSSL Old BSD license with the problematic advertising requirement
-Berkeley DB New BSD license with additional requirement that linked software must be free open source
-Boost MIT-like license
-
-Versions used in this release:
-MinGW GCC 3.4.5
-wxWidgets 2.9.0
-OpenSSL 0.9.8k
-Berkeley DB 4.7.25.NC
-Boost 1.42.1
-
-
-Notes
------
-The UI layout is edited with wxFormBuilder. The project file is
-uiproject.fbp. It generates uibase.cpp and uibase.h, which define base
-classes that do the rote work of constructing all the UI elements.
-
-The release is built with GCC and then "strip bitcoin.exe" to strip the debug
-symbols, which reduces the executable size by about 90%.
-
-
-wxWidgets
----------
-cd \wxwidgets\build\msw
-make -f makefile.gcc
- or
-nmake -f makefile.vc
-
-
-OpenSSL
--------
-Bitcoin does not use any encryption. If you want to do a no-everything
-build of OpenSSL to exclude encryption routines, a few patches are required.
-(instructions for OpenSSL v0.9.8k)
-
-Edit engines\e_gmp.c and engines\e_capi.c and add this #ifndef around
-the openssl/rsa.h include:
- #ifndef OPENSSL_NO_RSA
- #include <openssl/rsa.h>
- #endif
-
-Edit ms\mingw32.bat and replace the Configure line's parameters with this
-no-everything list. You have to put this in the batch file because batch
-files can't take more than nine command line parameters.
- perl Configure mingw threads no-rc2 no-rc4 no-rc5 no-idea no-des no-bf no-cast no-aes no-camellia no-seed no-rsa no-dh
-
-Also REM out the following line in ms\mingw32.bat after the mingw32-make
-line. The build fails after it's already finished building libeay32, which
-is all we care about, but the failure aborts the script before it runs
-dllwrap to generate libeay32.dll.
- REM if errorlevel 1 goto end
-
-Build
- cd \openssl
- ms\mingw32.bat
-
-If you want to use it with MSVC, generate the .lib file
- lib /machine:i386 /def:ms\libeay32.def /out:out\libeay32.lib
-
-
-Berkeley DB
------------
-Using MinGW and MSYS:
-cd \db\build_unix
-sh ../dist/configure --enable-mingw --enable-cxx
-make
-
-
-Boost
------
-download bjam.exe from
-http://sourceforge.net/project/showfiles.php?group_id=7586&package_id=72941
-cd \boost
-bjam toolset=gcc --build-type=complete stage
- or
-bjam toolset=msvc --build-type=complete stage
+Copyright (c) 2009-2010 Satoshi Nakamoto +Distributed under the MIT/X11 software license, see the accompanying +file license.txt or http://www.opensource.org/licenses/mit-license.php. +This product includes software developed by the OpenSSL Project for use in +the OpenSSL Toolkit (http://www.openssl.org/). This product includes +cryptographic software written by Eric Young (eay@cryptsoft.com). + + +WINDOWS BUILD NOTES +=================== + +Compilers Supported +------------------- +MinGW GCC (recommended) + +MSVC 6.0 SP6: You'll need Boost version 1.34 because they dropped support +for MSVC 6.0 after that. However, they didn't add Asio until 1.35. +You should still be able to build with MSVC 6.0 by adding Asio to 1.34 by +unpacking boost_asio_*.zip into the boost directory: +http://sourceforge.net/projects/asio/files/asio + +MSVC 8.0 (2005) SP1 has been tested. Note: MSVC 7.0 and up have a habit of +linking to runtime DLLs that are not installed on XP by default. + + +Dependencies +------------ +Libraries you need to download separately and build: + + default path download +wxWidgets-2.9 \wxwidgets http://www.wxwidgets.org/downloads/ +OpenSSL \openssl http://www.openssl.org/source/ +Berkeley DB \db http://www.oracle.com/technology/software/products/berkeley-db/index.html +Boost \boost http://www.boost.org/users/download/ + +Their licenses: +wxWidgets LGPL 2.1 with very liberal exceptions +OpenSSL Old BSD license with the problematic advertising requirement +Berkeley DB New BSD license with additional requirement that linked software must be free open source +Boost MIT-like license + +Versions used in this release: +MinGW GCC 3.4.5 +wxWidgets 2.9.0 +OpenSSL 0.9.8k +Berkeley DB 4.7.25.NC +Boost 1.42.1 + + +Notes +----- +The UI layout is edited with wxFormBuilder. The project file is +uiproject.fbp. It generates uibase.cpp and uibase.h, which define base +classes that do the rote work of constructing all the UI elements. + +The release is built with GCC and then "strip bitcoin.exe" to strip the debug +symbols, which reduces the executable size by about 90%. + + +wxWidgets +--------- +cd \wxwidgets\build\msw +make -f makefile.gcc + or +nmake -f makefile.vc + + +OpenSSL +------- +Bitcoin does not use any encryption. If you want to do a no-everything +build of OpenSSL to exclude encryption routines, a few patches are required. +(instructions for OpenSSL v0.9.8k) + +Edit engines\e_gmp.c and engines\e_capi.c and add this #ifndef around +the openssl/rsa.h include: + #ifndef OPENSSL_NO_RSA + #include <openssl/rsa.h> + #endif + +Edit ms\mingw32.bat and replace the Configure line's parameters with this +no-everything list. You have to put this in the batch file because batch +files can't take more than nine command line parameters. + perl Configure mingw threads no-rc2 no-rc4 no-rc5 no-idea no-des no-bf no-cast no-aes no-camellia no-seed no-rsa no-dh + +Also REM out the following line in ms\mingw32.bat after the mingw32-make +line. The build fails after it's already finished building libeay32, which +is all we care about, but the failure aborts the script before it runs +dllwrap to generate libeay32.dll. + REM if errorlevel 1 goto end + +Build + cd \openssl + ms\mingw32.bat + +If you want to use it with MSVC, generate the .lib file + lib /machine:i386 /def:ms\libeay32.def /out:out\libeay32.lib + + +Berkeley DB +----------- +Using MinGW and MSYS: +cd \db\build_unix +sh ../dist/configure --enable-mingw --enable-cxx +make + + +Boost +----- +download bjam.exe from +http://sourceforge.net/project/showfiles.php?group_id=7586&package_id=72941 +cd \boost +bjam toolset=gcc --build-type=complete stage + or +bjam toolset=msvc --build-type=complete stage diff --git a/build-osx.txt b/build-osx.txt index d6084565d7..5858a2a503 100644 --- a/build-osx.txt +++ b/build-osx.txt @@ -1,217 +1,217 @@ -Copyright (c) 2009-2010 Satoshi Nakamoto
-Distributed under the MIT/X11 software license, see the accompanying
-file license.txt or http://www.opensource.org/licenses/mit-license.php.
-This product includes software developed by the OpenSSL Project for use in
-the OpenSSL Toolkit (http://www.openssl.org/). This product includes
-cryptographic software written by Eric Young (eay@cryptsoft.com).
-
-
-Mac OS X build instructions
-Laszlo Hanyecz (solar@heliacal.net)
-
-
-Tested on 10.5 and 10.6 intel. PPC is not supported because it's big-endian.
-
-All of the commands should be executed in Terminal.app.. it's in
-/Applications/Utilities
-
-You need to install XCode with all the options checked so that the compiler
-and everything is available in /usr not just /Developer
-I think it comes on the DVD but you can get the current version from
-http://developer.apple.com
-
-
-1. Pick a directory to work inside.. something like ~/bitcoin works. The
-structure I use looks like this:
-(~ is your home directory)
-
-~/bitcoin
-~/bitcoin/trunk # source code
-~/bitcoin/deps # dependencies.. like libraries and headers needed to compile
-~/bitcoin/Bitcoin.app # the application bundle where you can run the app
-
-Just execute: mkdir ~/bitcoin
-This will create the top dir for you..
-
-WARNING: do not use the ~ notation with the configure scripts.. use the full
-name of the directory, for example /Users/james/bitcoin/deps for a user named
-'james'. In my examples I am using 'macosuser' so make sure you change that.
-
-2. Check out the trunk version of the bitcoin code from subversion:
-
-cd ~/bitcoin
-svn checkout https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk
-
-This will make ~/bitcoin/trunk for you with all the files from subversion.
-
-3. Get and build the dependencies
-
-
-Boost
------
-
-Download from http://www.boost.org/users/download/
-I'm assuming it ended up in ~/Downloads..
-
-mkdir ~/bitcoin/deps
-cd ~/bitcoin/deps
-tar xvjf ~/Downloads/boost_1_42_0.tar.bz2
-cd boost_1_42_0
-./bootstrap.sh
-./bjam architecture=combined address-model=32_64 macosx-version=10.6 macosx-version-min=10.5 link=static runtime-link=static --toolset=darwin --prefix=/Users/macosuser/bitcoin/deps install
-
-This part takes a while.. use your judgement and fix it if something doesn't
-build for some reason.
-
-Change the prefix to whatever your directory is (my username in this example
-is macosuser). I'm also running on 10.6 so i have macosx-version=10.6 change
-to 10.5 if you're using leopard.
-
-This is what my output looked like at the end:
-...failed updating 2 targets...
-...skipped 144 targets...
-...updated 8074 targets...
-
-
-OpenSSL
--------
-
-Download from http://www.openssl.org/source/
-
-We would like to build this as a 32 bit/64 bit library so we actually build it
-2 times and join it together here.. If you downloaded with safari it already
-uncompressed it so it will just be a tar not a tar.gz
-
-cd ~/bitcoin/deps
-tar xvf ~/Downloads/openssl-1.0.0.tar
-mv openssl-1.0.0 openssl-1.0.0-i386
-tar xvf ~/Downloads/openssl-1.0.0.tar
-mv openssl-1.0.0 openssl-1.0.0-x86_64
-# build i386 (32 bit intel) binary
-cd openssl-1.0.0-i386
-./Configure --prefix=/Users/macosuser/bitcoin/deps --openssldir=/Users/macosuser/deps/openssl darwin-i386-cc && make
-make install # only do this on one of the architectures, to install the headers
-cd ..
-# build x86_64 (64 bit intel) binary
-cd openssl-1.0.0-x86_64
-./Configure --prefix=/Users/macosuser/bitcoin/deps --openssldir=/Users/macosuser/deps/openssl darwin64-x86_64-cc && make
-cd ..
-
-# combine the libs
-cd ~/bitcoin/deps
-lipo -arch i386 openssl-1.0.0-i386/libcrypto.a -arch x86_64 openssl-1.0.0-x86_64/libcrypto.a -o lib/libcrypto.a -create
-lipo -arch i386 openssl-1.0.0-i386/libssl.a -arch x86_64 openssl-1.0.0-x86_64/libssl.a -o lib/libssl.a -create
-
-Verify your binaries
-
-file lib/libcrypto.a
-
-output should look like this:
-
-ib/libcrypto.a: Mach-O universal binary with 2 architectures
-lib/libcrypto.a (for architecture i386): current ar archive random library
-lib/libcrypto.a (for architecture x86_64): current ar archive random library
-
-
-Berkeley DB
------------
-
-Download from http://freshmeat.net/projects/berkeleydb/
-
-cd ~/bitcoin/deps
-tar xvf ~/Downloads/db-4.8.26.tar
-cd db-4.8.26/build_unix
-../dist/configure --prefix=/Users/macosuser/bitcoin/deps --enable-cxx && make && make install
-
-
-wxWidgets
----------
-
-This is the big one..
-
-Check it out from svn
-
-cd ~/bitcoin/deps
-svn checkout http://svn.wxwidgets.org/svn/wx/wxWidgets/trunk wxWidgets-trunk
-
-This will make a wxWidgets-trunk directory in deps.
-
-Use this script snippet, change your prefix to whatever your dir is:
-
-PREFIX=~/bitcoin/deps
-SRCDIR="$PREFIX/wxWidgets-trunk"
-BUILDDIR="$SRCDIR/macbuild"
-
-cd "$PREFIX" &&
-#svn checkout http://svn.wxwidgets.org/svn/wx/wxWidgets/trunk wxWidgets-trunk &&
-cd "$SRCDIR" &&
-
-[ -f include/wx/hashmap.h.orig ] || cp include/wx/hashmap.h include/wx/hashmap.h.orig &&
-sed 's/if wxUSE_STL/if 0 \&\& wxUSE_STL/g' < include/wx/hashmap.h.orig > include/wx/hashmap.h &&
-
-[ -f include/wx/hashset.h.orig ] || cp include/wx/hashset.h include/wx/hashset.h.orig &&
-sed 's/if wxUSE_STL/if 0 \&\& wxUSE_STL/g' < include/wx/hashset.h.orig > include/wx/hashset.h &&
-
-
-
-rm -vrf "$BUILDDIR" &&
-mkdir "$BUILDDIR" &&
-cd "$BUILDDIR" &&
-
-../configure --prefix="$PREFIX" \
---with-osx_cocoa \
---disable-shared \
---disable-debug_flag \
---with-macosx-version-min=10.5 \
---enable-stl \
---enable-utf8 \
---enable-universal_binary \
---with-libjpeg=builtin \
---with-libpng=builtin \
---with-regex=builtin \
---with-libtiff=builtin \
---with-zlib=builtin \
---with-expat=builtin \
---with-macosx-sdk=/Developer/SDKs/MacOSX10.5.sdk &&
-
-
-find . -name Makefile |
-while read i; do
- echo $i;
- sed 's/-arch i386/-arch i386 -arch x86_64/g' < "$i" > "$i".new &&
- mv "$i" "$i".old &&
- mv "$i".new "$i";
-done
-
-
-
-make &&
-make install
-
-
-
-Now you should be able to build bitcoin
-
-cd ~/bitcoin/trunk
-make -f makefile.osx bitcoin
-
-Before you can run it, you need to create an application bundle for Mac OS.
-Create the directories in terminal using mkdir and copy the files into place.
-They are available at http://heliacal.net/~solar/bitcoin/mac-build/
-You need the Info.plist and the .ins file. The Contents/MacOS/bitcoin file is
-the output of the build.
-Your directory structure should look like this:
-
-Bitcoin.app
-Bitcoin.app/Contents
-Bitcoin.app/Contents/Info.plist
-Bitcoin.app/Contents/MacOS
-Bitcoin.app/Contents/MacOS/bitcoin
-Bitcoin.app/Contents/Resources
-Bitcoin.app/Contents/Resources/BitcoinAppIcon.icns
-
-To run it you can just click the Bitcoin.app in Finder, or just do open
-~/bitcoin/Bitcoin.app
-If you want to run it with arguments you can just run it without backgrounding
-by specifying the full name in terminal:
-~/bitcoin/Bitcoin.app/Contents/MacOS/bitcoin -addnode=192.75.207.66
+Copyright (c) 2009-2010 Satoshi Nakamoto +Distributed under the MIT/X11 software license, see the accompanying +file license.txt or http://www.opensource.org/licenses/mit-license.php. +This product includes software developed by the OpenSSL Project for use in +the OpenSSL Toolkit (http://www.openssl.org/). This product includes +cryptographic software written by Eric Young (eay@cryptsoft.com). + + +Mac OS X build instructions +Laszlo Hanyecz (solar@heliacal.net) + + +Tested on 10.5 and 10.6 intel. PPC is not supported because it's big-endian. + +All of the commands should be executed in Terminal.app.. it's in +/Applications/Utilities + +You need to install XCode with all the options checked so that the compiler +and everything is available in /usr not just /Developer +I think it comes on the DVD but you can get the current version from +http://developer.apple.com + + +1. Pick a directory to work inside.. something like ~/bitcoin works. The +structure I use looks like this: +(~ is your home directory) + +~/bitcoin +~/bitcoin/trunk # source code +~/bitcoin/deps # dependencies.. like libraries and headers needed to compile +~/bitcoin/Bitcoin.app # the application bundle where you can run the app + +Just execute: mkdir ~/bitcoin +This will create the top dir for you.. + +WARNING: do not use the ~ notation with the configure scripts.. use the full +name of the directory, for example /Users/james/bitcoin/deps for a user named +'james'. In my examples I am using 'macosuser' so make sure you change that. + +2. Check out the trunk version of the bitcoin code from subversion: + +cd ~/bitcoin +svn checkout https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk + +This will make ~/bitcoin/trunk for you with all the files from subversion. + +3. Get and build the dependencies + + +Boost +----- + +Download from http://www.boost.org/users/download/ +I'm assuming it ended up in ~/Downloads.. + +mkdir ~/bitcoin/deps +cd ~/bitcoin/deps +tar xvjf ~/Downloads/boost_1_42_0.tar.bz2 +cd boost_1_42_0 +./bootstrap.sh +./bjam architecture=combined address-model=32_64 macosx-version=10.6 macosx-version-min=10.5 link=static runtime-link=static --toolset=darwin --prefix=/Users/macosuser/bitcoin/deps install + +This part takes a while.. use your judgement and fix it if something doesn't +build for some reason. + +Change the prefix to whatever your directory is (my username in this example +is macosuser). I'm also running on 10.6 so i have macosx-version=10.6 change +to 10.5 if you're using leopard. + +This is what my output looked like at the end: +...failed updating 2 targets... +...skipped 144 targets... +...updated 8074 targets... + + +OpenSSL +------- + +Download from http://www.openssl.org/source/ + +We would like to build this as a 32 bit/64 bit library so we actually build it +2 times and join it together here.. If you downloaded with safari it already +uncompressed it so it will just be a tar not a tar.gz + +cd ~/bitcoin/deps +tar xvf ~/Downloads/openssl-1.0.0.tar +mv openssl-1.0.0 openssl-1.0.0-i386 +tar xvf ~/Downloads/openssl-1.0.0.tar +mv openssl-1.0.0 openssl-1.0.0-x86_64 +# build i386 (32 bit intel) binary +cd openssl-1.0.0-i386 +./Configure --prefix=/Users/macosuser/bitcoin/deps --openssldir=/Users/macosuser/deps/openssl darwin-i386-cc && make +make install # only do this on one of the architectures, to install the headers +cd .. +# build x86_64 (64 bit intel) binary +cd openssl-1.0.0-x86_64 +./Configure --prefix=/Users/macosuser/bitcoin/deps --openssldir=/Users/macosuser/deps/openssl darwin64-x86_64-cc && make +cd .. + +# combine the libs +cd ~/bitcoin/deps +lipo -arch i386 openssl-1.0.0-i386/libcrypto.a -arch x86_64 openssl-1.0.0-x86_64/libcrypto.a -o lib/libcrypto.a -create +lipo -arch i386 openssl-1.0.0-i386/libssl.a -arch x86_64 openssl-1.0.0-x86_64/libssl.a -o lib/libssl.a -create + +Verify your binaries + +file lib/libcrypto.a + +output should look like this: + +ib/libcrypto.a: Mach-O universal binary with 2 architectures +lib/libcrypto.a (for architecture i386): current ar archive random library +lib/libcrypto.a (for architecture x86_64): current ar archive random library + + +Berkeley DB +----------- + +Download from http://freshmeat.net/projects/berkeleydb/ + +cd ~/bitcoin/deps +tar xvf ~/Downloads/db-4.8.26.tar +cd db-4.8.26/build_unix +../dist/configure --prefix=/Users/macosuser/bitcoin/deps --enable-cxx && make && make install + + +wxWidgets +--------- + +This is the big one.. + +Check it out from svn + +cd ~/bitcoin/deps +svn checkout http://svn.wxwidgets.org/svn/wx/wxWidgets/trunk wxWidgets-trunk + +This will make a wxWidgets-trunk directory in deps. + +Use this script snippet, change your prefix to whatever your dir is: + +PREFIX=~/bitcoin/deps +SRCDIR="$PREFIX/wxWidgets-trunk" +BUILDDIR="$SRCDIR/macbuild" + +cd "$PREFIX" && +#svn checkout http://svn.wxwidgets.org/svn/wx/wxWidgets/trunk wxWidgets-trunk && +cd "$SRCDIR" && + +[ -f include/wx/hashmap.h.orig ] || cp include/wx/hashmap.h include/wx/hashmap.h.orig && +sed 's/if wxUSE_STL/if 0 \&\& wxUSE_STL/g' < include/wx/hashmap.h.orig > include/wx/hashmap.h && + +[ -f include/wx/hashset.h.orig ] || cp include/wx/hashset.h include/wx/hashset.h.orig && +sed 's/if wxUSE_STL/if 0 \&\& wxUSE_STL/g' < include/wx/hashset.h.orig > include/wx/hashset.h && + + + +rm -vrf "$BUILDDIR" && +mkdir "$BUILDDIR" && +cd "$BUILDDIR" && + +../configure --prefix="$PREFIX" \ +--with-osx_cocoa \ +--disable-shared \ +--disable-debug_flag \ +--with-macosx-version-min=10.5 \ +--enable-stl \ +--enable-utf8 \ +--enable-universal_binary \ +--with-libjpeg=builtin \ +--with-libpng=builtin \ +--with-regex=builtin \ +--with-libtiff=builtin \ +--with-zlib=builtin \ +--with-expat=builtin \ +--with-macosx-sdk=/Developer/SDKs/MacOSX10.5.sdk && + + +find . -name Makefile | +while read i; do + echo $i; + sed 's/-arch i386/-arch i386 -arch x86_64/g' < "$i" > "$i".new && + mv "$i" "$i".old && + mv "$i".new "$i"; +done + + + +make && +make install + + + +Now you should be able to build bitcoin + +cd ~/bitcoin/trunk +make -f makefile.osx bitcoin + +Before you can run it, you need to create an application bundle for Mac OS. +Create the directories in terminal using mkdir and copy the files into place. +They are available at http://heliacal.net/~solar/bitcoin/mac-build/ +You need the Info.plist and the .ins file. The Contents/MacOS/bitcoin file is +the output of the build. +Your directory structure should look like this: + +Bitcoin.app +Bitcoin.app/Contents +Bitcoin.app/Contents/Info.plist +Bitcoin.app/Contents/MacOS +Bitcoin.app/Contents/MacOS/bitcoin +Bitcoin.app/Contents/Resources +Bitcoin.app/Contents/Resources/BitcoinAppIcon.icns + +To run it you can just click the Bitcoin.app in Finder, or just do open +~/bitcoin/Bitcoin.app +If you want to run it with arguments you can just run it without backgrounding +by specifying the full name in terminal: +~/bitcoin/Bitcoin.app/Contents/MacOS/bitcoin -addnode=192.75.207.66 diff --git a/build-unix.txt b/build-unix.txt index 30a4a36321..448e6eaf81 100644 --- a/build-unix.txt +++ b/build-unix.txt @@ -1,83 +1,83 @@ -Copyright (c) 2009-2010 Satoshi Nakamoto
-Distributed under the MIT/X11 software license, see the accompanying
-file license.txt or http://www.opensource.org/licenses/mit-license.php.
-This product includes software developed by the OpenSSL Project for use in
-the OpenSSL Toolkit (http://www.openssl.org/). This product includes
-cryptographic software written by Eric Young (eay@cryptsoft.com).
-
-
-UNIX BUILD NOTES
-================
-
-Dependencies
-------------
-sudo apt-get install build-essential
-sudo apt-get install libgtk2.0-dev
-sudo apt-get install libssl-dev
-sudo apt-get install libdb4.7-dev
-sudo apt-get install libdb4.7++-dev
-sudo apt-get install libboost-all-dev
-
-We're now using wxWidgets 2.9, which uses UTF-8.
-
-There isn't currently a debian package of wxWidgets we can use. The 2.8
-packages for Karmic are UTF-16 unicode and won't work for us, and we've had
-trouble building 2.8 on 64-bit.
-
-You need to download wxWidgets from http://www.wxwidgets.org/downloads/
-and build it yourself. See the build instructions and configure parameters
-below.
-
-Licenses of statically linked libraries:
-wxWidgets LGPL 2.1 with very liberal exceptions
-Berkeley DB New BSD license with additional requirement that linked software must be free open source
-Boost MIT-like license
-
-Versions used in this release:
-GCC 4.4.3
-OpenSSL 0.9.8k
-wxWidgets 2.9.0
-Berkeley DB 4.7.25.NC
-Boost 1.40.0
-
-
-Notes
------
-The UI layout is edited with wxFormBuilder. The project file is
-uiproject.fbp. It generates uibase.cpp and uibase.h, which define base
-classes that do the rote work of constructing all the UI elements.
-
-The release is built with GCC and then "strip bitcoin" to strip the debug
-symbols, which reduces the executable size by about 90%.
-
-
-wxWidgets
----------
-cd /usr/local
-tar -xzvf wxWidgets-2.9.0.tar.gz
-cd /usr/local/wxWidgets-2.9.0
-mkdir buildgtk
-cd buildgtk
-../configure --with-gtk --enable-debug --disable-shared --enable-monolithic
-make
-sudo su
-make install
-ldconfig
-su <username>
-cd ..
-mkdir buildbase
-cd buildbase
-../configure --disable-gui --enable-debug --disable-shared --enable-monolithic
-make
-sudo su
-make install
-ldconfig
-
-
-Boost
------
-If you want to build Boost yourself,
-cd /usr/local/boost_1_40_0
-su
-./bootstrap.sh
-./bjam install
+Copyright (c) 2009-2010 Satoshi Nakamoto +Distributed under the MIT/X11 software license, see the accompanying +file license.txt or http://www.opensource.org/licenses/mit-license.php. +This product includes software developed by the OpenSSL Project for use in +the OpenSSL Toolkit (http://www.openssl.org/). This product includes +cryptographic software written by Eric Young (eay@cryptsoft.com). + + +UNIX BUILD NOTES +================ + +Dependencies +------------ +sudo apt-get install build-essential +sudo apt-get install libgtk2.0-dev +sudo apt-get install libssl-dev +sudo apt-get install libdb4.7-dev +sudo apt-get install libdb4.7++-dev +sudo apt-get install libboost-all-dev + +We're now using wxWidgets 2.9, which uses UTF-8. + +There isn't currently a debian package of wxWidgets we can use. The 2.8 +packages for Karmic are UTF-16 unicode and won't work for us, and we've had +trouble building 2.8 on 64-bit. + +You need to download wxWidgets from http://www.wxwidgets.org/downloads/ +and build it yourself. See the build instructions and configure parameters +below. + +Licenses of statically linked libraries: +wxWidgets LGPL 2.1 with very liberal exceptions +Berkeley DB New BSD license with additional requirement that linked software must be free open source +Boost MIT-like license + +Versions used in this release: +GCC 4.4.3 +OpenSSL 0.9.8k +wxWidgets 2.9.0 +Berkeley DB 4.7.25.NC +Boost 1.40.0 + + +Notes +----- +The UI layout is edited with wxFormBuilder. The project file is +uiproject.fbp. It generates uibase.cpp and uibase.h, which define base +classes that do the rote work of constructing all the UI elements. + +The release is built with GCC and then "strip bitcoin" to strip the debug +symbols, which reduces the executable size by about 90%. + + +wxWidgets +--------- +cd /usr/local +tar -xzvf wxWidgets-2.9.0.tar.gz +cd /usr/local/wxWidgets-2.9.0 +mkdir buildgtk +cd buildgtk +../configure --with-gtk --enable-debug --disable-shared --enable-monolithic +make +sudo su +make install +ldconfig +su <username> +cd .. +mkdir buildbase +cd buildbase +../configure --disable-gui --enable-debug --disable-shared --enable-monolithic +make +sudo su +make install +ldconfig + + +Boost +----- +If you want to build Boost yourself, +cd /usr/local/boost_1_40_0 +su +./bootstrap.sh +./bjam install @@ -1,737 +1,737 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
-
-#include "headers.h"
-
-void ThreadFlushWalletDB(void* parg);
-
-
-unsigned int nWalletDBUpdated;
-
-
-
-
-//
-// CDB
-//
-
-static CCriticalSection cs_db;
-static bool fDbEnvInit = false;
-DbEnv dbenv(0);
-static map<string, int> mapFileUseCount;
-static map<string, Db*> mapDb;
-
-class CDBInit
-{
-public:
- CDBInit()
- {
- }
- ~CDBInit()
- {
- if (fDbEnvInit)
- {
- dbenv.close(0);
- fDbEnvInit = false;
- }
- }
-}
-instance_of_cdbinit;
-
-
-CDB::CDB(const char* pszFile, const char* pszMode) : pdb(NULL)
-{
- int ret;
- if (pszFile == NULL)
- return;
-
- fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w'));
- bool fCreate = strchr(pszMode, 'c');
- unsigned int nFlags = DB_THREAD;
- if (fCreate)
- nFlags |= DB_CREATE;
-
- CRITICAL_BLOCK(cs_db)
- {
- if (!fDbEnvInit)
- {
- if (fShutdown)
- return;
- string strDataDir = GetDataDir();
- string strLogDir = strDataDir + "/database";
- _mkdir(strLogDir.c_str());
- string strErrorFile = strDataDir + "/db.log";
- printf("dbenv.open strLogDir=%s strErrorFile=%s\n", strLogDir.c_str(), strErrorFile.c_str());
-
- dbenv.set_lg_dir(strLogDir.c_str());
- dbenv.set_lg_max(10000000);
- dbenv.set_lk_max_locks(10000);
- dbenv.set_lk_max_objects(10000);
- dbenv.set_errfile(fopen(strErrorFile.c_str(), "a")); /// debug
- dbenv.set_flags(DB_AUTO_COMMIT, 1);
- ret = dbenv.open(strDataDir.c_str(),
- DB_CREATE |
- DB_INIT_LOCK |
- DB_INIT_LOG |
- DB_INIT_MPOOL |
- DB_INIT_TXN |
- DB_THREAD |
- DB_PRIVATE |
- DB_RECOVER,
- S_IRUSR | S_IWUSR);
- if (ret > 0)
- throw runtime_error(strprintf("CDB() : error %d opening database environment\n", ret));
- fDbEnvInit = true;
- }
-
- strFile = pszFile;
- ++mapFileUseCount[strFile];
- pdb = mapDb[strFile];
- if (pdb == NULL)
- {
- pdb = new Db(&dbenv, 0);
-
- ret = pdb->open(NULL, // Txn pointer
- pszFile, // Filename
- "main", // Logical db name
- DB_BTREE, // Database type
- nFlags, // Flags
- 0);
-
- if (ret > 0)
- {
- delete pdb;
- pdb = NULL;
- CRITICAL_BLOCK(cs_db)
- --mapFileUseCount[strFile];
- strFile = "";
- throw runtime_error(strprintf("CDB() : can't open database file %s, error %d\n", pszFile, ret));
- }
-
- if (fCreate && !Exists(string("version")))
- {
- bool fTmp = fReadOnly;
- fReadOnly = false;
- WriteVersion(VERSION);
- fReadOnly = fTmp;
- }
-
- mapDb[strFile] = pdb;
- }
- }
-}
-
-void CDB::Close()
-{
- if (!pdb)
- return;
- if (!vTxn.empty())
- vTxn.front()->abort();
- vTxn.clear();
- pdb = NULL;
- dbenv.txn_checkpoint(0, 0, 0);
-
- CRITICAL_BLOCK(cs_db)
- --mapFileUseCount[strFile];
-}
-
-void CloseDb(const string& strFile)
-{
- CRITICAL_BLOCK(cs_db)
- {
- if (mapDb[strFile] != NULL)
- {
- // Close the database handle
- Db* pdb = mapDb[strFile];
- pdb->close(0);
- delete pdb;
- mapDb[strFile] = NULL;
- }
- }
-}
-
-void DBFlush(bool fShutdown)
-{
- // Flush log data to the actual data file
- // on all files that are not in use
- printf("DBFlush(%s)%s\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " db not started");
- if (!fDbEnvInit)
- return;
- CRITICAL_BLOCK(cs_db)
- {
- map<string, int>::iterator mi = mapFileUseCount.begin();
- while (mi != mapFileUseCount.end())
- {
- string strFile = (*mi).first;
- int nRefCount = (*mi).second;
- printf("%s refcount=%d\n", strFile.c_str(), nRefCount);
- if (nRefCount == 0)
- {
- // Move log data to the dat file
- CloseDb(strFile);
- dbenv.txn_checkpoint(0, 0, 0);
- printf("%s flush\n", strFile.c_str());
- dbenv.lsn_reset(strFile.c_str(), 0);
- mapFileUseCount.erase(mi++);
- }
- else
- mi++;
- }
- if (fShutdown)
- {
- char** listp;
- if (mapFileUseCount.empty())
- dbenv.log_archive(&listp, DB_ARCH_REMOVE);
- dbenv.close(0);
- fDbEnvInit = false;
- }
- }
-}
-
-
-
-
-
-
-//
-// CTxDB
-//
-
-bool CTxDB::ReadTxIndex(uint256 hash, CTxIndex& txindex)
-{
- assert(!fClient);
- txindex.SetNull();
- return Read(make_pair(string("tx"), hash), txindex);
-}
-
-bool CTxDB::UpdateTxIndex(uint256 hash, const CTxIndex& txindex)
-{
- assert(!fClient);
- return Write(make_pair(string("tx"), hash), txindex);
-}
-
-bool CTxDB::AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight)
-{
- assert(!fClient);
-
- // Add to tx index
- uint256 hash = tx.GetHash();
- CTxIndex txindex(pos, tx.vout.size());
- return Write(make_pair(string("tx"), hash), txindex);
-}
-
-bool CTxDB::EraseTxIndex(const CTransaction& tx)
-{
- assert(!fClient);
- uint256 hash = tx.GetHash();
-
- return Erase(make_pair(string("tx"), hash));
-}
-
-bool CTxDB::ContainsTx(uint256 hash)
-{
- assert(!fClient);
- return Exists(make_pair(string("tx"), hash));
-}
-
-bool CTxDB::ReadOwnerTxes(uint160 hash160, int nMinHeight, vector<CTransaction>& vtx)
-{
- assert(!fClient);
- vtx.clear();
-
- // Get cursor
- Dbc* pcursor = GetCursor();
- if (!pcursor)
- return false;
-
- unsigned int fFlags = DB_SET_RANGE;
- loop
- {
- // Read next record
- CDataStream ssKey;
- if (fFlags == DB_SET_RANGE)
- ssKey << string("owner") << hash160 << CDiskTxPos(0, 0, 0);
- CDataStream ssValue;
- int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags);
- fFlags = DB_NEXT;
- if (ret == DB_NOTFOUND)
- break;
- else if (ret != 0)
- {
- pcursor->close();
- return false;
- }
-
- // Unserialize
- string strType;
- uint160 hashItem;
- CDiskTxPos pos;
- ssKey >> strType >> hashItem >> pos;
- int nItemHeight;
- ssValue >> nItemHeight;
-
- // Read transaction
- if (strType != "owner" || hashItem != hash160)
- break;
- if (nItemHeight >= nMinHeight)
- {
- vtx.resize(vtx.size()+1);
- if (!vtx.back().ReadFromDisk(pos))
- {
- pcursor->close();
- return false;
- }
- }
- }
-
- pcursor->close();
- return true;
-}
-
-bool CTxDB::ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex)
-{
- assert(!fClient);
- tx.SetNull();
- if (!ReadTxIndex(hash, txindex))
- return false;
- return (tx.ReadFromDisk(txindex.pos));
-}
-
-bool CTxDB::ReadDiskTx(uint256 hash, CTransaction& tx)
-{
- CTxIndex txindex;
- return ReadDiskTx(hash, tx, txindex);
-}
-
-bool CTxDB::ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex)
-{
- return ReadDiskTx(outpoint.hash, tx, txindex);
-}
-
-bool CTxDB::ReadDiskTx(COutPoint outpoint, CTransaction& tx)
-{
- CTxIndex txindex;
- return ReadDiskTx(outpoint.hash, tx, txindex);
-}
-
-bool CTxDB::WriteBlockIndex(const CDiskBlockIndex& blockindex)
-{
- return Write(make_pair(string("blockindex"), blockindex.GetBlockHash()), blockindex);
-}
-
-bool CTxDB::EraseBlockIndex(uint256 hash)
-{
- return Erase(make_pair(string("blockindex"), hash));
-}
-
-bool CTxDB::ReadHashBestChain(uint256& hashBestChain)
-{
- return Read(string("hashBestChain"), hashBestChain);
-}
-
-bool CTxDB::WriteHashBestChain(uint256 hashBestChain)
-{
- return Write(string("hashBestChain"), hashBestChain);
-}
-
-CBlockIndex* InsertBlockIndex(uint256 hash)
-{
- if (hash == 0)
- return NULL;
-
- // Return existing
- map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
- if (mi != mapBlockIndex.end())
- return (*mi).second;
-
- // Create new
- CBlockIndex* pindexNew = new CBlockIndex();
- if (!pindexNew)
- throw runtime_error("LoadBlockIndex() : new CBlockIndex failed");
- mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
- pindexNew->phashBlock = &((*mi).first);
-
- return pindexNew;
-}
-
-bool CTxDB::LoadBlockIndex()
-{
- // Get cursor
- Dbc* pcursor = GetCursor();
- if (!pcursor)
- return false;
-
- unsigned int fFlags = DB_SET_RANGE;
- loop
- {
- // Read next record
- CDataStream ssKey;
- if (fFlags == DB_SET_RANGE)
- ssKey << make_pair(string("blockindex"), uint256(0));
- CDataStream ssValue;
- int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags);
- fFlags = DB_NEXT;
- if (ret == DB_NOTFOUND)
- break;
- else if (ret != 0)
- return false;
-
- // Unserialize
- string strType;
- ssKey >> strType;
- if (strType == "blockindex")
- {
- CDiskBlockIndex diskindex;
- ssValue >> diskindex;
-
- // Construct block index object
- CBlockIndex* pindexNew = InsertBlockIndex(diskindex.GetBlockHash());
- pindexNew->pprev = InsertBlockIndex(diskindex.hashPrev);
- pindexNew->pnext = InsertBlockIndex(diskindex.hashNext);
- pindexNew->nFile = diskindex.nFile;
- pindexNew->nBlockPos = diskindex.nBlockPos;
- pindexNew->nHeight = diskindex.nHeight;
- pindexNew->nVersion = diskindex.nVersion;
- pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot;
- pindexNew->nTime = diskindex.nTime;
- pindexNew->nBits = diskindex.nBits;
- pindexNew->nNonce = diskindex.nNonce;
-
- // Watch for genesis block and best block
- if (pindexGenesisBlock == NULL && diskindex.GetBlockHash() == hashGenesisBlock)
- pindexGenesisBlock = pindexNew;
- }
- else
- {
- break;
- }
- }
- pcursor->close();
-
- if (!ReadHashBestChain(hashBestChain))
- {
- if (pindexGenesisBlock == NULL)
- return true;
- return error("CTxDB::LoadBlockIndex() : hashBestChain not found");
- }
-
- if (!mapBlockIndex.count(hashBestChain))
- return error("CTxDB::LoadBlockIndex() : blockindex for hashBestChain not found");
- pindexBest = mapBlockIndex[hashBestChain];
- nBestHeight = pindexBest->nHeight;
- printf("LoadBlockIndex(): hashBestChain=%s height=%d\n", hashBestChain.ToString().substr(0,16).c_str(), nBestHeight);
-
- return true;
-}
-
-
-
-
-
-//
-// CAddrDB
-//
-
-bool CAddrDB::WriteAddress(const CAddress& addr)
-{
- return Write(make_pair(string("addr"), addr.GetKey()), addr);
-}
-
-bool CAddrDB::LoadAddresses()
-{
- CRITICAL_BLOCK(cs_mapAddresses)
- {
- // Load user provided addresses
- CAutoFile filein = fopen((GetDataDir() + "/addr.txt").c_str(), "rt");
- if (filein)
- {
- try
- {
- char psz[1000];
- while (fgets(psz, sizeof(psz), filein))
- {
- CAddress addr(psz, NODE_NETWORK);
- addr.nTime = 0; // so it won't relay unless successfully connected
- if (addr.IsValid())
- AddAddress(addr);
- }
- }
- catch (...) { }
- }
-
- // Get cursor
- Dbc* pcursor = GetCursor();
- if (!pcursor)
- return false;
-
- loop
- {
- // Read next record
- CDataStream ssKey;
- CDataStream ssValue;
- int ret = ReadAtCursor(pcursor, ssKey, ssValue);
- if (ret == DB_NOTFOUND)
- break;
- else if (ret != 0)
- return false;
-
- // Unserialize
- string strType;
- ssKey >> strType;
- if (strType == "addr")
- {
- CAddress addr;
- ssValue >> addr;
- mapAddresses.insert(make_pair(addr.GetKey(), addr));
- }
- }
- pcursor->close();
-
- printf("Loaded %d addresses\n", mapAddresses.size());
-
- // Fix for possible bug that manifests in mapAddresses.count in irc.cpp,
- // just need to call count here and it doesn't happen there. The bug was the
- // pack pragma in irc.cpp and has been fixed, but I'm not in a hurry to delete this.
- mapAddresses.count(vector<unsigned char>(18));
- }
-
- return true;
-}
-
-bool LoadAddresses()
-{
- return CAddrDB("cr+").LoadAddresses();
-}
-
-
-
-
-//
-// CWalletDB
-//
-
-bool CWalletDB::LoadWallet()
-{
- vchDefaultKey.clear();
- int nFileVersion = 0;
-
- // Modify defaults
-#ifndef __WXMSW__
- // Tray icon sometimes disappears on 9.10 karmic koala 64-bit, leaving no way to access the program
- fMinimizeToTray = false;
- fMinimizeOnClose = false;
-#endif
-
- //// todo: shouldn't we catch exceptions and try to recover and continue?
- CRITICAL_BLOCK(cs_mapKeys)
- CRITICAL_BLOCK(cs_mapWallet)
- {
- // Get cursor
- Dbc* pcursor = GetCursor();
- if (!pcursor)
- return false;
-
- loop
- {
- // Read next record
- CDataStream ssKey;
- CDataStream ssValue;
- int ret = ReadAtCursor(pcursor, ssKey, ssValue);
- if (ret == DB_NOTFOUND)
- break;
- else if (ret != 0)
- return false;
-
- // Unserialize
- // Taking advantage of the fact that pair serialization
- // is just the two items serialized one after the other
- string strType;
- ssKey >> strType;
- if (strType == "name")
- {
- string strAddress;
- ssKey >> strAddress;
- ssValue >> mapAddressBook[strAddress];
- }
- else if (strType == "tx")
- {
- uint256 hash;
- ssKey >> hash;
- CWalletTx& wtx = mapWallet[hash];
- ssValue >> wtx;
-
- if (wtx.GetHash() != hash)
- printf("Error in wallet.dat, hash mismatch\n");
-
- //// debug print
- //printf("LoadWallet %s\n", wtx.GetHash().ToString().c_str());
- //printf(" %12I64d %s %s %s\n",
- // wtx.vout[0].nValue,
- // DateTimeStrFormat("%x %H:%M:%S", wtx.nTime).c_str(),
- // wtx.hashBlock.ToString().substr(0,16).c_str(),
- // wtx.mapValue["message"].c_str());
- }
- else if (strType == "key" || strType == "wkey")
- {
- vector<unsigned char> vchPubKey;
- ssKey >> vchPubKey;
- CWalletKey wkey;
- if (strType == "key")
- ssValue >> wkey.vchPrivKey;
- else
- ssValue >> wkey;
-
- mapKeys[vchPubKey] = wkey.vchPrivKey;
- mapPubKeys[Hash160(vchPubKey)] = vchPubKey;
- }
- else if (strType == "defaultkey")
- {
- ssValue >> vchDefaultKey;
- }
- else if (strType == "version")
- {
- ssValue >> nFileVersion;
- }
- else if (strType == "setting")
- {
- string strKey;
- ssKey >> strKey;
-
- // Menu state
- if (strKey == "fGenerateBitcoins") ssValue >> fGenerateBitcoins;
-
- // Options
- if (strKey == "nTransactionFee") ssValue >> nTransactionFee;
- if (strKey == "addrIncoming") ssValue >> addrIncoming;
- if (strKey == "fLimitProcessors") ssValue >> fLimitProcessors;
- if (strKey == "nLimitProcessors") ssValue >> nLimitProcessors;
- if (strKey == "fMinimizeToTray") ssValue >> fMinimizeToTray;
- if (strKey == "fMinimizeOnClose") ssValue >> fMinimizeOnClose;
- if (strKey == "fUseProxy") ssValue >> fUseProxy;
- if (strKey == "addrProxy") ssValue >> addrProxy;
-
- }
- }
- pcursor->close();
- }
-
- printf("nFileVersion = %d\n", nFileVersion);
- printf("fGenerateBitcoins = %d\n", fGenerateBitcoins);
- printf("nTransactionFee = %"PRI64d"\n", nTransactionFee);
- printf("addrIncoming = %s\n", addrIncoming.ToString().c_str());
- printf("fMinimizeToTray = %d\n", fMinimizeToTray);
- printf("fMinimizeOnClose = %d\n", fMinimizeOnClose);
- printf("fUseProxy = %d\n", fUseProxy);
- printf("addrProxy = %s\n", addrProxy.ToString().c_str());
-
-
- // The transaction fee setting won't be needed for many years to come.
- // Setting it to zero here in case they set it to something in an earlier version.
- if (nTransactionFee != 0)
- {
- nTransactionFee = 0;
- WriteSetting("nTransactionFee", nTransactionFee);
- }
-
- // Upgrade
- if (nFileVersion < VERSION)
- {
- // Get rid of old debug.log file in current directory
- if (nFileVersion <= 105 && !pszSetDataDir[0])
- unlink("debug.log");
-
- WriteVersion(VERSION);
- }
-
- return true;
-}
-
-bool LoadWallet(bool& fFirstRunRet)
-{
- fFirstRunRet = false;
- if (!CWalletDB("cr+").LoadWallet())
- return false;
- fFirstRunRet = vchDefaultKey.empty();
-
- if (mapKeys.count(vchDefaultKey))
- {
- // Set keyUser
- keyUser.SetPubKey(vchDefaultKey);
- keyUser.SetPrivKey(mapKeys[vchDefaultKey]);
- }
- else
- {
- // Create new keyUser and set as default key
- RandAddSeedPerfmon();
- keyUser.MakeNewKey();
- if (!AddKey(keyUser))
- return false;
- if (!SetAddressBookName(PubKeyToAddress(keyUser.GetPubKey()), "Your Address"))
- return false;
- CWalletDB().WriteDefaultKey(keyUser.GetPubKey());
- }
-
- CreateThread(ThreadFlushWalletDB, NULL);
- return true;
-}
-
-void ThreadFlushWalletDB(void* parg)
-{
- static bool fOneThread;
- if (fOneThread)
- return;
- fOneThread = true;
- if (mapArgs.count("-noflushwallet"))
- return;
-
- unsigned int nLastSeen = nWalletDBUpdated;
- unsigned int nLastFlushed = nWalletDBUpdated;
- int64 nLastWalletUpdate = GetTime();
- while (!fShutdown)
- {
- Sleep(500);
-
- if (nLastSeen != nWalletDBUpdated)
- {
- nLastSeen = nWalletDBUpdated;
- nLastWalletUpdate = GetTime();
- }
-
- if (nLastFlushed != nWalletDBUpdated && GetTime() - nLastWalletUpdate >= 2)
- {
- TRY_CRITICAL_BLOCK(cs_db)
- {
- // Don't do this if any databases are in use
- int nRefCount = 0;
- map<string, int>::iterator mi = mapFileUseCount.begin();
- while (mi != mapFileUseCount.end())
- {
- nRefCount += (*mi).second;
- mi++;
- }
-
- if (nRefCount == 0 && !fShutdown)
- {
- string strFile = "wallet.dat";
- map<string, int>::iterator mi = mapFileUseCount.find(strFile);
- if (mi != mapFileUseCount.end())
- {
- printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
- printf("Flushing wallet.dat\n");
- nLastFlushed = nWalletDBUpdated;
- int64 nStart = GetTimeMillis();
-
- // Flush wallet.dat so it's self contained
- CloseDb(strFile);
- dbenv.txn_checkpoint(0, 0, 0);
- dbenv.lsn_reset(strFile.c_str(), 0);
-
- mapFileUseCount.erase(mi++);
- printf("Flushed wallet.dat %"PRI64d"ms\n", GetTimeMillis() - nStart);
- }
- }
- }
- }
- }
-}
+// Copyright (c) 2009-2010 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +#include "headers.h" + +void ThreadFlushWalletDB(void* parg); + + +unsigned int nWalletDBUpdated; + + + + +// +// CDB +// + +static CCriticalSection cs_db; +static bool fDbEnvInit = false; +DbEnv dbenv(0); +static map<string, int> mapFileUseCount; +static map<string, Db*> mapDb; + +class CDBInit +{ +public: + CDBInit() + { + } + ~CDBInit() + { + if (fDbEnvInit) + { + dbenv.close(0); + fDbEnvInit = false; + } + } +} +instance_of_cdbinit; + + +CDB::CDB(const char* pszFile, const char* pszMode) : pdb(NULL) +{ + int ret; + if (pszFile == NULL) + return; + + fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w')); + bool fCreate = strchr(pszMode, 'c'); + unsigned int nFlags = DB_THREAD; + if (fCreate) + nFlags |= DB_CREATE; + + CRITICAL_BLOCK(cs_db) + { + if (!fDbEnvInit) + { + if (fShutdown) + return; + string strDataDir = GetDataDir(); + string strLogDir = strDataDir + "/database"; + _mkdir(strLogDir.c_str()); + string strErrorFile = strDataDir + "/db.log"; + printf("dbenv.open strLogDir=%s strErrorFile=%s\n", strLogDir.c_str(), strErrorFile.c_str()); + + dbenv.set_lg_dir(strLogDir.c_str()); + dbenv.set_lg_max(10000000); + dbenv.set_lk_max_locks(10000); + dbenv.set_lk_max_objects(10000); + dbenv.set_errfile(fopen(strErrorFile.c_str(), "a")); /// debug + dbenv.set_flags(DB_AUTO_COMMIT, 1); + ret = dbenv.open(strDataDir.c_str(), + DB_CREATE | + DB_INIT_LOCK | + DB_INIT_LOG | + DB_INIT_MPOOL | + DB_INIT_TXN | + DB_THREAD | + DB_PRIVATE | + DB_RECOVER, + S_IRUSR | S_IWUSR); + if (ret > 0) + throw runtime_error(strprintf("CDB() : error %d opening database environment\n", ret)); + fDbEnvInit = true; + } + + strFile = pszFile; + ++mapFileUseCount[strFile]; + pdb = mapDb[strFile]; + if (pdb == NULL) + { + pdb = new Db(&dbenv, 0); + + ret = pdb->open(NULL, // Txn pointer + pszFile, // Filename + "main", // Logical db name + DB_BTREE, // Database type + nFlags, // Flags + 0); + + if (ret > 0) + { + delete pdb; + pdb = NULL; + CRITICAL_BLOCK(cs_db) + --mapFileUseCount[strFile]; + strFile = ""; + throw runtime_error(strprintf("CDB() : can't open database file %s, error %d\n", pszFile, ret)); + } + + if (fCreate && !Exists(string("version"))) + { + bool fTmp = fReadOnly; + fReadOnly = false; + WriteVersion(VERSION); + fReadOnly = fTmp; + } + + mapDb[strFile] = pdb; + } + } +} + +void CDB::Close() +{ + if (!pdb) + return; + if (!vTxn.empty()) + vTxn.front()->abort(); + vTxn.clear(); + pdb = NULL; + dbenv.txn_checkpoint(0, 0, 0); + + CRITICAL_BLOCK(cs_db) + --mapFileUseCount[strFile]; +} + +void CloseDb(const string& strFile) +{ + CRITICAL_BLOCK(cs_db) + { + if (mapDb[strFile] != NULL) + { + // Close the database handle + Db* pdb = mapDb[strFile]; + pdb->close(0); + delete pdb; + mapDb[strFile] = NULL; + } + } +} + +void DBFlush(bool fShutdown) +{ + // Flush log data to the actual data file + // on all files that are not in use + printf("DBFlush(%s)%s\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " db not started"); + if (!fDbEnvInit) + return; + CRITICAL_BLOCK(cs_db) + { + map<string, int>::iterator mi = mapFileUseCount.begin(); + while (mi != mapFileUseCount.end()) + { + string strFile = (*mi).first; + int nRefCount = (*mi).second; + printf("%s refcount=%d\n", strFile.c_str(), nRefCount); + if (nRefCount == 0) + { + // Move log data to the dat file + CloseDb(strFile); + dbenv.txn_checkpoint(0, 0, 0); + printf("%s flush\n", strFile.c_str()); + dbenv.lsn_reset(strFile.c_str(), 0); + mapFileUseCount.erase(mi++); + } + else + mi++; + } + if (fShutdown) + { + char** listp; + if (mapFileUseCount.empty()) + dbenv.log_archive(&listp, DB_ARCH_REMOVE); + dbenv.close(0); + fDbEnvInit = false; + } + } +} + + + + + + +// +// CTxDB +// + +bool CTxDB::ReadTxIndex(uint256 hash, CTxIndex& txindex) +{ + assert(!fClient); + txindex.SetNull(); + return Read(make_pair(string("tx"), hash), txindex); +} + +bool CTxDB::UpdateTxIndex(uint256 hash, const CTxIndex& txindex) +{ + assert(!fClient); + return Write(make_pair(string("tx"), hash), txindex); +} + +bool CTxDB::AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight) +{ + assert(!fClient); + + // Add to tx index + uint256 hash = tx.GetHash(); + CTxIndex txindex(pos, tx.vout.size()); + return Write(make_pair(string("tx"), hash), txindex); +} + +bool CTxDB::EraseTxIndex(const CTransaction& tx) +{ + assert(!fClient); + uint256 hash = tx.GetHash(); + + return Erase(make_pair(string("tx"), hash)); +} + +bool CTxDB::ContainsTx(uint256 hash) +{ + assert(!fClient); + return Exists(make_pair(string("tx"), hash)); +} + +bool CTxDB::ReadOwnerTxes(uint160 hash160, int nMinHeight, vector<CTransaction>& vtx) +{ + assert(!fClient); + vtx.clear(); + + // Get cursor + Dbc* pcursor = GetCursor(); + if (!pcursor) + return false; + + unsigned int fFlags = DB_SET_RANGE; + loop + { + // Read next record + CDataStream ssKey; + if (fFlags == DB_SET_RANGE) + ssKey << string("owner") << hash160 << CDiskTxPos(0, 0, 0); + CDataStream ssValue; + int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags); + fFlags = DB_NEXT; + if (ret == DB_NOTFOUND) + break; + else if (ret != 0) + { + pcursor->close(); + return false; + } + + // Unserialize + string strType; + uint160 hashItem; + CDiskTxPos pos; + ssKey >> strType >> hashItem >> pos; + int nItemHeight; + ssValue >> nItemHeight; + + // Read transaction + if (strType != "owner" || hashItem != hash160) + break; + if (nItemHeight >= nMinHeight) + { + vtx.resize(vtx.size()+1); + if (!vtx.back().ReadFromDisk(pos)) + { + pcursor->close(); + return false; + } + } + } + + pcursor->close(); + return true; +} + +bool CTxDB::ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex) +{ + assert(!fClient); + tx.SetNull(); + if (!ReadTxIndex(hash, txindex)) + return false; + return (tx.ReadFromDisk(txindex.pos)); +} + +bool CTxDB::ReadDiskTx(uint256 hash, CTransaction& tx) +{ + CTxIndex txindex; + return ReadDiskTx(hash, tx, txindex); +} + +bool CTxDB::ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex) +{ + return ReadDiskTx(outpoint.hash, tx, txindex); +} + +bool CTxDB::ReadDiskTx(COutPoint outpoint, CTransaction& tx) +{ + CTxIndex txindex; + return ReadDiskTx(outpoint.hash, tx, txindex); +} + +bool CTxDB::WriteBlockIndex(const CDiskBlockIndex& blockindex) +{ + return Write(make_pair(string("blockindex"), blockindex.GetBlockHash()), blockindex); +} + +bool CTxDB::EraseBlockIndex(uint256 hash) +{ + return Erase(make_pair(string("blockindex"), hash)); +} + +bool CTxDB::ReadHashBestChain(uint256& hashBestChain) +{ + return Read(string("hashBestChain"), hashBestChain); +} + +bool CTxDB::WriteHashBestChain(uint256 hashBestChain) +{ + return Write(string("hashBestChain"), hashBestChain); +} + +CBlockIndex* InsertBlockIndex(uint256 hash) +{ + if (hash == 0) + return NULL; + + // Return existing + map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash); + if (mi != mapBlockIndex.end()) + return (*mi).second; + + // Create new + CBlockIndex* pindexNew = new CBlockIndex(); + if (!pindexNew) + throw runtime_error("LoadBlockIndex() : new CBlockIndex failed"); + mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first; + pindexNew->phashBlock = &((*mi).first); + + return pindexNew; +} + +bool CTxDB::LoadBlockIndex() +{ + // Get cursor + Dbc* pcursor = GetCursor(); + if (!pcursor) + return false; + + unsigned int fFlags = DB_SET_RANGE; + loop + { + // Read next record + CDataStream ssKey; + if (fFlags == DB_SET_RANGE) + ssKey << make_pair(string("blockindex"), uint256(0)); + CDataStream ssValue; + int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags); + fFlags = DB_NEXT; + if (ret == DB_NOTFOUND) + break; + else if (ret != 0) + return false; + + // Unserialize + string strType; + ssKey >> strType; + if (strType == "blockindex") + { + CDiskBlockIndex diskindex; + ssValue >> diskindex; + + // Construct block index object + CBlockIndex* pindexNew = InsertBlockIndex(diskindex.GetBlockHash()); + pindexNew->pprev = InsertBlockIndex(diskindex.hashPrev); + pindexNew->pnext = InsertBlockIndex(diskindex.hashNext); + pindexNew->nFile = diskindex.nFile; + pindexNew->nBlockPos = diskindex.nBlockPos; + pindexNew->nHeight = diskindex.nHeight; + pindexNew->nVersion = diskindex.nVersion; + pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot; + pindexNew->nTime = diskindex.nTime; + pindexNew->nBits = diskindex.nBits; + pindexNew->nNonce = diskindex.nNonce; + + // Watch for genesis block and best block + if (pindexGenesisBlock == NULL && diskindex.GetBlockHash() == hashGenesisBlock) + pindexGenesisBlock = pindexNew; + } + else + { + break; + } + } + pcursor->close(); + + if (!ReadHashBestChain(hashBestChain)) + { + if (pindexGenesisBlock == NULL) + return true; + return error("CTxDB::LoadBlockIndex() : hashBestChain not found"); + } + + if (!mapBlockIndex.count(hashBestChain)) + return error("CTxDB::LoadBlockIndex() : blockindex for hashBestChain not found"); + pindexBest = mapBlockIndex[hashBestChain]; + nBestHeight = pindexBest->nHeight; + printf("LoadBlockIndex(): hashBestChain=%s height=%d\n", hashBestChain.ToString().substr(0,16).c_str(), nBestHeight); + + return true; +} + + + + + +// +// CAddrDB +// + +bool CAddrDB::WriteAddress(const CAddress& addr) +{ + return Write(make_pair(string("addr"), addr.GetKey()), addr); +} + +bool CAddrDB::LoadAddresses() +{ + CRITICAL_BLOCK(cs_mapAddresses) + { + // Load user provided addresses + CAutoFile filein = fopen((GetDataDir() + "/addr.txt").c_str(), "rt"); + if (filein) + { + try + { + char psz[1000]; + while (fgets(psz, sizeof(psz), filein)) + { + CAddress addr(psz, NODE_NETWORK); + addr.nTime = 0; // so it won't relay unless successfully connected + if (addr.IsValid()) + AddAddress(addr); + } + } + catch (...) { } + } + + // Get cursor + Dbc* pcursor = GetCursor(); + if (!pcursor) + return false; + + loop + { + // Read next record + CDataStream ssKey; + CDataStream ssValue; + int ret = ReadAtCursor(pcursor, ssKey, ssValue); + if (ret == DB_NOTFOUND) + break; + else if (ret != 0) + return false; + + // Unserialize + string strType; + ssKey >> strType; + if (strType == "addr") + { + CAddress addr; + ssValue >> addr; + mapAddresses.insert(make_pair(addr.GetKey(), addr)); + } + } + pcursor->close(); + + printf("Loaded %d addresses\n", mapAddresses.size()); + + // Fix for possible bug that manifests in mapAddresses.count in irc.cpp, + // just need to call count here and it doesn't happen there. The bug was the + // pack pragma in irc.cpp and has been fixed, but I'm not in a hurry to delete this. + mapAddresses.count(vector<unsigned char>(18)); + } + + return true; +} + +bool LoadAddresses() +{ + return CAddrDB("cr+").LoadAddresses(); +} + + + + +// +// CWalletDB +// + +bool CWalletDB::LoadWallet() +{ + vchDefaultKey.clear(); + int nFileVersion = 0; + + // Modify defaults +#ifndef __WXMSW__ + // Tray icon sometimes disappears on 9.10 karmic koala 64-bit, leaving no way to access the program + fMinimizeToTray = false; + fMinimizeOnClose = false; +#endif + + //// todo: shouldn't we catch exceptions and try to recover and continue? + CRITICAL_BLOCK(cs_mapKeys) + CRITICAL_BLOCK(cs_mapWallet) + { + // Get cursor + Dbc* pcursor = GetCursor(); + if (!pcursor) + return false; + + loop + { + // Read next record + CDataStream ssKey; + CDataStream ssValue; + int ret = ReadAtCursor(pcursor, ssKey, ssValue); + if (ret == DB_NOTFOUND) + break; + else if (ret != 0) + return false; + + // Unserialize + // Taking advantage of the fact that pair serialization + // is just the two items serialized one after the other + string strType; + ssKey >> strType; + if (strType == "name") + { + string strAddress; + ssKey >> strAddress; + ssValue >> mapAddressBook[strAddress]; + } + else if (strType == "tx") + { + uint256 hash; + ssKey >> hash; + CWalletTx& wtx = mapWallet[hash]; + ssValue >> wtx; + + if (wtx.GetHash() != hash) + printf("Error in wallet.dat, hash mismatch\n"); + + //// debug print + //printf("LoadWallet %s\n", wtx.GetHash().ToString().c_str()); + //printf(" %12I64d %s %s %s\n", + // wtx.vout[0].nValue, + // DateTimeStrFormat("%x %H:%M:%S", wtx.nTime).c_str(), + // wtx.hashBlock.ToString().substr(0,16).c_str(), + // wtx.mapValue["message"].c_str()); + } + else if (strType == "key" || strType == "wkey") + { + vector<unsigned char> vchPubKey; + ssKey >> vchPubKey; + CWalletKey wkey; + if (strType == "key") + ssValue >> wkey.vchPrivKey; + else + ssValue >> wkey; + + mapKeys[vchPubKey] = wkey.vchPrivKey; + mapPubKeys[Hash160(vchPubKey)] = vchPubKey; + } + else if (strType == "defaultkey") + { + ssValue >> vchDefaultKey; + } + else if (strType == "version") + { + ssValue >> nFileVersion; + } + else if (strType == "setting") + { + string strKey; + ssKey >> strKey; + + // Menu state + if (strKey == "fGenerateBitcoins") ssValue >> fGenerateBitcoins; + + // Options + if (strKey == "nTransactionFee") ssValue >> nTransactionFee; + if (strKey == "addrIncoming") ssValue >> addrIncoming; + if (strKey == "fLimitProcessors") ssValue >> fLimitProcessors; + if (strKey == "nLimitProcessors") ssValue >> nLimitProcessors; + if (strKey == "fMinimizeToTray") ssValue >> fMinimizeToTray; + if (strKey == "fMinimizeOnClose") ssValue >> fMinimizeOnClose; + if (strKey == "fUseProxy") ssValue >> fUseProxy; + if (strKey == "addrProxy") ssValue >> addrProxy; + + } + } + pcursor->close(); + } + + printf("nFileVersion = %d\n", nFileVersion); + printf("fGenerateBitcoins = %d\n", fGenerateBitcoins); + printf("nTransactionFee = %"PRI64d"\n", nTransactionFee); + printf("addrIncoming = %s\n", addrIncoming.ToString().c_str()); + printf("fMinimizeToTray = %d\n", fMinimizeToTray); + printf("fMinimizeOnClose = %d\n", fMinimizeOnClose); + printf("fUseProxy = %d\n", fUseProxy); + printf("addrProxy = %s\n", addrProxy.ToString().c_str()); + + + // The transaction fee setting won't be needed for many years to come. + // Setting it to zero here in case they set it to something in an earlier version. + if (nTransactionFee != 0) + { + nTransactionFee = 0; + WriteSetting("nTransactionFee", nTransactionFee); + } + + // Upgrade + if (nFileVersion < VERSION) + { + // Get rid of old debug.log file in current directory + if (nFileVersion <= 105 && !pszSetDataDir[0]) + unlink("debug.log"); + + WriteVersion(VERSION); + } + + return true; +} + +bool LoadWallet(bool& fFirstRunRet) +{ + fFirstRunRet = false; + if (!CWalletDB("cr+").LoadWallet()) + return false; + fFirstRunRet = vchDefaultKey.empty(); + + if (mapKeys.count(vchDefaultKey)) + { + // Set keyUser + keyUser.SetPubKey(vchDefaultKey); + keyUser.SetPrivKey(mapKeys[vchDefaultKey]); + } + else + { + // Create new keyUser and set as default key + RandAddSeedPerfmon(); + keyUser.MakeNewKey(); + if (!AddKey(keyUser)) + return false; + if (!SetAddressBookName(PubKeyToAddress(keyUser.GetPubKey()), "Your Address")) + return false; + CWalletDB().WriteDefaultKey(keyUser.GetPubKey()); + } + + CreateThread(ThreadFlushWalletDB, NULL); + return true; +} + +void ThreadFlushWalletDB(void* parg) +{ + static bool fOneThread; + if (fOneThread) + return; + fOneThread = true; + if (mapArgs.count("-noflushwallet")) + return; + + unsigned int nLastSeen = nWalletDBUpdated; + unsigned int nLastFlushed = nWalletDBUpdated; + int64 nLastWalletUpdate = GetTime(); + while (!fShutdown) + { + Sleep(500); + + if (nLastSeen != nWalletDBUpdated) + { + nLastSeen = nWalletDBUpdated; + nLastWalletUpdate = GetTime(); + } + + if (nLastFlushed != nWalletDBUpdated && GetTime() - nLastWalletUpdate >= 2) + { + TRY_CRITICAL_BLOCK(cs_db) + { + // Don't do this if any databases are in use + int nRefCount = 0; + map<string, int>::iterator mi = mapFileUseCount.begin(); + while (mi != mapFileUseCount.end()) + { + nRefCount += (*mi).second; + mi++; + } + + if (nRefCount == 0 && !fShutdown) + { + string strFile = "wallet.dat"; + map<string, int>::iterator mi = mapFileUseCount.find(strFile); + if (mi != mapFileUseCount.end()) + { + printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); + printf("Flushing wallet.dat\n"); + nLastFlushed = nWalletDBUpdated; + int64 nStart = GetTimeMillis(); + + // Flush wallet.dat so it's self contained + CloseDb(strFile); + dbenv.txn_checkpoint(0, 0, 0); + dbenv.lsn_reset(strFile.c_str(), 0); + + mapFileUseCount.erase(mi++); + printf("Flushed wallet.dat %"PRI64d"ms\n", GetTimeMillis() - nStart); + } + } + } + } + } +} @@ -1,404 +1,404 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
-
-class CTransaction;
-class CTxIndex;
-class CDiskBlockIndex;
-class CDiskTxPos;
-class COutPoint;
-class CUser;
-class CReview;
-class CAddress;
-class CWalletTx;
-
-extern map<string, string> mapAddressBook;
-extern CCriticalSection cs_mapAddressBook;
-extern vector<unsigned char> vchDefaultKey;
-extern bool fClient;
-
-
-
-extern unsigned int nWalletDBUpdated;
-extern DbEnv dbenv;
-
-
-extern void DBFlush(bool fShutdown);
-
-
-
-
-class CDB
-{
-protected:
- Db* pdb;
- string strFile;
- vector<DbTxn*> vTxn;
- bool fReadOnly;
-
- explicit CDB(const char* pszFile, const char* pszMode="r+");
- ~CDB() { Close(); }
-public:
- void Close();
-private:
- CDB(const CDB&);
- void operator=(const CDB&);
-
-protected:
- template<typename K, typename T>
- bool Read(const K& key, T& value)
- {
- if (!pdb)
- return false;
-
- // Key
- CDataStream ssKey(SER_DISK);
- ssKey.reserve(1000);
- ssKey << key;
- Dbt datKey(&ssKey[0], ssKey.size());
-
- // Read
- Dbt datValue;
- datValue.set_flags(DB_DBT_MALLOC);
- int ret = pdb->get(GetTxn(), &datKey, &datValue, 0);
- memset(datKey.get_data(), 0, datKey.get_size());
- if (datValue.get_data() == NULL)
- return false;
-
- // Unserialize value
- CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK);
- ssValue >> value;
-
- // Clear and free memory
- memset(datValue.get_data(), 0, datValue.get_size());
- free(datValue.get_data());
- return (ret == 0);
- }
-
- template<typename K, typename T>
- bool Write(const K& key, const T& value, bool fOverwrite=true)
- {
- if (!pdb)
- return false;
- if (fReadOnly)
- assert(("Write called on database in read-only mode", false));
-
- // Key
- CDataStream ssKey(SER_DISK);
- ssKey.reserve(1000);
- ssKey << key;
- Dbt datKey(&ssKey[0], ssKey.size());
-
- // Value
- CDataStream ssValue(SER_DISK);
- ssValue.reserve(10000);
- ssValue << value;
- Dbt datValue(&ssValue[0], ssValue.size());
-
- // Write
- int ret = pdb->put(GetTxn(), &datKey, &datValue, (fOverwrite ? 0 : DB_NOOVERWRITE));
-
- // Clear memory in case it was a private key
- memset(datKey.get_data(), 0, datKey.get_size());
- memset(datValue.get_data(), 0, datValue.get_size());
- return (ret == 0);
- }
-
- template<typename K>
- bool Erase(const K& key)
- {
- if (!pdb)
- return false;
- if (fReadOnly)
- assert(("Erase called on database in read-only mode", false));
-
- // Key
- CDataStream ssKey(SER_DISK);
- ssKey.reserve(1000);
- ssKey << key;
- Dbt datKey(&ssKey[0], ssKey.size());
-
- // Erase
- int ret = pdb->del(GetTxn(), &datKey, 0);
-
- // Clear memory
- memset(datKey.get_data(), 0, datKey.get_size());
- return (ret == 0 || ret == DB_NOTFOUND);
- }
-
- template<typename K>
- bool Exists(const K& key)
- {
- if (!pdb)
- return false;
-
- // Key
- CDataStream ssKey(SER_DISK);
- ssKey.reserve(1000);
- ssKey << key;
- Dbt datKey(&ssKey[0], ssKey.size());
-
- // Exists
- int ret = pdb->exists(GetTxn(), &datKey, 0);
-
- // Clear memory
- memset(datKey.get_data(), 0, datKey.get_size());
- return (ret == 0);
- }
-
- Dbc* GetCursor()
- {
- if (!pdb)
- return NULL;
- Dbc* pcursor = NULL;
- int ret = pdb->cursor(NULL, &pcursor, 0);
- if (ret != 0)
- return NULL;
- return pcursor;
- }
-
- 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)
- {
- datKey.set_data(&ssKey[0]);
- datKey.set_size(ssKey.size());
- }
- Dbt datValue;
- if (fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)
- {
- datValue.set_data(&ssValue[0]);
- datValue.set_size(ssValue.size());
- }
- datKey.set_flags(DB_DBT_MALLOC);
- datValue.set_flags(DB_DBT_MALLOC);
- int ret = pcursor->get(&datKey, &datValue, fFlags);
- if (ret != 0)
- return ret;
- else if (datKey.get_data() == NULL || datValue.get_data() == NULL)
- return 99999;
-
- // Convert to streams
- ssKey.SetType(SER_DISK);
- ssKey.clear();
- ssKey.write((char*)datKey.get_data(), datKey.get_size());
- ssValue.SetType(SER_DISK);
- ssValue.clear();
- ssValue.write((char*)datValue.get_data(), datValue.get_size());
-
- // Clear and free memory
- memset(datKey.get_data(), 0, datKey.get_size());
- memset(datValue.get_data(), 0, datValue.get_size());
- free(datKey.get_data());
- free(datValue.get_data());
- return 0;
- }
-
- DbTxn* GetTxn()
- {
- if (!vTxn.empty())
- return vTxn.back();
- else
- return NULL;
- }
-
-public:
- bool TxnBegin()
- {
- if (!pdb)
- return false;
- DbTxn* ptxn = NULL;
- int ret = dbenv.txn_begin(GetTxn(), &ptxn, 0);
- if (!ptxn || ret != 0)
- return false;
- vTxn.push_back(ptxn);
- return true;
- }
-
- bool TxnCommit()
- {
- if (!pdb)
- return false;
- if (vTxn.empty())
- return false;
- int ret = vTxn.back()->commit(0);
- vTxn.pop_back();
- return (ret == 0);
- }
-
- bool TxnAbort()
- {
- if (!pdb)
- return false;
- if (vTxn.empty())
- return false;
- int ret = vTxn.back()->abort();
- vTxn.pop_back();
- return (ret == 0);
- }
-
- bool ReadVersion(int& nVersion)
- {
- nVersion = 0;
- return Read(string("version"), nVersion);
- }
-
- bool WriteVersion(int nVersion)
- {
- return Write(string("version"), nVersion);
- }
-};
-
-
-
-
-
-
-
-
-class CTxDB : public CDB
-{
-public:
- CTxDB(const char* pszMode="r+") : CDB(!fClient ? "blkindex.dat" : NULL, pszMode) { }
-private:
- CTxDB(const CTxDB&);
- void operator=(const CTxDB&);
-public:
- bool ReadTxIndex(uint256 hash, CTxIndex& txindex);
- bool UpdateTxIndex(uint256 hash, const CTxIndex& txindex);
- bool AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight);
- bool EraseTxIndex(const CTransaction& tx);
- bool ContainsTx(uint256 hash);
- bool ReadOwnerTxes(uint160 hash160, int nHeight, vector<CTransaction>& vtx);
- bool ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex);
- bool ReadDiskTx(uint256 hash, CTransaction& tx);
- bool ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex);
- bool ReadDiskTx(COutPoint outpoint, CTransaction& tx);
- bool WriteBlockIndex(const CDiskBlockIndex& blockindex);
- bool EraseBlockIndex(uint256 hash);
- bool ReadHashBestChain(uint256& hashBestChain);
- bool WriteHashBestChain(uint256 hashBestChain);
- bool LoadBlockIndex();
-};
-
-
-
-
-
-class CAddrDB : public CDB
-{
-public:
- CAddrDB(const char* pszMode="r+") : CDB("addr.dat", pszMode) { }
-private:
- CAddrDB(const CAddrDB&);
- void operator=(const CAddrDB&);
-public:
- bool WriteAddress(const CAddress& addr);
- bool LoadAddresses();
-};
-
-bool LoadAddresses();
-
-
-
-
-
-
-class CWalletDB : public CDB
-{
-public:
- CWalletDB(const char* pszMode="r+") : CDB("wallet.dat", pszMode) { }
-private:
- CWalletDB(const CWalletDB&);
- void operator=(const CWalletDB&);
-public:
- bool ReadName(const string& strAddress, string& strName)
- {
- strName = "";
- return Read(make_pair(string("name"), strAddress), strName);
- }
-
- bool WriteName(const string& strAddress, const string& strName)
- {
- CRITICAL_BLOCK(cs_mapAddressBook)
- mapAddressBook[strAddress] = strName;
- nWalletDBUpdated++;
- return Write(make_pair(string("name"), strAddress), strName);
- }
-
- bool EraseName(const string& strAddress)
- {
- // This should only be used for sending addresses, never for receiving addresses,
- // receiving addresses must always have an address book entry if they're not change return.
- CRITICAL_BLOCK(cs_mapAddressBook)
- mapAddressBook.erase(strAddress);
- nWalletDBUpdated++;
- return Erase(make_pair(string("name"), strAddress));
- }
-
- bool ReadTx(uint256 hash, CWalletTx& wtx)
- {
- return Read(make_pair(string("tx"), hash), wtx);
- }
-
- bool WriteTx(uint256 hash, const CWalletTx& wtx)
- {
- nWalletDBUpdated++;
- return Write(make_pair(string("tx"), hash), wtx);
- }
-
- bool EraseTx(uint256 hash)
- {
- nWalletDBUpdated++;
- return Erase(make_pair(string("tx"), hash));
- }
-
- bool ReadKey(const vector<unsigned char>& vchPubKey, CPrivKey& vchPrivKey)
- {
- vchPrivKey.clear();
- return Read(make_pair(string("key"), vchPubKey), vchPrivKey);
- }
-
- bool WriteKey(const vector<unsigned char>& vchPubKey, const CPrivKey& vchPrivKey)
- {
- nWalletDBUpdated++;
- return Write(make_pair(string("key"), vchPubKey), vchPrivKey, false);
- }
-
- bool ReadDefaultKey(vector<unsigned char>& vchPubKey)
- {
- vchPubKey.clear();
- return Read(string("defaultkey"), vchPubKey);
- }
-
- bool WriteDefaultKey(const vector<unsigned char>& vchPubKey)
- {
- vchDefaultKey = vchPubKey;
- nWalletDBUpdated++;
- return Write(string("defaultkey"), vchPubKey);
- }
-
- template<typename T>
- bool ReadSetting(const string& strKey, T& value)
- {
- return Read(make_pair(string("setting"), strKey), value);
- }
-
- template<typename T>
- bool WriteSetting(const string& strKey, const T& value)
- {
- nWalletDBUpdated++;
- return Write(make_pair(string("setting"), strKey), value);
- }
-
- bool LoadWallet();
-};
-
-bool LoadWallet(bool& fFirstRunRet);
-
-inline bool SetAddressBookName(const string& strAddress, const string& strName)
-{
- return CWalletDB().WriteName(strAddress, strName);
-}
+// Copyright (c) 2009-2010 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +class CTransaction; +class CTxIndex; +class CDiskBlockIndex; +class CDiskTxPos; +class COutPoint; +class CUser; +class CReview; +class CAddress; +class CWalletTx; + +extern map<string, string> mapAddressBook; +extern CCriticalSection cs_mapAddressBook; +extern vector<unsigned char> vchDefaultKey; +extern bool fClient; + + + +extern unsigned int nWalletDBUpdated; +extern DbEnv dbenv; + + +extern void DBFlush(bool fShutdown); + + + + +class CDB +{ +protected: + Db* pdb; + string strFile; + vector<DbTxn*> vTxn; + bool fReadOnly; + + explicit CDB(const char* pszFile, const char* pszMode="r+"); + ~CDB() { Close(); } +public: + void Close(); +private: + CDB(const CDB&); + void operator=(const CDB&); + +protected: + template<typename K, typename T> + bool Read(const K& key, T& value) + { + if (!pdb) + return false; + + // Key + CDataStream ssKey(SER_DISK); + ssKey.reserve(1000); + ssKey << key; + Dbt datKey(&ssKey[0], ssKey.size()); + + // Read + Dbt datValue; + datValue.set_flags(DB_DBT_MALLOC); + int ret = pdb->get(GetTxn(), &datKey, &datValue, 0); + memset(datKey.get_data(), 0, datKey.get_size()); + if (datValue.get_data() == NULL) + return false; + + // Unserialize value + CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK); + ssValue >> value; + + // Clear and free memory + memset(datValue.get_data(), 0, datValue.get_size()); + free(datValue.get_data()); + return (ret == 0); + } + + template<typename K, typename T> + bool Write(const K& key, const T& value, bool fOverwrite=true) + { + if (!pdb) + return false; + if (fReadOnly) + assert(("Write called on database in read-only mode", false)); + + // Key + CDataStream ssKey(SER_DISK); + ssKey.reserve(1000); + ssKey << key; + Dbt datKey(&ssKey[0], ssKey.size()); + + // Value + CDataStream ssValue(SER_DISK); + ssValue.reserve(10000); + ssValue << value; + Dbt datValue(&ssValue[0], ssValue.size()); + + // Write + int ret = pdb->put(GetTxn(), &datKey, &datValue, (fOverwrite ? 0 : DB_NOOVERWRITE)); + + // Clear memory in case it was a private key + memset(datKey.get_data(), 0, datKey.get_size()); + memset(datValue.get_data(), 0, datValue.get_size()); + return (ret == 0); + } + + template<typename K> + bool Erase(const K& key) + { + if (!pdb) + return false; + if (fReadOnly) + assert(("Erase called on database in read-only mode", false)); + + // Key + CDataStream ssKey(SER_DISK); + ssKey.reserve(1000); + ssKey << key; + Dbt datKey(&ssKey[0], ssKey.size()); + + // Erase + int ret = pdb->del(GetTxn(), &datKey, 0); + + // Clear memory + memset(datKey.get_data(), 0, datKey.get_size()); + return (ret == 0 || ret == DB_NOTFOUND); + } + + template<typename K> + bool Exists(const K& key) + { + if (!pdb) + return false; + + // Key + CDataStream ssKey(SER_DISK); + ssKey.reserve(1000); + ssKey << key; + Dbt datKey(&ssKey[0], ssKey.size()); + + // Exists + int ret = pdb->exists(GetTxn(), &datKey, 0); + + // Clear memory + memset(datKey.get_data(), 0, datKey.get_size()); + return (ret == 0); + } + + Dbc* GetCursor() + { + if (!pdb) + return NULL; + Dbc* pcursor = NULL; + int ret = pdb->cursor(NULL, &pcursor, 0); + if (ret != 0) + return NULL; + return pcursor; + } + + 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) + { + datKey.set_data(&ssKey[0]); + datKey.set_size(ssKey.size()); + } + Dbt datValue; + if (fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE) + { + datValue.set_data(&ssValue[0]); + datValue.set_size(ssValue.size()); + } + datKey.set_flags(DB_DBT_MALLOC); + datValue.set_flags(DB_DBT_MALLOC); + int ret = pcursor->get(&datKey, &datValue, fFlags); + if (ret != 0) + return ret; + else if (datKey.get_data() == NULL || datValue.get_data() == NULL) + return 99999; + + // Convert to streams + ssKey.SetType(SER_DISK); + ssKey.clear(); + ssKey.write((char*)datKey.get_data(), datKey.get_size()); + ssValue.SetType(SER_DISK); + ssValue.clear(); + ssValue.write((char*)datValue.get_data(), datValue.get_size()); + + // Clear and free memory + memset(datKey.get_data(), 0, datKey.get_size()); + memset(datValue.get_data(), 0, datValue.get_size()); + free(datKey.get_data()); + free(datValue.get_data()); + return 0; + } + + DbTxn* GetTxn() + { + if (!vTxn.empty()) + return vTxn.back(); + else + return NULL; + } + +public: + bool TxnBegin() + { + if (!pdb) + return false; + DbTxn* ptxn = NULL; + int ret = dbenv.txn_begin(GetTxn(), &ptxn, 0); + if (!ptxn || ret != 0) + return false; + vTxn.push_back(ptxn); + return true; + } + + bool TxnCommit() + { + if (!pdb) + return false; + if (vTxn.empty()) + return false; + int ret = vTxn.back()->commit(0); + vTxn.pop_back(); + return (ret == 0); + } + + bool TxnAbort() + { + if (!pdb) + return false; + if (vTxn.empty()) + return false; + int ret = vTxn.back()->abort(); + vTxn.pop_back(); + return (ret == 0); + } + + bool ReadVersion(int& nVersion) + { + nVersion = 0; + return Read(string("version"), nVersion); + } + + bool WriteVersion(int nVersion) + { + return Write(string("version"), nVersion); + } +}; + + + + + + + + +class CTxDB : public CDB +{ +public: + CTxDB(const char* pszMode="r+") : CDB(!fClient ? "blkindex.dat" : NULL, pszMode) { } +private: + CTxDB(const CTxDB&); + void operator=(const CTxDB&); +public: + bool ReadTxIndex(uint256 hash, CTxIndex& txindex); + bool UpdateTxIndex(uint256 hash, const CTxIndex& txindex); + bool AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight); + bool EraseTxIndex(const CTransaction& tx); + bool ContainsTx(uint256 hash); + bool ReadOwnerTxes(uint160 hash160, int nHeight, vector<CTransaction>& vtx); + bool ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex); + bool ReadDiskTx(uint256 hash, CTransaction& tx); + bool ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex); + bool ReadDiskTx(COutPoint outpoint, CTransaction& tx); + bool WriteBlockIndex(const CDiskBlockIndex& blockindex); + bool EraseBlockIndex(uint256 hash); + bool ReadHashBestChain(uint256& hashBestChain); + bool WriteHashBestChain(uint256 hashBestChain); + bool LoadBlockIndex(); +}; + + + + + +class CAddrDB : public CDB +{ +public: + CAddrDB(const char* pszMode="r+") : CDB("addr.dat", pszMode) { } +private: + CAddrDB(const CAddrDB&); + void operator=(const CAddrDB&); +public: + bool WriteAddress(const CAddress& addr); + bool LoadAddresses(); +}; + +bool LoadAddresses(); + + + + + + +class CWalletDB : public CDB +{ +public: + CWalletDB(const char* pszMode="r+") : CDB("wallet.dat", pszMode) { } +private: + CWalletDB(const CWalletDB&); + void operator=(const CWalletDB&); +public: + bool ReadName(const string& strAddress, string& strName) + { + strName = ""; + return Read(make_pair(string("name"), strAddress), strName); + } + + bool WriteName(const string& strAddress, const string& strName) + { + CRITICAL_BLOCK(cs_mapAddressBook) + mapAddressBook[strAddress] = strName; + nWalletDBUpdated++; + return Write(make_pair(string("name"), strAddress), strName); + } + + bool EraseName(const string& strAddress) + { + // This should only be used for sending addresses, never for receiving addresses, + // receiving addresses must always have an address book entry if they're not change return. + CRITICAL_BLOCK(cs_mapAddressBook) + mapAddressBook.erase(strAddress); + nWalletDBUpdated++; + return Erase(make_pair(string("name"), strAddress)); + } + + bool ReadTx(uint256 hash, CWalletTx& wtx) + { + return Read(make_pair(string("tx"), hash), wtx); + } + + bool WriteTx(uint256 hash, const CWalletTx& wtx) + { + nWalletDBUpdated++; + return Write(make_pair(string("tx"), hash), wtx); + } + + bool EraseTx(uint256 hash) + { + nWalletDBUpdated++; + return Erase(make_pair(string("tx"), hash)); + } + + bool ReadKey(const vector<unsigned char>& vchPubKey, CPrivKey& vchPrivKey) + { + vchPrivKey.clear(); + return Read(make_pair(string("key"), vchPubKey), vchPrivKey); + } + + bool WriteKey(const vector<unsigned char>& vchPubKey, const CPrivKey& vchPrivKey) + { + nWalletDBUpdated++; + return Write(make_pair(string("key"), vchPubKey), vchPrivKey, false); + } + + bool ReadDefaultKey(vector<unsigned char>& vchPubKey) + { + vchPubKey.clear(); + return Read(string("defaultkey"), vchPubKey); + } + + bool WriteDefaultKey(const vector<unsigned char>& vchPubKey) + { + vchDefaultKey = vchPubKey; + nWalletDBUpdated++; + return Write(string("defaultkey"), vchPubKey); + } + + template<typename T> + bool ReadSetting(const string& strKey, T& value) + { + return Read(make_pair(string("setting"), strKey), value); + } + + template<typename T> + bool WriteSetting(const string& strKey, const T& value) + { + nWalletDBUpdated++; + return Write(make_pair(string("setting"), strKey), value); + } + + bool LoadWallet(); +}; + +bool LoadWallet(bool& fFirstRunRet); + +inline bool SetAddressBookName(const string& strAddress, const string& strName) +{ + return CWalletDB().WriteName(strAddress, strName); +} @@ -1,127 +1,127 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
-
-#ifdef _MSC_VER
-#pragma warning(disable:4786)
-#pragma warning(disable:4804)
-#pragma warning(disable:4805)
-#pragma warning(disable:4717)
-#endif
-#ifdef _WIN32_WINNT
-#undef _WIN32_WINNT
-#endif
-#define _WIN32_WINNT 0x0400
-#ifdef _WIN32_IE
-#undef _WIN32_IE
-#endif
-#define _WIN32_IE 0x0400
-#define WIN32_LEAN_AND_MEAN 1
-#define __STDC_LIMIT_MACROS // to enable UINT64_MAX from stdint.h
-#include <wx/wx.h>
-#include <wx/stdpaths.h>
-#include <wx/snglinst.h>
-#if wxUSE_GUI
-#include <wx/utils.h>
-#include <wx/clipbrd.h>
-#include <wx/taskbar.h>
-#endif
-#include <openssl/ecdsa.h>
-#include <openssl/evp.h>
-#include <openssl/rand.h>
-#include <openssl/sha.h>
-#include <openssl/ripemd.h>
-#include <db_cxx.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include <limits.h>
-#include <float.h>
-#include <assert.h>
-#include <memory>
-#include <iostream>
-#include <sstream>
-#include <string>
-#include <vector>
-#include <list>
-#include <deque>
-#include <map>
-#include <set>
-#include <algorithm>
-#include <numeric>
-#include <boost/foreach.hpp>
-#include <boost/lexical_cast.hpp>
-#include <boost/tuple/tuple.hpp>
-#include <boost/tuple/tuple_comparison.hpp>
-#include <boost/tuple/tuple_io.hpp>
-#include <boost/array.hpp>
-#include <boost/bind.hpp>
-#include <boost/function.hpp>
-#include <boost/filesystem.hpp>
-#include <boost/filesystem/fstream.hpp>
-#include <boost/algorithm/string.hpp>
-#include <boost/interprocess/sync/interprocess_mutex.hpp>
-#include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
-#include <boost/date_time/gregorian/gregorian_types.hpp>
-#include <boost/date_time/posix_time/posix_time_types.hpp>
-
-#ifdef __WXMSW__
-#include <windows.h>
-#include <winsock2.h>
-#include <mswsock.h>
-#include <shlobj.h>
-#include <shlwapi.h>
-#include <io.h>
-#include <process.h>
-#include <malloc.h>
-#else
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <unistd.h>
-#include <errno.h>
-#include <net/if.h>
-#include <ifaddrs.h>
-#endif
-#ifdef __BSD__
-#include <netinet/in.h>
-#endif
-
-
-#pragma hdrstop
-using namespace std;
-using namespace boost;
-
-#include "strlcpy.h"
-#include "serialize.h"
-#include "uint256.h"
-#include "util.h"
-#include "key.h"
-#include "bignum.h"
-#include "base58.h"
-#include "script.h"
-#include "db.h"
-#include "net.h"
-#include "irc.h"
-#include "main.h"
-#include "rpc.h"
-#if wxUSE_GUI
-#include "uibase.h"
-#endif
-#include "ui.h"
-#include "init.h"
-
-#include "xpm/addressbook16.xpm"
-#include "xpm/addressbook20.xpm"
-#include "xpm/bitcoin16.xpm"
-#include "xpm/bitcoin20.xpm"
-#include "xpm/bitcoin32.xpm"
-#include "xpm/bitcoin48.xpm"
-#include "xpm/bitcoin80.xpm"
-#include "xpm/check.xpm"
-#include "xpm/send16.xpm"
-#include "xpm/send16noshadow.xpm"
-#include "xpm/send20.xpm"
-#include "xpm/about.xpm"
+// Copyright (c) 2009-2010 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +#ifdef _MSC_VER +#pragma warning(disable:4786) +#pragma warning(disable:4804) +#pragma warning(disable:4805) +#pragma warning(disable:4717) +#endif +#ifdef _WIN32_WINNT +#undef _WIN32_WINNT +#endif +#define _WIN32_WINNT 0x0400 +#ifdef _WIN32_IE +#undef _WIN32_IE +#endif +#define _WIN32_IE 0x0400 +#define WIN32_LEAN_AND_MEAN 1 +#define __STDC_LIMIT_MACROS // to enable UINT64_MAX from stdint.h +#include <wx/wx.h> +#include <wx/stdpaths.h> +#include <wx/snglinst.h> +#if wxUSE_GUI +#include <wx/utils.h> +#include <wx/clipbrd.h> +#include <wx/taskbar.h> +#endif +#include <openssl/ecdsa.h> +#include <openssl/evp.h> +#include <openssl/rand.h> +#include <openssl/sha.h> +#include <openssl/ripemd.h> +#include <db_cxx.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <limits.h> +#include <float.h> +#include <assert.h> +#include <memory> +#include <iostream> +#include <sstream> +#include <string> +#include <vector> +#include <list> +#include <deque> +#include <map> +#include <set> +#include <algorithm> +#include <numeric> +#include <boost/foreach.hpp> +#include <boost/lexical_cast.hpp> +#include <boost/tuple/tuple.hpp> +#include <boost/tuple/tuple_comparison.hpp> +#include <boost/tuple/tuple_io.hpp> +#include <boost/array.hpp> +#include <boost/bind.hpp> +#include <boost/function.hpp> +#include <boost/filesystem.hpp> +#include <boost/filesystem/fstream.hpp> +#include <boost/algorithm/string.hpp> +#include <boost/interprocess/sync/interprocess_mutex.hpp> +#include <boost/interprocess/sync/interprocess_recursive_mutex.hpp> +#include <boost/date_time/gregorian/gregorian_types.hpp> +#include <boost/date_time/posix_time/posix_time_types.hpp> + +#ifdef __WXMSW__ +#include <windows.h> +#include <winsock2.h> +#include <mswsock.h> +#include <shlobj.h> +#include <shlwapi.h> +#include <io.h> +#include <process.h> +#include <malloc.h> +#else +#include <sys/time.h> +#include <sys/resource.h> +#include <sys/socket.h> +#include <arpa/inet.h> +#include <netdb.h> +#include <unistd.h> +#include <errno.h> +#include <net/if.h> +#include <ifaddrs.h> +#endif +#ifdef __BSD__ +#include <netinet/in.h> +#endif + + +#pragma hdrstop +using namespace std; +using namespace boost; + +#include "strlcpy.h" +#include "serialize.h" +#include "uint256.h" +#include "util.h" +#include "key.h" +#include "bignum.h" +#include "base58.h" +#include "script.h" +#include "db.h" +#include "net.h" +#include "irc.h" +#include "main.h" +#include "rpc.h" +#if wxUSE_GUI +#include "uibase.h" +#endif +#include "ui.h" +#include "init.h" + +#include "xpm/addressbook16.xpm" +#include "xpm/addressbook20.xpm" +#include "xpm/bitcoin16.xpm" +#include "xpm/bitcoin20.xpm" +#include "xpm/bitcoin32.xpm" +#include "xpm/bitcoin48.xpm" +#include "xpm/bitcoin80.xpm" +#include "xpm/check.xpm" +#include "xpm/send16.xpm" +#include "xpm/send16noshadow.xpm" +#include "xpm/send20.xpm" +#include "xpm/about.xpm" @@ -1,678 +1,678 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
-
-#include "headers.h"
-
-
-
-
-void ExitTimeout(void* parg)
-{
-#ifdef __WXMSW__
- Sleep(5000);
- ExitProcess(0);
-#endif
-}
-
-void Shutdown(void* parg)
-{
- static CCriticalSection cs_Shutdown;
- static bool fTaken;
- bool fFirstThread;
- CRITICAL_BLOCK(cs_Shutdown)
- {
- fFirstThread = !fTaken;
- fTaken = true;
- }
- static bool fExit;
- if (fFirstThread)
- {
- fShutdown = true;
- nTransactionsUpdated++;
- DBFlush(false);
- StopNode();
- DBFlush(true);
- CreateThread(ExitTimeout, NULL);
- Sleep(50);
- printf("Bitcoin exiting\n\n");
- fExit = true;
- exit(0);
- }
- else
- {
- while (!fExit)
- Sleep(500);
- Sleep(100);
- ExitThread(0);
- }
-}
-
-
-
-
-
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// Startup folder
-//
-
-#ifdef __WXMSW__
-string StartupShortcutPath()
-{
- return MyGetSpecialFolderPath(CSIDL_STARTUP, true) + "\\Bitcoin.lnk";
-}
-
-bool GetStartOnSystemStartup()
-{
- return filesystem::exists(StartupShortcutPath().c_str());
-}
-
-void SetStartOnSystemStartup(bool fAutoStart)
-{
- // If the shortcut exists already, remove it for updating
- remove(StartupShortcutPath().c_str());
-
- if (fAutoStart)
- {
- CoInitialize(NULL);
-
- // Get a pointer to the IShellLink interface.
- IShellLink* psl = NULL;
- HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL,
- CLSCTX_INPROC_SERVER, IID_IShellLink,
- reinterpret_cast<void**>(&psl));
-
- if (SUCCEEDED(hres))
- {
- // Get the current executable path
- TCHAR pszExePath[MAX_PATH];
- GetModuleFileName(NULL, pszExePath, sizeof(pszExePath));
-
- // Set the path to the shortcut target
- psl->SetPath(pszExePath);
- PathRemoveFileSpec(pszExePath);
- psl->SetWorkingDirectory(pszExePath);
- psl->SetShowCmd(SW_SHOWMINNOACTIVE);
-
- // Query IShellLink for the IPersistFile interface for
- // saving the shortcut in persistent storage.
- IPersistFile* ppf = NULL;
- hres = psl->QueryInterface(IID_IPersistFile,
- reinterpret_cast<void**>(&ppf));
- if (SUCCEEDED(hres))
- {
- WCHAR pwsz[MAX_PATH];
- // Ensure that the string is ANSI.
- MultiByteToWideChar(CP_ACP, 0, StartupShortcutPath().c_str(), -1, pwsz, MAX_PATH);
- // Save the link by calling IPersistFile::Save.
- hres = ppf->Save(pwsz, TRUE);
- ppf->Release();
- }
- psl->Release();
- }
- CoUninitialize();
- }
-}
-
-#elif defined(__WXGTK__)
-
-//
-// Follow the Desktop Application Autostart Spec:
-// http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html
-//
-
-boost::filesystem::path GetAutostartDir()
-{
- namespace fs = boost::filesystem;
-
- char* pszConfigHome = getenv("XDG_CONFIG_HOME");
- if (pszConfigHome) return fs::path(pszConfigHome) / fs::path("autostart");
- char* pszHome = getenv("HOME");
- if (pszHome) return fs::path(pszHome) / fs::path(".config/autostart");
- return fs::path();
-}
-
-boost::filesystem::path GetAutostartFilePath()
-{
- return GetAutostartDir() / boost::filesystem::path("bitcoin.desktop");
-}
-
-bool GetStartOnSystemStartup()
-{
- boost::filesystem::ifstream optionFile(GetAutostartFilePath());
- if (!optionFile.good())
- return false;
- // Scan through file for "Hidden=true":
- string line;
- while (!optionFile.eof())
- {
- getline(optionFile, line);
- if (line.find("Hidden") != string::npos &&
- line.find("true") != string::npos)
- return false;
- }
- optionFile.close();
-
- return true;
-}
-
-void SetStartOnSystemStartup(bool fAutoStart)
-{
- if (!fAutoStart)
- {
- unlink(GetAutostartFilePath().native_file_string().c_str());
- }
- else
- {
- boost::filesystem::create_directories(GetAutostartDir());
-
- boost::filesystem::ofstream optionFile(GetAutostartFilePath(), ios_base::out|ios_base::trunc);
- if (!optionFile.good())
- {
- wxMessageBox(_("Cannot write autostart/bitcoin.desktop file"), "Bitcoin");
- return;
- }
- // Write a bitcoin.desktop file to the autostart directory:
- char pszExePath[MAX_PATH+1];
- memset(pszExePath, 0, sizeof(pszExePath));
- readlink("/proc/self/exe", pszExePath, sizeof(pszExePath)-1);
- optionFile << "[Desktop Entry]\n";
- optionFile << "Type=Application\n";
- optionFile << "Name=Bitcoin\n";
- optionFile << "Exec=" << pszExePath << "\n";
- optionFile << "Terminal=false\n";
- optionFile << "Hidden=false\n";
- optionFile.close();
- }
-}
-#else
-
-// TODO: OSX startup stuff; see:
-// http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPSystemStartup/Articles/CustomLogin.html
-
-bool GetStartOnSystemStartup() { return false; }
-void SetStartOnSystemStartup(bool fAutoStart) { }
-
-#endif
-
-
-
-
-
-
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// CMyApp
-//
-
-// Define a new application
-class CMyApp : public wxApp
-{
-public:
- wxLocale m_locale;
-
- CMyApp(){};
- ~CMyApp(){};
- bool OnInit();
- bool OnInit2();
- int OnExit();
-
- // Hook Initialize so we can start without GUI
- virtual bool Initialize(int& argc, wxChar** argv);
-
- // 2nd-level exception handling: we get all the exceptions occurring in any
- // event handler here
- virtual bool OnExceptionInMainLoop();
-
- // 3rd, and final, level exception handling: whenever an unhandled
- // exception is caught, this function is called
- virtual void OnUnhandledException();
-
- // and now for something different: this function is called in case of a
- // crash (e.g. dereferencing null pointer, division by 0, ...)
- virtual void OnFatalException();
-};
-
-IMPLEMENT_APP(CMyApp)
-
-bool CMyApp::Initialize(int& argc, wxChar** argv)
-{
- if (argc > 1 && argv[1][0] != '-' && (!fWindows || argv[1][0] != '/') &&
- wxString(argv[1]) != "start")
- {
- fCommandLine = true;
- }
- else if (!fGUI)
- {
- fDaemon = true;
- }
- else
- {
- // wxApp::Initialize will remove environment-specific parameters,
- // so it's too early to call ParseParameters yet
- for (int i = 1; i < argc; i++)
- {
- wxString str = argv[i];
- #ifdef __WXMSW__
- if (str.size() >= 1 && str[0] == '/')
- str[0] = '-';
- char pszLower[MAX_PATH];
- strlcpy(pszLower, str.c_str(), sizeof(pszLower));
- strlwr(pszLower);
- str = pszLower;
- #endif
- // haven't decided which argument to use for this yet
- if (str == "-daemon" || str == "-d" || str == "start")
- fDaemon = true;
- }
- }
-
-#ifdef __WXGTK__
- if (fDaemon || fCommandLine)
- {
- // Call the original Initialize while suppressing error messages
- // and ignoring failure. If unable to initialize GTK, it fails
- // near the end so hopefully the last few things don't matter.
- {
- wxLogNull logNo;
- wxApp::Initialize(argc, argv);
- }
-
- if (fDaemon)
- {
- // Daemonize
- pid_t pid = fork();
- if (pid < 0)
- {
- fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno);
- return false;
- }
- if (pid > 0)
- pthread_exit((void*)0);
- }
-
- return true;
- }
-#endif
-
- return wxApp::Initialize(argc, argv);
-}
-
-bool CMyApp::OnInit()
-{
- bool fRet = false;
- try
- {
- fRet = OnInit2();
- }
- catch (std::exception& e) {
- PrintException(&e, "OnInit()");
- } catch (...) {
- PrintException(NULL, "OnInit()");
- }
- if (!fRet)
- Shutdown(NULL);
- return fRet;
-}
-
-extern int g_isPainting;
-
-bool CMyApp::OnInit2()
-{
-#ifdef _MSC_VER
- // Turn off microsoft heap dump noise
- _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
- _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0));
-#endif
-#if _MSC_VER >= 1400
- // Disable confusing "helpful" text message on abort, ctrl-c
- _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
-#endif
-#if defined(__WXMSW__) && defined(__WXDEBUG__) && wxUSE_GUI
- // Disable malfunctioning wxWidgets debug assertion
- g_isPainting = 10000;
-#endif
-#if wxUSE_GUI
- wxImage::AddHandler(new wxPNGHandler);
-#endif
-#if defined(__WXMSW__ ) || defined(__WXMAC__)
- SetAppName("Bitcoin");
-#else
- SetAppName("bitcoin");
-#endif
-#ifndef __WXMSW__
- umask(077);
-#endif
-#ifdef __WXMSW__
-#if wxUSE_UNICODE
- // Hack to set wxConvLibc codepage to UTF-8 on Windows,
- // may break if wxMBConv_win32 implementation in strconv.cpp changes.
- class wxMBConv_win32 : public wxMBConv
- {
- public:
- long m_CodePage;
- size_t m_minMBCharWidth;
- };
- if (((wxMBConv_win32*)&wxConvLibc)->m_CodePage == CP_ACP)
- ((wxMBConv_win32*)&wxConvLibc)->m_CodePage = CP_UTF8;
-#endif
-#endif
-
- // Load locale/<lang>/LC_MESSAGES/bitcoin.mo language file
- m_locale.Init(wxLANGUAGE_DEFAULT, 0);
- m_locale.AddCatalogLookupPathPrefix("locale");
- if (!fWindows)
- {
- m_locale.AddCatalogLookupPathPrefix("/usr/share/locale");
- m_locale.AddCatalogLookupPathPrefix("/usr/local/share/locale");
- }
- m_locale.AddCatalog("wxstd"); // wxWidgets standard translations, if any
- m_locale.AddCatalog("bitcoin");
-
- //
- // Parameters
- //
- if (fCommandLine)
- {
- int ret = CommandLineRPC(argc, argv);
- exit(ret);
- }
-
- ParseParameters(argc, argv);
- if (mapArgs.count("-?") || mapArgs.count("--help"))
- {
- wxString strUsage = string() +
- _("Usage:") + "\t\t\t\t\t\t\t\t\t\t\n" +
- " bitcoin [options] \t" + "\n" +
- " bitcoin [command] \t" + _("Send command to bitcoin running with -server or -daemon\n") +
- " bitcoin [command] -? \t" + _("Get help for a command\n") +
- " bitcoin help \t" + _("List commands\n") +
- _("Options:\n") +
- " -gen \t " + _("Generate coins\n") +
- " -gen=0 \t " + _("Don't generate coins\n") +
- " -min \t " + _("Start minimized\n") +
- " -datadir=<dir> \t " + _("Specify data directory\n") +
- " -proxy=<ip:port>\t " + _("Connect through socks4 proxy\n") +
- " -addnode=<ip> \t " + _("Add a node to connect to\n") +
- " -connect=<ip> \t " + _("Connect only to the specified node\n") +
- " -server \t " + _("Accept command line and JSON-RPC commands\n") +
- " -daemon \t " + _("Run in the background as a daemon and accept commands\n") +
- " -? \t " + _("This help message\n");
-
-#if defined(__WXMSW__) && wxUSE_GUI
- // Tabs make the columns line up in the message box
- wxMessageBox(strUsage, "Bitcoin", wxOK);
-#else
- // Remove tabs
- strUsage.Replace("\t", "");
- fprintf(stderr, "%s", ((string)strUsage).c_str());
-#endif
- return false;
- }
-
- if (mapArgs.count("-datadir"))
- strlcpy(pszSetDataDir, mapArgs["-datadir"].c_str(), sizeof(pszSetDataDir));
-
- if (mapArgs.count("-debug"))
- fDebug = true;
-
- if (mapArgs.count("-printtodebugger"))
- fPrintToDebugger = true;
-
- if (!fDebug && !pszSetDataDir[0])
- ShrinkDebugFile();
- printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
- printf("Bitcoin version %d.%d.%d%s beta, OS version %s\n", VERSION/10000, (VERSION/100)%100, VERSION%100, pszSubVer, ((string)wxGetOsDescription()).c_str());
- printf("System default language is %d %s\n", m_locale.GetSystemLanguage(), ((string)m_locale.GetSysName()).c_str());
- printf("Language file %s (%s)\n", (string("locale/") + (string)m_locale.GetCanonicalName() + "/LC_MESSAGES/bitcoin.mo").c_str(), ((string)m_locale.GetLocale()).c_str());
- printf("Default data directory %s\n", GetDefaultDataDir().c_str());
-
- if (mapArgs.count("-loadblockindextest"))
- {
- CTxDB txdb("r");
- txdb.LoadBlockIndex();
- PrintBlockTree();
- return false;
- }
-
- //
- // Limit to single instance per user
- // Required to protect the database files if we're going to keep deleting log.*
- //
-#ifdef __WXMSW__
- // todo: wxSingleInstanceChecker wasn't working on Linux, never deleted its lock file
- // maybe should go by whether successfully bind port 8333 instead
- wxString strMutexName = wxString("bitcoin_running.") + getenv("HOMEPATH");
- for (int i = 0; i < strMutexName.size(); i++)
- if (!isalnum(strMutexName[i]))
- strMutexName[i] = '.';
- wxSingleInstanceChecker* psingleinstancechecker = new wxSingleInstanceChecker(strMutexName);
- if (psingleinstancechecker->IsAnotherRunning())
- {
- printf("Existing instance found\n");
- unsigned int nStart = GetTime();
- loop
- {
- // TODO: find out how to do this in Linux, or replace with wxWidgets commands
- // Show the previous instance and exit
- HWND hwndPrev = FindWindowA("wxWindowClassNR", "Bitcoin");
- if (hwndPrev)
- {
- if (IsIconic(hwndPrev))
- ShowWindow(hwndPrev, SW_RESTORE);
- SetForegroundWindow(hwndPrev);
- return false;
- }
-
- if (GetTime() > nStart + 60)
- return false;
-
- // Resume this instance if the other exits
- delete psingleinstancechecker;
- Sleep(1000);
- psingleinstancechecker = new wxSingleInstanceChecker(strMutexName);
- if (!psingleinstancechecker->IsAnotherRunning())
- break;
- }
- }
-#endif
-
- // Bind to the port early so we can tell if another instance is already running.
- // This is a backup to wxSingleInstanceChecker, which doesn't work on Linux.
- string strErrors;
- if (!BindListenPort(strErrors))
- {
- wxMessageBox(strErrors, "Bitcoin");
- return false;
- }
-
- //
- // Load data files
- //
- if (fDaemon)
- fprintf(stdout, "bitcoin server starting\n");
- strErrors = "";
- int64 nStart;
-
- printf("Loading addresses...\n");
- nStart = GetTimeMillis();
- if (!LoadAddresses())
- strErrors += _("Error loading addr.dat \n");
- printf(" addresses %15"PRI64d"ms\n", GetTimeMillis() - nStart);
-
- printf("Loading block index...\n");
- nStart = GetTimeMillis();
- if (!LoadBlockIndex())
- strErrors += _("Error loading blkindex.dat \n");
- printf(" block index %15"PRI64d"ms\n", GetTimeMillis() - nStart);
-
- printf("Loading wallet...\n");
- nStart = GetTimeMillis();
- bool fFirstRun;
- if (!LoadWallet(fFirstRun))
- strErrors += _("Error loading wallet.dat \n");
- printf(" wallet %15"PRI64d"ms\n", GetTimeMillis() - nStart);
-
- printf("Done loading\n");
-
- //// debug print
- printf("mapBlockIndex.size() = %d\n", mapBlockIndex.size());
- printf("nBestHeight = %d\n", nBestHeight);
- printf("mapKeys.size() = %d\n", mapKeys.size());
- printf("mapPubKeys.size() = %d\n", mapPubKeys.size());
- printf("mapWallet.size() = %d\n", mapWallet.size());
- printf("mapAddressBook.size() = %d\n", mapAddressBook.size());
-
- if (!strErrors.empty())
- {
- wxMessageBox(strErrors, "Bitcoin");
- return false;
- }
-
- // Add wallet transactions that aren't already in a block to mapTransactions
- ReacceptWalletTransactions();
-
- //
- // Parameters
- //
- if (mapArgs.count("-printblockindex") || mapArgs.count("-printblocktree"))
- {
- PrintBlockTree();
- return false;
- }
-
- if (mapArgs.count("-printblock"))
- {
- string strMatch = mapArgs["-printblock"];
- int nFound = 0;
- for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi)
- {
- uint256 hash = (*mi).first;
- if (strncmp(hash.ToString().c_str(), strMatch.c_str(), strMatch.size()) == 0)
- {
- CBlockIndex* pindex = (*mi).second;
- CBlock block;
- block.ReadFromDisk(pindex);
- block.BuildMerkleTree();
- block.print();
- printf("\n");
- nFound++;
- }
- }
- if (nFound == 0)
- printf("No blocks matching %s were found\n", strMatch.c_str());
- return false;
- }
-
- if (mapArgs.count("-gen"))
- {
- if (mapArgs["-gen"].empty())
- fGenerateBitcoins = true;
- else
- fGenerateBitcoins = (atoi(mapArgs["-gen"].c_str()) != 0);
- }
-
- if (mapArgs.count("-proxy"))
- {
- fUseProxy = true;
- addrProxy = CAddress(mapArgs["-proxy"]);
- if (!addrProxy.IsValid())
- {
- wxMessageBox(_("Invalid -proxy address"), "Bitcoin");
- return false;
- }
- }
-
- if (mapArgs.count("-addnode"))
- {
- foreach(string strAddr, mapMultiArgs["-addnode"])
- {
- CAddress addr(strAddr, NODE_NETWORK);
- addr.nTime = 0; // so it won't relay unless successfully connected
- if (addr.IsValid())
- AddAddress(addr);
- }
- }
-
- //
- // Create the main window and start the node
- //
- if (!fDaemon)
- CreateMainWindow();
-
- if (!CheckDiskSpace())
- return false;
-
- RandAddSeedPerfmon();
-
- if (!CreateThread(StartNode, NULL))
- wxMessageBox("Error: CreateThread(StartNode) failed", "Bitcoin");
-
- if (mapArgs.count("-server") || fDaemon)
- CreateThread(ThreadRPCServer, NULL);
-
- if (fFirstRun)
- SetStartOnSystemStartup(true);
-
- return true;
-}
-
-int CMyApp::OnExit()
-{
- Shutdown(NULL);
- return wxApp::OnExit();
-}
-
-bool CMyApp::OnExceptionInMainLoop()
-{
- try
- {
- throw;
- }
- catch (std::exception& e)
- {
- PrintException(&e, "CMyApp::OnExceptionInMainLoop()");
- wxLogWarning("Exception %s %s", typeid(e).name(), e.what());
- Sleep(1000);
- throw;
- }
- catch (...)
- {
- PrintException(NULL, "CMyApp::OnExceptionInMainLoop()");
- wxLogWarning("Unknown exception");
- Sleep(1000);
- throw;
- }
- return true;
-}
-
-void CMyApp::OnUnhandledException()
-{
- // this shows how we may let some exception propagate uncaught
- try
- {
- throw;
- }
- catch (std::exception& e)
- {
- PrintException(&e, "CMyApp::OnUnhandledException()");
- wxLogWarning("Exception %s %s", typeid(e).name(), e.what());
- Sleep(1000);
- throw;
- }
- catch (...)
- {
- PrintException(NULL, "CMyApp::OnUnhandledException()");
- wxLogWarning("Unknown exception");
- Sleep(1000);
- throw;
- }
-}
-
-void CMyApp::OnFatalException()
-{
- wxMessageBox(_("Program has crashed and will terminate. "), "Bitcoin", wxOK | wxICON_ERROR);
-}
+// Copyright (c) 2009-2010 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +#include "headers.h" + + + + +void ExitTimeout(void* parg) +{ +#ifdef __WXMSW__ + Sleep(5000); + ExitProcess(0); +#endif +} + +void Shutdown(void* parg) +{ + static CCriticalSection cs_Shutdown; + static bool fTaken; + bool fFirstThread; + CRITICAL_BLOCK(cs_Shutdown) + { + fFirstThread = !fTaken; + fTaken = true; + } + static bool fExit; + if (fFirstThread) + { + fShutdown = true; + nTransactionsUpdated++; + DBFlush(false); + StopNode(); + DBFlush(true); + CreateThread(ExitTimeout, NULL); + Sleep(50); + printf("Bitcoin exiting\n\n"); + fExit = true; + exit(0); + } + else + { + while (!fExit) + Sleep(500); + Sleep(100); + ExitThread(0); + } +} + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// Startup folder +// + +#ifdef __WXMSW__ +string StartupShortcutPath() +{ + return MyGetSpecialFolderPath(CSIDL_STARTUP, true) + "\\Bitcoin.lnk"; +} + +bool GetStartOnSystemStartup() +{ + return filesystem::exists(StartupShortcutPath().c_str()); +} + +void SetStartOnSystemStartup(bool fAutoStart) +{ + // If the shortcut exists already, remove it for updating + remove(StartupShortcutPath().c_str()); + + if (fAutoStart) + { + CoInitialize(NULL); + + // Get a pointer to the IShellLink interface. + IShellLink* psl = NULL; + HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, + CLSCTX_INPROC_SERVER, IID_IShellLink, + reinterpret_cast<void**>(&psl)); + + if (SUCCEEDED(hres)) + { + // Get the current executable path + TCHAR pszExePath[MAX_PATH]; + GetModuleFileName(NULL, pszExePath, sizeof(pszExePath)); + + // Set the path to the shortcut target + psl->SetPath(pszExePath); + PathRemoveFileSpec(pszExePath); + psl->SetWorkingDirectory(pszExePath); + psl->SetShowCmd(SW_SHOWMINNOACTIVE); + + // Query IShellLink for the IPersistFile interface for + // saving the shortcut in persistent storage. + IPersistFile* ppf = NULL; + hres = psl->QueryInterface(IID_IPersistFile, + reinterpret_cast<void**>(&ppf)); + if (SUCCEEDED(hres)) + { + WCHAR pwsz[MAX_PATH]; + // Ensure that the string is ANSI. + MultiByteToWideChar(CP_ACP, 0, StartupShortcutPath().c_str(), -1, pwsz, MAX_PATH); + // Save the link by calling IPersistFile::Save. + hres = ppf->Save(pwsz, TRUE); + ppf->Release(); + } + psl->Release(); + } + CoUninitialize(); + } +} + +#elif defined(__WXGTK__) + +// +// Follow the Desktop Application Autostart Spec: +// http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html +// + +boost::filesystem::path GetAutostartDir() +{ + namespace fs = boost::filesystem; + + char* pszConfigHome = getenv("XDG_CONFIG_HOME"); + if (pszConfigHome) return fs::path(pszConfigHome) / fs::path("autostart"); + char* pszHome = getenv("HOME"); + if (pszHome) return fs::path(pszHome) / fs::path(".config/autostart"); + return fs::path(); +} + +boost::filesystem::path GetAutostartFilePath() +{ + return GetAutostartDir() / boost::filesystem::path("bitcoin.desktop"); +} + +bool GetStartOnSystemStartup() +{ + boost::filesystem::ifstream optionFile(GetAutostartFilePath()); + if (!optionFile.good()) + return false; + // Scan through file for "Hidden=true": + string line; + while (!optionFile.eof()) + { + getline(optionFile, line); + if (line.find("Hidden") != string::npos && + line.find("true") != string::npos) + return false; + } + optionFile.close(); + + return true; +} + +void SetStartOnSystemStartup(bool fAutoStart) +{ + if (!fAutoStart) + { + unlink(GetAutostartFilePath().native_file_string().c_str()); + } + else + { + boost::filesystem::create_directories(GetAutostartDir()); + + boost::filesystem::ofstream optionFile(GetAutostartFilePath(), ios_base::out|ios_base::trunc); + if (!optionFile.good()) + { + wxMessageBox(_("Cannot write autostart/bitcoin.desktop file"), "Bitcoin"); + return; + } + // Write a bitcoin.desktop file to the autostart directory: + char pszExePath[MAX_PATH+1]; + memset(pszExePath, 0, sizeof(pszExePath)); + readlink("/proc/self/exe", pszExePath, sizeof(pszExePath)-1); + optionFile << "[Desktop Entry]\n"; + optionFile << "Type=Application\n"; + optionFile << "Name=Bitcoin\n"; + optionFile << "Exec=" << pszExePath << "\n"; + optionFile << "Terminal=false\n"; + optionFile << "Hidden=false\n"; + optionFile.close(); + } +} +#else + +// TODO: OSX startup stuff; see: +// http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPSystemStartup/Articles/CustomLogin.html + +bool GetStartOnSystemStartup() { return false; } +void SetStartOnSystemStartup(bool fAutoStart) { } + +#endif + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CMyApp +// + +// Define a new application +class CMyApp : public wxApp +{ +public: + wxLocale m_locale; + + CMyApp(){}; + ~CMyApp(){}; + bool OnInit(); + bool OnInit2(); + int OnExit(); + + // Hook Initialize so we can start without GUI + virtual bool Initialize(int& argc, wxChar** argv); + + // 2nd-level exception handling: we get all the exceptions occurring in any + // event handler here + virtual bool OnExceptionInMainLoop(); + + // 3rd, and final, level exception handling: whenever an unhandled + // exception is caught, this function is called + virtual void OnUnhandledException(); + + // and now for something different: this function is called in case of a + // crash (e.g. dereferencing null pointer, division by 0, ...) + virtual void OnFatalException(); +}; + +IMPLEMENT_APP(CMyApp) + +bool CMyApp::Initialize(int& argc, wxChar** argv) +{ + if (argc > 1 && argv[1][0] != '-' && (!fWindows || argv[1][0] != '/') && + wxString(argv[1]) != "start") + { + fCommandLine = true; + } + else if (!fGUI) + { + fDaemon = true; + } + else + { + // wxApp::Initialize will remove environment-specific parameters, + // so it's too early to call ParseParameters yet + for (int i = 1; i < argc; i++) + { + wxString str = argv[i]; + #ifdef __WXMSW__ + if (str.size() >= 1 && str[0] == '/') + str[0] = '-'; + char pszLower[MAX_PATH]; + strlcpy(pszLower, str.c_str(), sizeof(pszLower)); + strlwr(pszLower); + str = pszLower; + #endif + // haven't decided which argument to use for this yet + if (str == "-daemon" || str == "-d" || str == "start") + fDaemon = true; + } + } + +#ifdef __WXGTK__ + if (fDaemon || fCommandLine) + { + // Call the original Initialize while suppressing error messages + // and ignoring failure. If unable to initialize GTK, it fails + // near the end so hopefully the last few things don't matter. + { + wxLogNull logNo; + wxApp::Initialize(argc, argv); + } + + if (fDaemon) + { + // Daemonize + pid_t pid = fork(); + if (pid < 0) + { + fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno); + return false; + } + if (pid > 0) + pthread_exit((void*)0); + } + + return true; + } +#endif + + return wxApp::Initialize(argc, argv); +} + +bool CMyApp::OnInit() +{ + bool fRet = false; + try + { + fRet = OnInit2(); + } + catch (std::exception& e) { + PrintException(&e, "OnInit()"); + } catch (...) { + PrintException(NULL, "OnInit()"); + } + if (!fRet) + Shutdown(NULL); + return fRet; +} + +extern int g_isPainting; + +bool CMyApp::OnInit2() +{ +#ifdef _MSC_VER + // Turn off microsoft heap dump noise + _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); + _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); +#endif +#if _MSC_VER >= 1400 + // Disable confusing "helpful" text message on abort, ctrl-c + _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); +#endif +#if defined(__WXMSW__) && defined(__WXDEBUG__) && wxUSE_GUI + // Disable malfunctioning wxWidgets debug assertion + g_isPainting = 10000; +#endif +#if wxUSE_GUI + wxImage::AddHandler(new wxPNGHandler); +#endif +#if defined(__WXMSW__ ) || defined(__WXMAC__) + SetAppName("Bitcoin"); +#else + SetAppName("bitcoin"); +#endif +#ifndef __WXMSW__ + umask(077); +#endif +#ifdef __WXMSW__ +#if wxUSE_UNICODE + // Hack to set wxConvLibc codepage to UTF-8 on Windows, + // may break if wxMBConv_win32 implementation in strconv.cpp changes. + class wxMBConv_win32 : public wxMBConv + { + public: + long m_CodePage; + size_t m_minMBCharWidth; + }; + if (((wxMBConv_win32*)&wxConvLibc)->m_CodePage == CP_ACP) + ((wxMBConv_win32*)&wxConvLibc)->m_CodePage = CP_UTF8; +#endif +#endif + + // Load locale/<lang>/LC_MESSAGES/bitcoin.mo language file + m_locale.Init(wxLANGUAGE_DEFAULT, 0); + m_locale.AddCatalogLookupPathPrefix("locale"); + if (!fWindows) + { + m_locale.AddCatalogLookupPathPrefix("/usr/share/locale"); + m_locale.AddCatalogLookupPathPrefix("/usr/local/share/locale"); + } + m_locale.AddCatalog("wxstd"); // wxWidgets standard translations, if any + m_locale.AddCatalog("bitcoin"); + + // + // Parameters + // + if (fCommandLine) + { + int ret = CommandLineRPC(argc, argv); + exit(ret); + } + + ParseParameters(argc, argv); + if (mapArgs.count("-?") || mapArgs.count("--help")) + { + wxString strUsage = string() + + _("Usage:") + "\t\t\t\t\t\t\t\t\t\t\n" + + " bitcoin [options] \t" + "\n" + + " bitcoin [command] \t" + _("Send command to bitcoin running with -server or -daemon\n") + + " bitcoin [command] -? \t" + _("Get help for a command\n") + + " bitcoin help \t" + _("List commands\n") + + _("Options:\n") + + " -gen \t " + _("Generate coins\n") + + " -gen=0 \t " + _("Don't generate coins\n") + + " -min \t " + _("Start minimized\n") + + " -datadir=<dir> \t " + _("Specify data directory\n") + + " -proxy=<ip:port>\t " + _("Connect through socks4 proxy\n") + + " -addnode=<ip> \t " + _("Add a node to connect to\n") + + " -connect=<ip> \t " + _("Connect only to the specified node\n") + + " -server \t " + _("Accept command line and JSON-RPC commands\n") + + " -daemon \t " + _("Run in the background as a daemon and accept commands\n") + + " -? \t " + _("This help message\n"); + +#if defined(__WXMSW__) && wxUSE_GUI + // Tabs make the columns line up in the message box + wxMessageBox(strUsage, "Bitcoin", wxOK); +#else + // Remove tabs + strUsage.Replace("\t", ""); + fprintf(stderr, "%s", ((string)strUsage).c_str()); +#endif + return false; + } + + if (mapArgs.count("-datadir")) + strlcpy(pszSetDataDir, mapArgs["-datadir"].c_str(), sizeof(pszSetDataDir)); + + if (mapArgs.count("-debug")) + fDebug = true; + + if (mapArgs.count("-printtodebugger")) + fPrintToDebugger = true; + + if (!fDebug && !pszSetDataDir[0]) + ShrinkDebugFile(); + printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); + printf("Bitcoin version %d.%d.%d%s beta, OS version %s\n", VERSION/10000, (VERSION/100)%100, VERSION%100, pszSubVer, ((string)wxGetOsDescription()).c_str()); + printf("System default language is %d %s\n", m_locale.GetSystemLanguage(), ((string)m_locale.GetSysName()).c_str()); + printf("Language file %s (%s)\n", (string("locale/") + (string)m_locale.GetCanonicalName() + "/LC_MESSAGES/bitcoin.mo").c_str(), ((string)m_locale.GetLocale()).c_str()); + printf("Default data directory %s\n", GetDefaultDataDir().c_str()); + + if (mapArgs.count("-loadblockindextest")) + { + CTxDB txdb("r"); + txdb.LoadBlockIndex(); + PrintBlockTree(); + return false; + } + + // + // Limit to single instance per user + // Required to protect the database files if we're going to keep deleting log.* + // +#ifdef __WXMSW__ + // todo: wxSingleInstanceChecker wasn't working on Linux, never deleted its lock file + // maybe should go by whether successfully bind port 8333 instead + wxString strMutexName = wxString("bitcoin_running.") + getenv("HOMEPATH"); + for (int i = 0; i < strMutexName.size(); i++) + if (!isalnum(strMutexName[i])) + strMutexName[i] = '.'; + wxSingleInstanceChecker* psingleinstancechecker = new wxSingleInstanceChecker(strMutexName); + if (psingleinstancechecker->IsAnotherRunning()) + { + printf("Existing instance found\n"); + unsigned int nStart = GetTime(); + loop + { + // TODO: find out how to do this in Linux, or replace with wxWidgets commands + // Show the previous instance and exit + HWND hwndPrev = FindWindowA("wxWindowClassNR", "Bitcoin"); + if (hwndPrev) + { + if (IsIconic(hwndPrev)) + ShowWindow(hwndPrev, SW_RESTORE); + SetForegroundWindow(hwndPrev); + return false; + } + + if (GetTime() > nStart + 60) + return false; + + // Resume this instance if the other exits + delete psingleinstancechecker; + Sleep(1000); + psingleinstancechecker = new wxSingleInstanceChecker(strMutexName); + if (!psingleinstancechecker->IsAnotherRunning()) + break; + } + } +#endif + + // Bind to the port early so we can tell if another instance is already running. + // This is a backup to wxSingleInstanceChecker, which doesn't work on Linux. + string strErrors; + if (!BindListenPort(strErrors)) + { + wxMessageBox(strErrors, "Bitcoin"); + return false; + } + + // + // Load data files + // + if (fDaemon) + fprintf(stdout, "bitcoin server starting\n"); + strErrors = ""; + int64 nStart; + + printf("Loading addresses...\n"); + nStart = GetTimeMillis(); + if (!LoadAddresses()) + strErrors += _("Error loading addr.dat \n"); + printf(" addresses %15"PRI64d"ms\n", GetTimeMillis() - nStart); + + printf("Loading block index...\n"); + nStart = GetTimeMillis(); + if (!LoadBlockIndex()) + strErrors += _("Error loading blkindex.dat \n"); + printf(" block index %15"PRI64d"ms\n", GetTimeMillis() - nStart); + + printf("Loading wallet...\n"); + nStart = GetTimeMillis(); + bool fFirstRun; + if (!LoadWallet(fFirstRun)) + strErrors += _("Error loading wallet.dat \n"); + printf(" wallet %15"PRI64d"ms\n", GetTimeMillis() - nStart); + + printf("Done loading\n"); + + //// debug print + printf("mapBlockIndex.size() = %d\n", mapBlockIndex.size()); + printf("nBestHeight = %d\n", nBestHeight); + printf("mapKeys.size() = %d\n", mapKeys.size()); + printf("mapPubKeys.size() = %d\n", mapPubKeys.size()); + printf("mapWallet.size() = %d\n", mapWallet.size()); + printf("mapAddressBook.size() = %d\n", mapAddressBook.size()); + + if (!strErrors.empty()) + { + wxMessageBox(strErrors, "Bitcoin"); + return false; + } + + // Add wallet transactions that aren't already in a block to mapTransactions + ReacceptWalletTransactions(); + + // + // Parameters + // + if (mapArgs.count("-printblockindex") || mapArgs.count("-printblocktree")) + { + PrintBlockTree(); + return false; + } + + if (mapArgs.count("-printblock")) + { + string strMatch = mapArgs["-printblock"]; + int nFound = 0; + for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi) + { + uint256 hash = (*mi).first; + if (strncmp(hash.ToString().c_str(), strMatch.c_str(), strMatch.size()) == 0) + { + CBlockIndex* pindex = (*mi).second; + CBlock block; + block.ReadFromDisk(pindex); + block.BuildMerkleTree(); + block.print(); + printf("\n"); + nFound++; + } + } + if (nFound == 0) + printf("No blocks matching %s were found\n", strMatch.c_str()); + return false; + } + + if (mapArgs.count("-gen")) + { + if (mapArgs["-gen"].empty()) + fGenerateBitcoins = true; + else + fGenerateBitcoins = (atoi(mapArgs["-gen"].c_str()) != 0); + } + + if (mapArgs.count("-proxy")) + { + fUseProxy = true; + addrProxy = CAddress(mapArgs["-proxy"]); + if (!addrProxy.IsValid()) + { + wxMessageBox(_("Invalid -proxy address"), "Bitcoin"); + return false; + } + } + + if (mapArgs.count("-addnode")) + { + foreach(string strAddr, mapMultiArgs["-addnode"]) + { + CAddress addr(strAddr, NODE_NETWORK); + addr.nTime = 0; // so it won't relay unless successfully connected + if (addr.IsValid()) + AddAddress(addr); + } + } + + // + // Create the main window and start the node + // + if (!fDaemon) + CreateMainWindow(); + + if (!CheckDiskSpace()) + return false; + + RandAddSeedPerfmon(); + + if (!CreateThread(StartNode, NULL)) + wxMessageBox("Error: CreateThread(StartNode) failed", "Bitcoin"); + + if (mapArgs.count("-server") || fDaemon) + CreateThread(ThreadRPCServer, NULL); + + if (fFirstRun) + SetStartOnSystemStartup(true); + + return true; +} + +int CMyApp::OnExit() +{ + Shutdown(NULL); + return wxApp::OnExit(); +} + +bool CMyApp::OnExceptionInMainLoop() +{ + try + { + throw; + } + catch (std::exception& e) + { + PrintException(&e, "CMyApp::OnExceptionInMainLoop()"); + wxLogWarning("Exception %s %s", typeid(e).name(), e.what()); + Sleep(1000); + throw; + } + catch (...) + { + PrintException(NULL, "CMyApp::OnExceptionInMainLoop()"); + wxLogWarning("Unknown exception"); + Sleep(1000); + throw; + } + return true; +} + +void CMyApp::OnUnhandledException() +{ + // this shows how we may let some exception propagate uncaught + try + { + throw; + } + catch (std::exception& e) + { + PrintException(&e, "CMyApp::OnUnhandledException()"); + wxLogWarning("Exception %s %s", typeid(e).name(), e.what()); + Sleep(1000); + throw; + } + catch (...) + { + PrintException(NULL, "CMyApp::OnUnhandledException()"); + wxLogWarning("Unknown exception"); + Sleep(1000); + throw; + } +} + +void CMyApp::OnFatalException() +{ + wxMessageBox(_("Program has crashed and will terminate. "), "Bitcoin", wxOK | wxICON_ERROR); +} @@ -1,7 +1,7 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
-
-void Shutdown(void* parg);
-bool GetStartOnSystemStartup();
-void SetStartOnSystemStartup(bool fAutoStart);
+// Copyright (c) 2009-2010 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +void Shutdown(void* parg); +bool GetStartOnSystemStartup(); +void SetStartOnSystemStartup(bool fAutoStart); @@ -1,324 +1,324 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
-
-#include "headers.h"
-
-int nGotIRCAddresses = 0;
-
-
-
-#pragma pack(push, 1)
-struct ircaddr
-{
- int ip;
- short port;
-};
-#pragma pack(pop)
-
-string EncodeAddress(const CAddress& addr)
-{
- struct ircaddr tmp;
- tmp.ip = addr.ip;
- tmp.port = addr.port;
-
- vector<unsigned char> vch(UBEGIN(tmp), UEND(tmp));
- return string("u") + EncodeBase58Check(vch);
-}
-
-bool DecodeAddress(string str, CAddress& addr)
-{
- vector<unsigned char> vch;
- if (!DecodeBase58Check(str.substr(1), vch))
- return false;
-
- struct ircaddr tmp;
- if (vch.size() != sizeof(tmp))
- return false;
- memcpy(&tmp, &vch[0], sizeof(tmp));
-
- addr = CAddress(tmp.ip, tmp.port, NODE_NETWORK);
- return true;
-}
-
-
-
-
-
-
-static bool Send(SOCKET hSocket, const char* pszSend)
-{
- if (strstr(pszSend, "PONG") != pszSend)
- printf("IRC SENDING: %s\n", pszSend);
- const char* psz = pszSend;
- const char* pszEnd = psz + strlen(psz);
- while (psz < pszEnd)
- {
- int ret = send(hSocket, psz, pszEnd - psz, MSG_NOSIGNAL);
- if (ret < 0)
- return false;
- psz += ret;
- }
- return true;
-}
-
-bool RecvLine(SOCKET hSocket, string& strLine)
-{
- strLine = "";
- loop
- {
- char c;
- int nBytes = recv(hSocket, &c, 1, 0);
- if (nBytes > 0)
- {
- if (c == '\n')
- continue;
- if (c == '\r')
- return true;
- strLine += c;
- if (strLine.size() >= 9000)
- return true;
- }
- else if (nBytes <= 0)
- {
- if (!strLine.empty())
- return true;
- // socket closed
- printf("IRC socket closed\n");
- return false;
- }
- else
- {
- // socket error
- int nErr = WSAGetLastError();
- if (nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
- {
- printf("IRC recv failed: %d\n", nErr);
- return false;
- }
- }
- }
-}
-
-bool RecvLineIRC(SOCKET hSocket, string& strLine)
-{
- loop
- {
- bool fRet = RecvLine(hSocket, strLine);
- if (fRet)
- {
- if (fShutdown)
- return false;
- vector<string> vWords;
- ParseString(strLine, ' ', vWords);
- if (vWords.size() >= 1 && vWords[0] == "PING")
- {
- strLine[1] = 'O';
- strLine += '\r';
- Send(hSocket, strLine.c_str());
- continue;
- }
- }
- return fRet;
- }
-}
-
-int RecvUntil(SOCKET hSocket, const char* psz1, const char* psz2=NULL, const char* psz3=NULL)
-{
- loop
- {
- string strLine;
- if (!RecvLineIRC(hSocket, strLine))
- return 0;
- printf("IRC %s\n", strLine.c_str());
- if (psz1 && strLine.find(psz1) != -1)
- return 1;
- if (psz2 && strLine.find(psz2) != -1)
- return 2;
- if (psz3 && strLine.find(psz3) != -1)
- return 3;
- }
-}
-
-bool Wait(int nSeconds)
-{
- if (fShutdown)
- return false;
- printf("IRC waiting %d seconds to reconnect\n", nSeconds);
- for (int i = 0; i < nSeconds; i++)
- {
- if (fShutdown)
- return false;
- Sleep(1000);
- }
- return true;
-}
-
-
-
-void ThreadIRCSeed(void* parg)
-{
- printf("ThreadIRCSeed started\n");
- int nErrorWait = 10;
- int nRetryWait = 10;
- bool fNameInUse = false;
- bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
-
- while (!fShutdown)
- {
- //CAddress addrConnect("216.155.130.130:6667"); // chat.freenode.net
- CAddress addrConnect("92.243.23.21:6667"); // irc.lfnet.org
- if (!fTOR)
- {
- //struct hostent* phostent = gethostbyname("chat.freenode.net");
- struct hostent* phostent = gethostbyname("irc.lfnet.org");
- if (phostent && phostent->h_addr_list && phostent->h_addr_list[0])
- addrConnect = CAddress(*(u_long*)phostent->h_addr_list[0], htons(6667));
- }
-
- SOCKET hSocket;
- if (!ConnectSocket(addrConnect, hSocket))
- {
- printf("IRC connect failed\n");
- nErrorWait = nErrorWait * 11 / 10;
- if (Wait(nErrorWait += 60))
- continue;
- else
- return;
- }
-
- if (!RecvUntil(hSocket, "Found your hostname", "using your IP address instead", "Couldn't look up your hostname"))
- {
- closesocket(hSocket);
- hSocket = INVALID_SOCKET;
- nErrorWait = nErrorWait * 11 / 10;
- if (Wait(nErrorWait += 60))
- continue;
- else
- return;
- }
-
- string strMyName;
- if (addrLocalHost.IsRoutable() && !fUseProxy && !fNameInUse)
- strMyName = EncodeAddress(addrLocalHost);
- else
- strMyName = strprintf("x%u", GetRand(1000000000));
-
- Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str());
- Send(hSocket, strprintf("USER %s 8 * : %s\r", strMyName.c_str(), strMyName.c_str()).c_str());
-
- int nRet = RecvUntil(hSocket, " 004 ", " 433 ");
- if (nRet != 1)
- {
- closesocket(hSocket);
- hSocket = INVALID_SOCKET;
- if (nRet == 2)
- {
- printf("IRC name already in use\n");
- fNameInUse = true;
- Wait(10);
- continue;
- }
- nErrorWait = nErrorWait * 11 / 10;
- if (Wait(nErrorWait += 60))
- continue;
- else
- return;
- }
- Sleep(500);
-
- Send(hSocket, "JOIN #bitcoin\r");
- Send(hSocket, "WHO #bitcoin\r");
-
- int64 nStart = GetTime();
- string strLine;
- while (!fShutdown && RecvLineIRC(hSocket, strLine))
- {
- if (strLine.empty() || strLine.size() > 900 || strLine[0] != ':')
- continue;
-
- vector<string> vWords;
- ParseString(strLine, ' ', vWords);
- if (vWords.size() < 2)
- continue;
-
- char pszName[10000];
- pszName[0] = '\0';
-
- if (vWords[1] == "352" && vWords.size() >= 8)
- {
- // index 7 is limited to 16 characters
- // could get full length name at index 10, but would be different from join messages
- strlcpy(pszName, vWords[7].c_str(), sizeof(pszName));
- printf("IRC got who\n");
- }
-
- if (vWords[1] == "JOIN" && vWords[0].size() > 1)
- {
- // :username!username@50000007.F000000B.90000002.IP JOIN :#channelname
- strlcpy(pszName, vWords[0].c_str() + 1, sizeof(pszName));
- if (strchr(pszName, '!'))
- *strchr(pszName, '!') = '\0';
- printf("IRC got join\n");
- }
-
- if (pszName[0] == 'u')
- {
- CAddress addr;
- if (DecodeAddress(pszName, addr))
- {
- addr.nTime = GetAdjustedTime() - 51 * 60;
- if (AddAddress(addr))
- printf("IRC got new address\n");
- nGotIRCAddresses++;
- }
- else
- {
- printf("IRC decode failed\n");
- }
- }
- }
- closesocket(hSocket);
- hSocket = INVALID_SOCKET;
-
- // IRC usually blocks TOR, so only try once
- if (fTOR)
- return;
-
- if (GetTime() - nStart > 20 * 60)
- {
- nErrorWait /= 3;
- nRetryWait /= 3;
- }
-
- nRetryWait = nRetryWait * 11 / 10;
- if (!Wait(nRetryWait += 60))
- return;
- }
-}
-
-
-
-
-
-
-
-
-
-
-#ifdef TEST
-int main(int argc, char *argv[])
-{
- WSADATA wsadata;
- if (WSAStartup(MAKEWORD(2,2), &wsadata) != NO_ERROR)
- {
- printf("Error at WSAStartup()\n");
- return false;
- }
-
- ThreadIRCSeed(NULL);
-
- WSACleanup();
- return 0;
-}
-#endif
+// Copyright (c) 2009-2010 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +#include "headers.h" + +int nGotIRCAddresses = 0; + + + +#pragma pack(push, 1) +struct ircaddr +{ + int ip; + short port; +}; +#pragma pack(pop) + +string EncodeAddress(const CAddress& addr) +{ + struct ircaddr tmp; + tmp.ip = addr.ip; + tmp.port = addr.port; + + vector<unsigned char> vch(UBEGIN(tmp), UEND(tmp)); + return string("u") + EncodeBase58Check(vch); +} + +bool DecodeAddress(string str, CAddress& addr) +{ + vector<unsigned char> vch; + if (!DecodeBase58Check(str.substr(1), vch)) + return false; + + struct ircaddr tmp; + if (vch.size() != sizeof(tmp)) + return false; + memcpy(&tmp, &vch[0], sizeof(tmp)); + + addr = CAddress(tmp.ip, tmp.port, NODE_NETWORK); + return true; +} + + + + + + +static bool Send(SOCKET hSocket, const char* pszSend) +{ + if (strstr(pszSend, "PONG") != pszSend) + printf("IRC SENDING: %s\n", pszSend); + const char* psz = pszSend; + const char* pszEnd = psz + strlen(psz); + while (psz < pszEnd) + { + int ret = send(hSocket, psz, pszEnd - psz, MSG_NOSIGNAL); + if (ret < 0) + return false; + psz += ret; + } + return true; +} + +bool RecvLine(SOCKET hSocket, string& strLine) +{ + strLine = ""; + loop + { + char c; + int nBytes = recv(hSocket, &c, 1, 0); + if (nBytes > 0) + { + if (c == '\n') + continue; + if (c == '\r') + return true; + strLine += c; + if (strLine.size() >= 9000) + return true; + } + else if (nBytes <= 0) + { + if (!strLine.empty()) + return true; + // socket closed + printf("IRC socket closed\n"); + return false; + } + else + { + // socket error + int nErr = WSAGetLastError(); + if (nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS) + { + printf("IRC recv failed: %d\n", nErr); + return false; + } + } + } +} + +bool RecvLineIRC(SOCKET hSocket, string& strLine) +{ + loop + { + bool fRet = RecvLine(hSocket, strLine); + if (fRet) + { + if (fShutdown) + return false; + vector<string> vWords; + ParseString(strLine, ' ', vWords); + if (vWords.size() >= 1 && vWords[0] == "PING") + { + strLine[1] = 'O'; + strLine += '\r'; + Send(hSocket, strLine.c_str()); + continue; + } + } + return fRet; + } +} + +int RecvUntil(SOCKET hSocket, const char* psz1, const char* psz2=NULL, const char* psz3=NULL) +{ + loop + { + string strLine; + if (!RecvLineIRC(hSocket, strLine)) + return 0; + printf("IRC %s\n", strLine.c_str()); + if (psz1 && strLine.find(psz1) != -1) + return 1; + if (psz2 && strLine.find(psz2) != -1) + return 2; + if (psz3 && strLine.find(psz3) != -1) + return 3; + } +} + +bool Wait(int nSeconds) +{ + if (fShutdown) + return false; + printf("IRC waiting %d seconds to reconnect\n", nSeconds); + for (int i = 0; i < nSeconds; i++) + { + if (fShutdown) + return false; + Sleep(1000); + } + return true; +} + + + +void ThreadIRCSeed(void* parg) +{ + printf("ThreadIRCSeed started\n"); + int nErrorWait = 10; + int nRetryWait = 10; + bool fNameInUse = false; + bool fTOR = (fUseProxy && addrProxy.port == htons(9050)); + + while (!fShutdown) + { + //CAddress addrConnect("216.155.130.130:6667"); // chat.freenode.net + CAddress addrConnect("92.243.23.21:6667"); // irc.lfnet.org + if (!fTOR) + { + //struct hostent* phostent = gethostbyname("chat.freenode.net"); + struct hostent* phostent = gethostbyname("irc.lfnet.org"); + if (phostent && phostent->h_addr_list && phostent->h_addr_list[0]) + addrConnect = CAddress(*(u_long*)phostent->h_addr_list[0], htons(6667)); + } + + SOCKET hSocket; + if (!ConnectSocket(addrConnect, hSocket)) + { + printf("IRC connect failed\n"); + nErrorWait = nErrorWait * 11 / 10; + if (Wait(nErrorWait += 60)) + continue; + else + return; + } + + if (!RecvUntil(hSocket, "Found your hostname", "using your IP address instead", "Couldn't look up your hostname")) + { + closesocket(hSocket); + hSocket = INVALID_SOCKET; + nErrorWait = nErrorWait * 11 / 10; + if (Wait(nErrorWait += 60)) + continue; + else + return; + } + + string strMyName; + if (addrLocalHost.IsRoutable() && !fUseProxy && !fNameInUse) + strMyName = EncodeAddress(addrLocalHost); + else + strMyName = strprintf("x%u", GetRand(1000000000)); + + Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str()); + Send(hSocket, strprintf("USER %s 8 * : %s\r", strMyName.c_str(), strMyName.c_str()).c_str()); + + int nRet = RecvUntil(hSocket, " 004 ", " 433 "); + if (nRet != 1) + { + closesocket(hSocket); + hSocket = INVALID_SOCKET; + if (nRet == 2) + { + printf("IRC name already in use\n"); + fNameInUse = true; + Wait(10); + continue; + } + nErrorWait = nErrorWait * 11 / 10; + if (Wait(nErrorWait += 60)) + continue; + else + return; + } + Sleep(500); + + Send(hSocket, "JOIN #bitcoin\r"); + Send(hSocket, "WHO #bitcoin\r"); + + int64 nStart = GetTime(); + string strLine; + while (!fShutdown && RecvLineIRC(hSocket, strLine)) + { + if (strLine.empty() || strLine.size() > 900 || strLine[0] != ':') + continue; + + vector<string> vWords; + ParseString(strLine, ' ', vWords); + if (vWords.size() < 2) + continue; + + char pszName[10000]; + pszName[0] = '\0'; + + if (vWords[1] == "352" && vWords.size() >= 8) + { + // index 7 is limited to 16 characters + // could get full length name at index 10, but would be different from join messages + strlcpy(pszName, vWords[7].c_str(), sizeof(pszName)); + printf("IRC got who\n"); + } + + if (vWords[1] == "JOIN" && vWords[0].size() > 1) + { + // :username!username@50000007.F000000B.90000002.IP JOIN :#channelname + strlcpy(pszName, vWords[0].c_str() + 1, sizeof(pszName)); + if (strchr(pszName, '!')) + *strchr(pszName, '!') = '\0'; + printf("IRC got join\n"); + } + + if (pszName[0] == 'u') + { + CAddress addr; + if (DecodeAddress(pszName, addr)) + { + addr.nTime = GetAdjustedTime() - 51 * 60; + if (AddAddress(addr)) + printf("IRC got new address\n"); + nGotIRCAddresses++; + } + else + { + printf("IRC decode failed\n"); + } + } + } + closesocket(hSocket); + hSocket = INVALID_SOCKET; + + // IRC usually blocks TOR, so only try once + if (fTOR) + return; + + if (GetTime() - nStart > 20 * 60) + { + nErrorWait /= 3; + nRetryWait /= 3; + } + + nRetryWait = nRetryWait * 11 / 10; + if (!Wait(nRetryWait += 60)) + return; + } +} + + + + + + + + + + +#ifdef TEST +int main(int argc, char *argv[]) +{ + WSADATA wsadata; + if (WSAStartup(MAKEWORD(2,2), &wsadata) != NO_ERROR) + { + printf("Error at WSAStartup()\n"); + return false; + } + + ThreadIRCSeed(NULL); + + WSACleanup(); + return 0; +} +#endif @@ -1,8 +1,8 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
-
-bool RecvLine(SOCKET hSocket, string& strLine);
-void ThreadIRCSeed(void* parg);
-
-extern int nGotIRCAddresses;
+// Copyright (c) 2009-2010 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +bool RecvLine(SOCKET hSocket, string& strLine); +void ThreadIRCSeed(void* parg); + +extern int nGotIRCAddresses; diff --git a/json/LICENSE.txt b/json/LICENSE.txt index fa193fe7b7..797d5363b3 100644 --- a/json/LICENSE.txt +++ b/json/LICENSE.txt @@ -1,24 +1,24 @@ -The MIT License
-
-Copyright (c) 2007 - 2009 John W. Wilkinson
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
+The MIT License + +Copyright (c) 2007 - 2009 John W. Wilkinson + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/json/json_spirit.h b/json/json_spirit.h index 7dac05c360..ac1879d5b3 100644 --- a/json/json_spirit.h +++ b/json/json_spirit.h @@ -1,18 +1,18 @@ -#ifndef JSON_SPIRIT
-#define JSON_SPIRIT
-
-// Copyright John W. Wilkinson 2007 - 2009.
-// Distributed under the MIT License, see accompanying file LICENSE.txt
-
-// json spirit version 4.03
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1020)
-# pragma once
-#endif
-
-#include "json_spirit_value.h"
-#include "json_spirit_reader.h"
-#include "json_spirit_writer.h"
-#include "json_spirit_utils.h"
-
-#endif
+#ifndef JSON_SPIRIT +#define JSON_SPIRIT + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include "json_spirit_value.h" +#include "json_spirit_reader.h" +#include "json_spirit_writer.h" +#include "json_spirit_utils.h" + +#endif diff --git a/json/json_spirit_error_position.h b/json/json_spirit_error_position.h index 4a535ff517..17208507df 100644 --- a/json/json_spirit_error_position.h +++ b/json/json_spirit_error_position.h @@ -1,54 +1,54 @@ -#ifndef JSON_SPIRIT_ERROR_POSITION
-#define JSON_SPIRIT_ERROR_POSITION
-
-// Copyright John W. Wilkinson 2007 - 2009.
-// Distributed under the MIT License, see accompanying file LICENSE.txt
-
-// json spirit version 4.03
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1020)
-# pragma once
-#endif
-
-#include <string>
-
-namespace json_spirit
-{
- // An Error_position exception is thrown by the "read_or_throw" functions below on finding an error.
- // Note the "read_or_throw" functions are around 3 times slower than the standard functions "read"
- // functions that return a bool.
- //
- struct Error_position
- {
- Error_position();
- Error_position( unsigned int line, unsigned int column, const std::string& reason );
- bool operator==( const Error_position& lhs ) const;
- unsigned int line_;
- unsigned int column_;
- std::string reason_;
- };
-
- inline Error_position::Error_position()
- : line_( 0 )
- , column_( 0 )
- {
- }
-
- inline Error_position::Error_position( unsigned int line, unsigned int column, const std::string& reason )
- : line_( line )
- , column_( column )
- , reason_( reason )
- {
- }
-
- inline bool Error_position::operator==( const Error_position& lhs ) const
- {
- if( this == &lhs ) return true;
-
- return ( reason_ == lhs.reason_ ) &&
- ( line_ == lhs.line_ ) &&
- ( column_ == lhs.column_ );
-}
-}
-
-#endif
+#ifndef JSON_SPIRIT_ERROR_POSITION +#define JSON_SPIRIT_ERROR_POSITION + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include <string> + +namespace json_spirit +{ + // An Error_position exception is thrown by the "read_or_throw" functions below on finding an error. + // Note the "read_or_throw" functions are around 3 times slower than the standard functions "read" + // functions that return a bool. + // + struct Error_position + { + Error_position(); + Error_position( unsigned int line, unsigned int column, const std::string& reason ); + bool operator==( const Error_position& lhs ) const; + unsigned int line_; + unsigned int column_; + std::string reason_; + }; + + inline Error_position::Error_position() + : line_( 0 ) + , column_( 0 ) + { + } + + inline Error_position::Error_position( unsigned int line, unsigned int column, const std::string& reason ) + : line_( line ) + , column_( column ) + , reason_( reason ) + { + } + + inline bool Error_position::operator==( const Error_position& lhs ) const + { + if( this == &lhs ) return true; + + return ( reason_ == lhs.reason_ ) && + ( line_ == lhs.line_ ) && + ( column_ == lhs.column_ ); +} +} + +#endif diff --git a/json/json_spirit_reader.cpp b/json/json_spirit_reader.cpp index 8e2fb5e2ab..aa4f637226 100644 --- a/json/json_spirit_reader.cpp +++ b/json/json_spirit_reader.cpp @@ -1,137 +1,137 @@ -// Copyright John W. Wilkinson 2007 - 2009.
-// Distributed under the MIT License, see accompanying file LICENSE.txt
-
-// json spirit version 4.03
-
-#include "json_spirit_reader.h"
-#include "json_spirit_reader_template.h"
-
-using namespace json_spirit;
-
-bool json_spirit::read( const std::string& s, Value& value )
-{
- return read_string( s, value );
-}
-
-void json_spirit::read_or_throw( const std::string& s, Value& value )
-{
- read_string_or_throw( s, value );
-}
-
-bool json_spirit::read( std::istream& is, Value& value )
-{
- return read_stream( is, value );
-}
-
-void json_spirit::read_or_throw( std::istream& is, Value& value )
-{
- read_stream_or_throw( is, value );
-}
-
-bool json_spirit::read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value )
-{
- return read_range( begin, end, value );
-}
-
-void json_spirit::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value )
-{
- begin = read_range_or_throw( begin, end, value );
-}
-
-#ifndef BOOST_NO_STD_WSTRING
-
-bool json_spirit::read( const std::wstring& s, wValue& value )
-{
- return read_string( s, value );
-}
-
-void json_spirit::read_or_throw( const std::wstring& s, wValue& value )
-{
- read_string_or_throw( s, value );
-}
-
-bool json_spirit::read( std::wistream& is, wValue& value )
-{
- return read_stream( is, value );
-}
-
-void json_spirit::read_or_throw( std::wistream& is, wValue& value )
-{
- read_stream_or_throw( is, value );
-}
-
-bool json_spirit::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value )
-{
- return read_range( begin, end, value );
-}
-
-void json_spirit::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value )
-{
- begin = read_range_or_throw( begin, end, value );
-}
-
-#endif
-
-bool json_spirit::read( const std::string& s, mValue& value )
-{
- return read_string( s, value );
-}
-
-void json_spirit::read_or_throw( const std::string& s, mValue& value )
-{
- read_string_or_throw( s, value );
-}
-
-bool json_spirit::read( std::istream& is, mValue& value )
-{
- return read_stream( is, value );
-}
-
-void json_spirit::read_or_throw( std::istream& is, mValue& value )
-{
- read_stream_or_throw( is, value );
-}
-
-bool json_spirit::read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value )
-{
- return read_range( begin, end, value );
-}
-
-void json_spirit::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value )
-{
- begin = read_range_or_throw( begin, end, value );
-}
-
-#ifndef BOOST_NO_STD_WSTRING
-
-bool json_spirit::read( const std::wstring& s, wmValue& value )
-{
- return read_string( s, value );
-}
-
-void json_spirit::read_or_throw( const std::wstring& s, wmValue& value )
-{
- read_string_or_throw( s, value );
-}
-
-bool json_spirit::read( std::wistream& is, wmValue& value )
-{
- return read_stream( is, value );
-}
-
-void json_spirit::read_or_throw( std::wistream& is, wmValue& value )
-{
- read_stream_or_throw( is, value );
-}
-
-bool json_spirit::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value )
-{
- return read_range( begin, end, value );
-}
-
-void json_spirit::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value )
-{
- begin = read_range_or_throw( begin, end, value );
-}
-
-#endif
+// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#include "json_spirit_reader.h" +#include "json_spirit_reader_template.h" + +using namespace json_spirit; + +bool json_spirit::read( const std::string& s, Value& value ) +{ + return read_string( s, value ); +} + +void json_spirit::read_or_throw( const std::string& s, Value& value ) +{ + read_string_or_throw( s, value ); +} + +bool json_spirit::read( std::istream& is, Value& value ) +{ + return read_stream( is, value ); +} + +void json_spirit::read_or_throw( std::istream& is, Value& value ) +{ + read_stream_or_throw( is, value ); +} + +bool json_spirit::read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ) +{ + return read_range( begin, end, value ); +} + +void json_spirit::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ) +{ + begin = read_range_or_throw( begin, end, value ); +} + +#ifndef BOOST_NO_STD_WSTRING + +bool json_spirit::read( const std::wstring& s, wValue& value ) +{ + return read_string( s, value ); +} + +void json_spirit::read_or_throw( const std::wstring& s, wValue& value ) +{ + read_string_or_throw( s, value ); +} + +bool json_spirit::read( std::wistream& is, wValue& value ) +{ + return read_stream( is, value ); +} + +void json_spirit::read_or_throw( std::wistream& is, wValue& value ) +{ + read_stream_or_throw( is, value ); +} + +bool json_spirit::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ) +{ + return read_range( begin, end, value ); +} + +void json_spirit::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ) +{ + begin = read_range_or_throw( begin, end, value ); +} + +#endif + +bool json_spirit::read( const std::string& s, mValue& value ) +{ + return read_string( s, value ); +} + +void json_spirit::read_or_throw( const std::string& s, mValue& value ) +{ + read_string_or_throw( s, value ); +} + +bool json_spirit::read( std::istream& is, mValue& value ) +{ + return read_stream( is, value ); +} + +void json_spirit::read_or_throw( std::istream& is, mValue& value ) +{ + read_stream_or_throw( is, value ); +} + +bool json_spirit::read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ) +{ + return read_range( begin, end, value ); +} + +void json_spirit::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ) +{ + begin = read_range_or_throw( begin, end, value ); +} + +#ifndef BOOST_NO_STD_WSTRING + +bool json_spirit::read( const std::wstring& s, wmValue& value ) +{ + return read_string( s, value ); +} + +void json_spirit::read_or_throw( const std::wstring& s, wmValue& value ) +{ + read_string_or_throw( s, value ); +} + +bool json_spirit::read( std::wistream& is, wmValue& value ) +{ + return read_stream( is, value ); +} + +void json_spirit::read_or_throw( std::wistream& is, wmValue& value ) +{ + read_stream_or_throw( is, value ); +} + +bool json_spirit::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ) +{ + return read_range( begin, end, value ); +} + +void json_spirit::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ) +{ + begin = read_range_or_throw( begin, end, value ); +} + +#endif diff --git a/json/json_spirit_reader.h b/json/json_spirit_reader.h index a58bfc10fe..96494a9789 100644 --- a/json/json_spirit_reader.h +++ b/json/json_spirit_reader.h @@ -1,62 +1,62 @@ -#ifndef JSON_SPIRIT_READER
-#define JSON_SPIRIT_READER
-
-// Copyright John W. Wilkinson 2007 - 2009.
-// Distributed under the MIT License, see accompanying file LICENSE.txt
-
-// json spirit version 4.03
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1020)
-# pragma once
-#endif
-
-#include "json_spirit_value.h"
-#include "json_spirit_error_position.h"
-#include <iostream>
-
-namespace json_spirit
-{
- // functions to reads a JSON values
-
- bool read( const std::string& s, Value& value );
- bool read( std::istream& is, Value& value );
- bool read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value );
-
- void read_or_throw( const std::string& s, Value& value );
- void read_or_throw( std::istream& is, Value& value );
- void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value );
-
-#ifndef BOOST_NO_STD_WSTRING
-
- bool read( const std::wstring& s, wValue& value );
- bool read( std::wistream& is, wValue& value );
- bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value );
-
- void read_or_throw( const std::wstring& s, wValue& value );
- void read_or_throw( std::wistream& is, wValue& value );
- void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value );
-
-#endif
-
- bool read( const std::string& s, mValue& value );
- bool read( std::istream& is, mValue& value );
- bool read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value );
-
- void read_or_throw( const std::string& s, mValue& value );
- void read_or_throw( std::istream& is, mValue& value );
- void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value );
-
-#ifndef BOOST_NO_STD_WSTRING
-
- bool read( const std::wstring& s, wmValue& value );
- bool read( std::wistream& is, wmValue& value );
- bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value );
-
- void read_or_throw( const std::wstring& s, wmValue& value );
- void read_or_throw( std::wistream& is, wmValue& value );
- void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value );
-
-#endif
-}
-
-#endif
+#ifndef JSON_SPIRIT_READER +#define JSON_SPIRIT_READER + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include "json_spirit_value.h" +#include "json_spirit_error_position.h" +#include <iostream> + +namespace json_spirit +{ + // functions to reads a JSON values + + bool read( const std::string& s, Value& value ); + bool read( std::istream& is, Value& value ); + bool read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ); + + void read_or_throw( const std::string& s, Value& value ); + void read_or_throw( std::istream& is, Value& value ); + void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ); + +#ifndef BOOST_NO_STD_WSTRING + + bool read( const std::wstring& s, wValue& value ); + bool read( std::wistream& is, wValue& value ); + bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ); + + void read_or_throw( const std::wstring& s, wValue& value ); + void read_or_throw( std::wistream& is, wValue& value ); + void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ); + +#endif + + bool read( const std::string& s, mValue& value ); + bool read( std::istream& is, mValue& value ); + bool read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ); + + void read_or_throw( const std::string& s, mValue& value ); + void read_or_throw( std::istream& is, mValue& value ); + void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ); + +#ifndef BOOST_NO_STD_WSTRING + + bool read( const std::wstring& s, wmValue& value ); + bool read( std::wistream& is, wmValue& value ); + bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ); + + void read_or_throw( const std::wstring& s, wmValue& value ); + void read_or_throw( std::wistream& is, wmValue& value ); + void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ); + +#endif +} + +#endif diff --git a/json/json_spirit_reader_template.h b/json/json_spirit_reader_template.h index 81cded4346..4dec00e6c9 100644 --- a/json/json_spirit_reader_template.h +++ b/json/json_spirit_reader_template.h @@ -1,612 +1,612 @@ -#ifndef JSON_SPIRIT_READER_TEMPLATE
-#define JSON_SPIRIT_READER_TEMPLATE
-
-// Copyright John W. Wilkinson 2007 - 2009.
-// Distributed under the MIT License, see accompanying file LICENSE.txt
-
-// json spirit version 4.03
-
-#include "json_spirit_value.h"
-#include "json_spirit_error_position.h"
-
-//#define BOOST_SPIRIT_THREADSAFE // uncomment for multithreaded use, requires linking to boost.thread
-
-#include <boost/bind.hpp>
-#include <boost/function.hpp>
-#include <boost/version.hpp>
-
-#if BOOST_VERSION >= 103800
- #include <boost/spirit/include/classic_core.hpp>
- #include <boost/spirit/include/classic_confix.hpp>
- #include <boost/spirit/include/classic_escape_char.hpp>
- #include <boost/spirit/include/classic_multi_pass.hpp>
- #include <boost/spirit/include/classic_position_iterator.hpp>
- #define spirit_namespace boost::spirit::classic
-#else
- #include <boost/spirit/core.hpp>
- #include <boost/spirit/utility/confix.hpp>
- #include <boost/spirit/utility/escape_char.hpp>
- #include <boost/spirit/iterator/multi_pass.hpp>
- #include <boost/spirit/iterator/position_iterator.hpp>
- #define spirit_namespace boost::spirit
-#endif
-
-namespace json_spirit
-{
- const spirit_namespace::int_parser < boost::int64_t > int64_p = spirit_namespace::int_parser < boost::int64_t >();
- const spirit_namespace::uint_parser< boost::uint64_t > uint64_p = spirit_namespace::uint_parser< boost::uint64_t >();
-
- template< class Iter_type >
- bool is_eq( Iter_type first, Iter_type last, const char* c_str )
- {
- for( Iter_type i = first; i != last; ++i, ++c_str )
- {
- if( *c_str == 0 ) return false;
-
- if( *i != *c_str ) return false;
- }
-
- return true;
- }
-
- template< class Char_type >
- Char_type hex_to_num( const Char_type c )
- {
- if( ( c >= '0' ) && ( c <= '9' ) ) return c - '0';
- if( ( c >= 'a' ) && ( c <= 'f' ) ) return c - 'a' + 10;
- if( ( c >= 'A' ) && ( c <= 'F' ) ) return c - 'A' + 10;
- return 0;
- }
-
- template< class Char_type, class Iter_type >
- Char_type hex_str_to_char( Iter_type& begin )
- {
- const Char_type c1( *( ++begin ) );
- const Char_type c2( *( ++begin ) );
-
- return ( hex_to_num( c1 ) << 4 ) + hex_to_num( c2 );
- }
-
- template< class Char_type, class Iter_type >
- Char_type unicode_str_to_char( Iter_type& begin )
- {
- const Char_type c1( *( ++begin ) );
- const Char_type c2( *( ++begin ) );
- const Char_type c3( *( ++begin ) );
- const Char_type c4( *( ++begin ) );
-
- return ( hex_to_num( c1 ) << 12 ) +
- ( hex_to_num( c2 ) << 8 ) +
- ( hex_to_num( c3 ) << 4 ) +
- hex_to_num( c4 );
- }
-
- template< class String_type >
- void append_esc_char_and_incr_iter( String_type& s,
- typename String_type::const_iterator& begin,
- typename String_type::const_iterator end )
- {
- typedef typename String_type::value_type Char_type;
-
- const Char_type c2( *begin );
-
- switch( c2 )
- {
- case 't': s += '\t'; break;
- case 'b': s += '\b'; break;
- case 'f': s += '\f'; break;
- case 'n': s += '\n'; break;
- case 'r': s += '\r'; break;
- case '\\': s += '\\'; break;
- case '/': s += '/'; break;
- case '"': s += '"'; break;
- case 'x':
- {
- if( end - begin >= 3 ) // expecting "xHH..."
- {
- s += hex_str_to_char< Char_type >( begin );
- }
- break;
- }
- case 'u':
- {
- if( end - begin >= 5 ) // expecting "uHHHH..."
- {
- s += unicode_str_to_char< Char_type >( begin );
- }
- break;
- }
- }
- }
-
- template< class String_type >
- String_type substitute_esc_chars( typename String_type::const_iterator begin,
- typename String_type::const_iterator end )
- {
- typedef typename String_type::const_iterator Iter_type;
-
- if( end - begin < 2 ) return String_type( begin, end );
-
- String_type result;
-
- result.reserve( end - begin );
-
- const Iter_type end_minus_1( end - 1 );
-
- Iter_type substr_start = begin;
- Iter_type i = begin;
-
- for( ; i < end_minus_1; ++i )
- {
- if( *i == '\\' )
- {
- result.append( substr_start, i );
-
- ++i; // skip the '\'
-
- append_esc_char_and_incr_iter( result, i, end );
-
- substr_start = i + 1;
- }
- }
-
- result.append( substr_start, end );
-
- return result;
- }
-
- template< class String_type >
- String_type get_str_( typename String_type::const_iterator begin,
- typename String_type::const_iterator end )
- {
- assert( end - begin >= 2 );
-
- typedef typename String_type::const_iterator Iter_type;
-
- Iter_type str_without_quotes( ++begin );
- Iter_type end_without_quotes( --end );
-
- return substitute_esc_chars< String_type >( str_without_quotes, end_without_quotes );
- }
-
- inline std::string get_str( std::string::const_iterator begin, std::string::const_iterator end )
- {
- return get_str_< std::string >( begin, end );
- }
-
- inline std::wstring get_str( std::wstring::const_iterator begin, std::wstring::const_iterator end )
- {
- return get_str_< std::wstring >( begin, end );
- }
-
- template< class String_type, class Iter_type >
- String_type get_str( Iter_type begin, Iter_type end )
- {
- const String_type tmp( begin, end ); // convert multipass iterators to string iterators
-
- return get_str( tmp.begin(), tmp.end() );
- }
-
- // this class's methods get called by the spirit parse resulting
- // in the creation of a JSON object or array
- //
- // NB Iter_type could be a std::string iterator, wstring iterator, a position iterator or a multipass iterator
- //
- template< class Value_type, class Iter_type >
- class Semantic_actions
- {
- public:
-
- typedef typename Value_type::Config_type Config_type;
- typedef typename Config_type::String_type String_type;
- typedef typename Config_type::Object_type Object_type;
- typedef typename Config_type::Array_type Array_type;
- typedef typename String_type::value_type Char_type;
-
- Semantic_actions( Value_type& value )
- : value_( value )
- , current_p_( 0 )
- {
- }
-
- void begin_obj( Char_type c )
- {
- assert( c == '{' );
-
- begin_compound< Object_type >();
- }
-
- void end_obj( Char_type c )
- {
- assert( c == '}' );
-
- end_compound();
- }
-
- void begin_array( Char_type c )
- {
- assert( c == '[' );
-
- begin_compound< Array_type >();
- }
-
- void end_array( Char_type c )
- {
- assert( c == ']' );
-
- end_compound();
- }
-
- void new_name( Iter_type begin, Iter_type end )
- {
- assert( current_p_->type() == obj_type );
-
- name_ = get_str< String_type >( begin, end );
- }
-
- void new_str( Iter_type begin, Iter_type end )
- {
- add_to_current( get_str< String_type >( begin, end ) );
- }
-
- void new_true( Iter_type begin, Iter_type end )
- {
- assert( is_eq( begin, end, "true" ) );
-
- add_to_current( true );
- }
-
- void new_false( Iter_type begin, Iter_type end )
- {
- assert( is_eq( begin, end, "false" ) );
-
- add_to_current( false );
- }
-
- void new_null( Iter_type begin, Iter_type end )
- {
- assert( is_eq( begin, end, "null" ) );
-
- add_to_current( Value_type() );
- }
-
- void new_int( boost::int64_t i )
- {
- add_to_current( i );
- }
-
- void new_uint64( boost::uint64_t ui )
- {
- add_to_current( ui );
- }
-
- void new_real( double d )
- {
- add_to_current( d );
- }
-
- private:
-
- Semantic_actions& operator=( const Semantic_actions& );
- // to prevent "assignment operator could not be generated" warning
-
- Value_type* add_first( const Value_type& value )
- {
- assert( current_p_ == 0 );
-
- value_ = value;
- current_p_ = &value_;
- return current_p_;
- }
-
- template< class Array_or_obj >
- void begin_compound()
- {
- if( current_p_ == 0 )
- {
- add_first( Array_or_obj() );
- }
- else
- {
- stack_.push_back( current_p_ );
-
- Array_or_obj new_array_or_obj; // avoid copy by building new array or object in place
-
- current_p_ = add_to_current( new_array_or_obj );
- }
- }
-
- void end_compound()
- {
- if( current_p_ != &value_ )
- {
- current_p_ = stack_.back();
-
- stack_.pop_back();
- }
- }
-
- Value_type* add_to_current( const Value_type& value )
- {
- if( current_p_ == 0 )
- {
- return add_first( value );
- }
- else if( current_p_->type() == array_type )
- {
- current_p_->get_array().push_back( value );
-
- return ¤t_p_->get_array().back();
- }
-
- assert( current_p_->type() == obj_type );
-
- return &Config_type::add( current_p_->get_obj(), name_, value );
- }
-
- Value_type& value_; // this is the object or array that is being created
- Value_type* current_p_; // the child object or array that is currently being constructed
-
- std::vector< Value_type* > stack_; // previous child objects and arrays
-
- String_type name_; // of current name/value pair
- };
-
- template< typename Iter_type >
- void throw_error( spirit_namespace::position_iterator< Iter_type > i, const std::string& reason )
- {
- throw Error_position( i.get_position().line, i.get_position().column, reason );
- }
-
- template< typename Iter_type >
- void throw_error( Iter_type i, const std::string& reason )
- {
- throw reason;
- }
-
- // the spirit grammer
- //
- template< class Value_type, class Iter_type >
- class Json_grammer : public spirit_namespace::grammar< Json_grammer< Value_type, Iter_type > >
- {
- public:
-
- typedef Semantic_actions< Value_type, Iter_type > Semantic_actions_t;
-
- Json_grammer( Semantic_actions_t& semantic_actions )
- : actions_( semantic_actions )
- {
- }
-
- static void throw_not_value( Iter_type begin, Iter_type end )
- {
- throw_error( begin, "not a value" );
- }
-
- static void throw_not_array( Iter_type begin, Iter_type end )
- {
- throw_error( begin, "not an array" );
- }
-
- static void throw_not_object( Iter_type begin, Iter_type end )
- {
- throw_error( begin, "not an object" );
- }
-
- static void throw_not_pair( Iter_type begin, Iter_type end )
- {
- throw_error( begin, "not a pair" );
- }
-
- static void throw_not_colon( Iter_type begin, Iter_type end )
- {
- throw_error( begin, "no colon in pair" );
- }
-
- static void throw_not_string( Iter_type begin, Iter_type end )
- {
- throw_error( begin, "not a string" );
- }
-
- template< typename ScannerT >
- class definition
- {
- public:
-
- definition( const Json_grammer& self )
- {
- using namespace spirit_namespace;
-
- typedef typename Value_type::String_type::value_type Char_type;
-
- // first we convert the semantic action class methods to functors with the
- // parameter signature expected by spirit
-
- typedef boost::function< void( Char_type ) > Char_action;
- typedef boost::function< void( Iter_type, Iter_type ) > Str_action;
- typedef boost::function< void( double ) > Real_action;
- typedef boost::function< void( boost::int64_t ) > Int_action;
- typedef boost::function< void( boost::uint64_t ) > Uint64_action;
-
- Char_action begin_obj ( boost::bind( &Semantic_actions_t::begin_obj, &self.actions_, _1 ) );
- Char_action end_obj ( boost::bind( &Semantic_actions_t::end_obj, &self.actions_, _1 ) );
- Char_action begin_array( boost::bind( &Semantic_actions_t::begin_array, &self.actions_, _1 ) );
- Char_action end_array ( boost::bind( &Semantic_actions_t::end_array, &self.actions_, _1 ) );
- Str_action new_name ( boost::bind( &Semantic_actions_t::new_name, &self.actions_, _1, _2 ) );
- Str_action new_str ( boost::bind( &Semantic_actions_t::new_str, &self.actions_, _1, _2 ) );
- Str_action new_true ( boost::bind( &Semantic_actions_t::new_true, &self.actions_, _1, _2 ) );
- Str_action new_false ( boost::bind( &Semantic_actions_t::new_false, &self.actions_, _1, _2 ) );
- Str_action new_null ( boost::bind( &Semantic_actions_t::new_null, &self.actions_, _1, _2 ) );
- Real_action new_real ( boost::bind( &Semantic_actions_t::new_real, &self.actions_, _1 ) );
- Int_action new_int ( boost::bind( &Semantic_actions_t::new_int, &self.actions_, _1 ) );
- Uint64_action new_uint64 ( boost::bind( &Semantic_actions_t::new_uint64, &self.actions_, _1 ) );
-
- // actual grammer
-
- json_
- = value_ | eps_p[ &throw_not_value ]
- ;
-
- value_
- = string_[ new_str ]
- | number_
- | object_
- | array_
- | str_p( "true" ) [ new_true ]
- | str_p( "false" )[ new_false ]
- | str_p( "null" ) [ new_null ]
- ;
-
- object_
- = ch_p('{')[ begin_obj ]
- >> !members_
- >> ( ch_p('}')[ end_obj ] | eps_p[ &throw_not_object ] )
- ;
-
- members_
- = pair_ >> *( ',' >> pair_ )
- ;
-
- pair_
- = string_[ new_name ]
- >> ( ':' | eps_p[ &throw_not_colon ] )
- >> ( value_ | eps_p[ &throw_not_value ] )
- ;
-
- array_
- = ch_p('[')[ begin_array ]
- >> !elements_
- >> ( ch_p(']')[ end_array ] | eps_p[ &throw_not_array ] )
- ;
-
- elements_
- = value_ >> *( ',' >> value_ )
- ;
-
- string_
- = lexeme_d // this causes white space inside a string to be retained
- [
- confix_p
- (
- '"',
- *lex_escape_ch_p,
- '"'
- )
- ]
- ;
-
- number_
- = strict_real_p[ new_real ]
- | int64_p [ new_int ]
- | uint64_p [ new_uint64 ]
- ;
- }
-
- spirit_namespace::rule< ScannerT > json_, object_, members_, pair_, array_, elements_, value_, string_, number_;
-
- const spirit_namespace::rule< ScannerT >& start() const { return json_; }
- };
-
- private:
-
- Json_grammer& operator=( const Json_grammer& ); // to prevent "assignment operator could not be generated" warning
-
- Semantic_actions_t& actions_;
- };
-
- template< class Iter_type, class Value_type >
- Iter_type read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value )
- {
- Semantic_actions< Value_type, Iter_type > semantic_actions( value );
-
- const spirit_namespace::parse_info< Iter_type > info =
- spirit_namespace::parse( begin, end,
- Json_grammer< Value_type, Iter_type >( semantic_actions ),
- spirit_namespace::space_p );
-
- if( !info.hit )
- {
- assert( false ); // in theory exception should already have been thrown
- throw_error( info.stop, "error" );
- }
-
- return info.stop;
- }
-
- template< class Iter_type, class Value_type >
- void add_posn_iter_and_read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value )
- {
- typedef spirit_namespace::position_iterator< Iter_type > Posn_iter_t;
-
- const Posn_iter_t posn_begin( begin, end );
- const Posn_iter_t posn_end( end, end );
-
- read_range_or_throw( posn_begin, posn_end, value );
- }
-
- template< class Iter_type, class Value_type >
- bool read_range( Iter_type& begin, Iter_type end, Value_type& value )
- {
- try
- {
- begin = read_range_or_throw( begin, end, value );
-
- return true;
- }
- catch( ... )
- {
- return false;
- }
- }
-
- template< class String_type, class Value_type >
- void read_string_or_throw( const String_type& s, Value_type& value )
- {
- add_posn_iter_and_read_range_or_throw( s.begin(), s.end(), value );
- }
-
- template< class String_type, class Value_type >
- bool read_string( const String_type& s, Value_type& value )
- {
- typename String_type::const_iterator begin = s.begin();
-
- return read_range( begin, s.end(), value );
- }
-
- template< class Istream_type >
- struct Multi_pass_iters
- {
- typedef typename Istream_type::char_type Char_type;
- typedef std::istream_iterator< Char_type, Char_type > istream_iter;
- typedef spirit_namespace::multi_pass< istream_iter > Mp_iter;
-
- Multi_pass_iters( Istream_type& is )
- {
- is.unsetf( std::ios::skipws );
-
- begin_ = spirit_namespace::make_multi_pass( istream_iter( is ) );
- end_ = spirit_namespace::make_multi_pass( istream_iter() );
- }
-
- Mp_iter begin_;
- Mp_iter end_;
- };
-
- template< class Istream_type, class Value_type >
- bool read_stream( Istream_type& is, Value_type& value )
- {
- Multi_pass_iters< Istream_type > mp_iters( is );
-
- return read_range( mp_iters.begin_, mp_iters.end_, value );
- }
-
- template< class Istream_type, class Value_type >
- void read_stream_or_throw( Istream_type& is, Value_type& value )
- {
- const Multi_pass_iters< Istream_type > mp_iters( is );
-
- add_posn_iter_and_read_range_or_throw( mp_iters.begin_, mp_iters.end_, value );
- }
-}
-
-#endif
+#ifndef JSON_SPIRIT_READER_TEMPLATE +#define JSON_SPIRIT_READER_TEMPLATE + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#include "json_spirit_value.h" +#include "json_spirit_error_position.h" + +//#define BOOST_SPIRIT_THREADSAFE // uncomment for multithreaded use, requires linking to boost.thread + +#include <boost/bind.hpp> +#include <boost/function.hpp> +#include <boost/version.hpp> + +#if BOOST_VERSION >= 103800 + #include <boost/spirit/include/classic_core.hpp> + #include <boost/spirit/include/classic_confix.hpp> + #include <boost/spirit/include/classic_escape_char.hpp> + #include <boost/spirit/include/classic_multi_pass.hpp> + #include <boost/spirit/include/classic_position_iterator.hpp> + #define spirit_namespace boost::spirit::classic +#else + #include <boost/spirit/core.hpp> + #include <boost/spirit/utility/confix.hpp> + #include <boost/spirit/utility/escape_char.hpp> + #include <boost/spirit/iterator/multi_pass.hpp> + #include <boost/spirit/iterator/position_iterator.hpp> + #define spirit_namespace boost::spirit +#endif + +namespace json_spirit +{ + const spirit_namespace::int_parser < boost::int64_t > int64_p = spirit_namespace::int_parser < boost::int64_t >(); + const spirit_namespace::uint_parser< boost::uint64_t > uint64_p = spirit_namespace::uint_parser< boost::uint64_t >(); + + template< class Iter_type > + bool is_eq( Iter_type first, Iter_type last, const char* c_str ) + { + for( Iter_type i = first; i != last; ++i, ++c_str ) + { + if( *c_str == 0 ) return false; + + if( *i != *c_str ) return false; + } + + return true; + } + + template< class Char_type > + Char_type hex_to_num( const Char_type c ) + { + if( ( c >= '0' ) && ( c <= '9' ) ) return c - '0'; + if( ( c >= 'a' ) && ( c <= 'f' ) ) return c - 'a' + 10; + if( ( c >= 'A' ) && ( c <= 'F' ) ) return c - 'A' + 10; + return 0; + } + + template< class Char_type, class Iter_type > + Char_type hex_str_to_char( Iter_type& begin ) + { + const Char_type c1( *( ++begin ) ); + const Char_type c2( *( ++begin ) ); + + return ( hex_to_num( c1 ) << 4 ) + hex_to_num( c2 ); + } + + template< class Char_type, class Iter_type > + Char_type unicode_str_to_char( Iter_type& begin ) + { + const Char_type c1( *( ++begin ) ); + const Char_type c2( *( ++begin ) ); + const Char_type c3( *( ++begin ) ); + const Char_type c4( *( ++begin ) ); + + return ( hex_to_num( c1 ) << 12 ) + + ( hex_to_num( c2 ) << 8 ) + + ( hex_to_num( c3 ) << 4 ) + + hex_to_num( c4 ); + } + + template< class String_type > + void append_esc_char_and_incr_iter( String_type& s, + typename String_type::const_iterator& begin, + typename String_type::const_iterator end ) + { + typedef typename String_type::value_type Char_type; + + const Char_type c2( *begin ); + + switch( c2 ) + { + case 't': s += '\t'; break; + case 'b': s += '\b'; break; + case 'f': s += '\f'; break; + case 'n': s += '\n'; break; + case 'r': s += '\r'; break; + case '\\': s += '\\'; break; + case '/': s += '/'; break; + case '"': s += '"'; break; + case 'x': + { + if( end - begin >= 3 ) // expecting "xHH..." + { + s += hex_str_to_char< Char_type >( begin ); + } + break; + } + case 'u': + { + if( end - begin >= 5 ) // expecting "uHHHH..." + { + s += unicode_str_to_char< Char_type >( begin ); + } + break; + } + } + } + + template< class String_type > + String_type substitute_esc_chars( typename String_type::const_iterator begin, + typename String_type::const_iterator end ) + { + typedef typename String_type::const_iterator Iter_type; + + if( end - begin < 2 ) return String_type( begin, end ); + + String_type result; + + result.reserve( end - begin ); + + const Iter_type end_minus_1( end - 1 ); + + Iter_type substr_start = begin; + Iter_type i = begin; + + for( ; i < end_minus_1; ++i ) + { + if( *i == '\\' ) + { + result.append( substr_start, i ); + + ++i; // skip the '\' + + append_esc_char_and_incr_iter( result, i, end ); + + substr_start = i + 1; + } + } + + result.append( substr_start, end ); + + return result; + } + + template< class String_type > + String_type get_str_( typename String_type::const_iterator begin, + typename String_type::const_iterator end ) + { + assert( end - begin >= 2 ); + + typedef typename String_type::const_iterator Iter_type; + + Iter_type str_without_quotes( ++begin ); + Iter_type end_without_quotes( --end ); + + return substitute_esc_chars< String_type >( str_without_quotes, end_without_quotes ); + } + + inline std::string get_str( std::string::const_iterator begin, std::string::const_iterator end ) + { + return get_str_< std::string >( begin, end ); + } + + inline std::wstring get_str( std::wstring::const_iterator begin, std::wstring::const_iterator end ) + { + return get_str_< std::wstring >( begin, end ); + } + + template< class String_type, class Iter_type > + String_type get_str( Iter_type begin, Iter_type end ) + { + const String_type tmp( begin, end ); // convert multipass iterators to string iterators + + return get_str( tmp.begin(), tmp.end() ); + } + + // this class's methods get called by the spirit parse resulting + // in the creation of a JSON object or array + // + // NB Iter_type could be a std::string iterator, wstring iterator, a position iterator or a multipass iterator + // + template< class Value_type, class Iter_type > + class Semantic_actions + { + public: + + typedef typename Value_type::Config_type Config_type; + typedef typename Config_type::String_type String_type; + typedef typename Config_type::Object_type Object_type; + typedef typename Config_type::Array_type Array_type; + typedef typename String_type::value_type Char_type; + + Semantic_actions( Value_type& value ) + : value_( value ) + , current_p_( 0 ) + { + } + + void begin_obj( Char_type c ) + { + assert( c == '{' ); + + begin_compound< Object_type >(); + } + + void end_obj( Char_type c ) + { + assert( c == '}' ); + + end_compound(); + } + + void begin_array( Char_type c ) + { + assert( c == '[' ); + + begin_compound< Array_type >(); + } + + void end_array( Char_type c ) + { + assert( c == ']' ); + + end_compound(); + } + + void new_name( Iter_type begin, Iter_type end ) + { + assert( current_p_->type() == obj_type ); + + name_ = get_str< String_type >( begin, end ); + } + + void new_str( Iter_type begin, Iter_type end ) + { + add_to_current( get_str< String_type >( begin, end ) ); + } + + void new_true( Iter_type begin, Iter_type end ) + { + assert( is_eq( begin, end, "true" ) ); + + add_to_current( true ); + } + + void new_false( Iter_type begin, Iter_type end ) + { + assert( is_eq( begin, end, "false" ) ); + + add_to_current( false ); + } + + void new_null( Iter_type begin, Iter_type end ) + { + assert( is_eq( begin, end, "null" ) ); + + add_to_current( Value_type() ); + } + + void new_int( boost::int64_t i ) + { + add_to_current( i ); + } + + void new_uint64( boost::uint64_t ui ) + { + add_to_current( ui ); + } + + void new_real( double d ) + { + add_to_current( d ); + } + + private: + + Semantic_actions& operator=( const Semantic_actions& ); + // to prevent "assignment operator could not be generated" warning + + Value_type* add_first( const Value_type& value ) + { + assert( current_p_ == 0 ); + + value_ = value; + current_p_ = &value_; + return current_p_; + } + + template< class Array_or_obj > + void begin_compound() + { + if( current_p_ == 0 ) + { + add_first( Array_or_obj() ); + } + else + { + stack_.push_back( current_p_ ); + + Array_or_obj new_array_or_obj; // avoid copy by building new array or object in place + + current_p_ = add_to_current( new_array_or_obj ); + } + } + + void end_compound() + { + if( current_p_ != &value_ ) + { + current_p_ = stack_.back(); + + stack_.pop_back(); + } + } + + Value_type* add_to_current( const Value_type& value ) + { + if( current_p_ == 0 ) + { + return add_first( value ); + } + else if( current_p_->type() == array_type ) + { + current_p_->get_array().push_back( value ); + + return ¤t_p_->get_array().back(); + } + + assert( current_p_->type() == obj_type ); + + return &Config_type::add( current_p_->get_obj(), name_, value ); + } + + Value_type& value_; // this is the object or array that is being created + Value_type* current_p_; // the child object or array that is currently being constructed + + std::vector< Value_type* > stack_; // previous child objects and arrays + + String_type name_; // of current name/value pair + }; + + template< typename Iter_type > + void throw_error( spirit_namespace::position_iterator< Iter_type > i, const std::string& reason ) + { + throw Error_position( i.get_position().line, i.get_position().column, reason ); + } + + template< typename Iter_type > + void throw_error( Iter_type i, const std::string& reason ) + { + throw reason; + } + + // the spirit grammer + // + template< class Value_type, class Iter_type > + class Json_grammer : public spirit_namespace::grammar< Json_grammer< Value_type, Iter_type > > + { + public: + + typedef Semantic_actions< Value_type, Iter_type > Semantic_actions_t; + + Json_grammer( Semantic_actions_t& semantic_actions ) + : actions_( semantic_actions ) + { + } + + static void throw_not_value( Iter_type begin, Iter_type end ) + { + throw_error( begin, "not a value" ); + } + + static void throw_not_array( Iter_type begin, Iter_type end ) + { + throw_error( begin, "not an array" ); + } + + static void throw_not_object( Iter_type begin, Iter_type end ) + { + throw_error( begin, "not an object" ); + } + + static void throw_not_pair( Iter_type begin, Iter_type end ) + { + throw_error( begin, "not a pair" ); + } + + static void throw_not_colon( Iter_type begin, Iter_type end ) + { + throw_error( begin, "no colon in pair" ); + } + + static void throw_not_string( Iter_type begin, Iter_type end ) + { + throw_error( begin, "not a string" ); + } + + template< typename ScannerT > + class definition + { + public: + + definition( const Json_grammer& self ) + { + using namespace spirit_namespace; + + typedef typename Value_type::String_type::value_type Char_type; + + // first we convert the semantic action class methods to functors with the + // parameter signature expected by spirit + + typedef boost::function< void( Char_type ) > Char_action; + typedef boost::function< void( Iter_type, Iter_type ) > Str_action; + typedef boost::function< void( double ) > Real_action; + typedef boost::function< void( boost::int64_t ) > Int_action; + typedef boost::function< void( boost::uint64_t ) > Uint64_action; + + Char_action begin_obj ( boost::bind( &Semantic_actions_t::begin_obj, &self.actions_, _1 ) ); + Char_action end_obj ( boost::bind( &Semantic_actions_t::end_obj, &self.actions_, _1 ) ); + Char_action begin_array( boost::bind( &Semantic_actions_t::begin_array, &self.actions_, _1 ) ); + Char_action end_array ( boost::bind( &Semantic_actions_t::end_array, &self.actions_, _1 ) ); + Str_action new_name ( boost::bind( &Semantic_actions_t::new_name, &self.actions_, _1, _2 ) ); + Str_action new_str ( boost::bind( &Semantic_actions_t::new_str, &self.actions_, _1, _2 ) ); + Str_action new_true ( boost::bind( &Semantic_actions_t::new_true, &self.actions_, _1, _2 ) ); + Str_action new_false ( boost::bind( &Semantic_actions_t::new_false, &self.actions_, _1, _2 ) ); + Str_action new_null ( boost::bind( &Semantic_actions_t::new_null, &self.actions_, _1, _2 ) ); + Real_action new_real ( boost::bind( &Semantic_actions_t::new_real, &self.actions_, _1 ) ); + Int_action new_int ( boost::bind( &Semantic_actions_t::new_int, &self.actions_, _1 ) ); + Uint64_action new_uint64 ( boost::bind( &Semantic_actions_t::new_uint64, &self.actions_, _1 ) ); + + // actual grammer + + json_ + = value_ | eps_p[ &throw_not_value ] + ; + + value_ + = string_[ new_str ] + | number_ + | object_ + | array_ + | str_p( "true" ) [ new_true ] + | str_p( "false" )[ new_false ] + | str_p( "null" ) [ new_null ] + ; + + object_ + = ch_p('{')[ begin_obj ] + >> !members_ + >> ( ch_p('}')[ end_obj ] | eps_p[ &throw_not_object ] ) + ; + + members_ + = pair_ >> *( ',' >> pair_ ) + ; + + pair_ + = string_[ new_name ] + >> ( ':' | eps_p[ &throw_not_colon ] ) + >> ( value_ | eps_p[ &throw_not_value ] ) + ; + + array_ + = ch_p('[')[ begin_array ] + >> !elements_ + >> ( ch_p(']')[ end_array ] | eps_p[ &throw_not_array ] ) + ; + + elements_ + = value_ >> *( ',' >> value_ ) + ; + + string_ + = lexeme_d // this causes white space inside a string to be retained + [ + confix_p + ( + '"', + *lex_escape_ch_p, + '"' + ) + ] + ; + + number_ + = strict_real_p[ new_real ] + | int64_p [ new_int ] + | uint64_p [ new_uint64 ] + ; + } + + spirit_namespace::rule< ScannerT > json_, object_, members_, pair_, array_, elements_, value_, string_, number_; + + const spirit_namespace::rule< ScannerT >& start() const { return json_; } + }; + + private: + + Json_grammer& operator=( const Json_grammer& ); // to prevent "assignment operator could not be generated" warning + + Semantic_actions_t& actions_; + }; + + template< class Iter_type, class Value_type > + Iter_type read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value ) + { + Semantic_actions< Value_type, Iter_type > semantic_actions( value ); + + const spirit_namespace::parse_info< Iter_type > info = + spirit_namespace::parse( begin, end, + Json_grammer< Value_type, Iter_type >( semantic_actions ), + spirit_namespace::space_p ); + + if( !info.hit ) + { + assert( false ); // in theory exception should already have been thrown + throw_error( info.stop, "error" ); + } + + return info.stop; + } + + template< class Iter_type, class Value_type > + void add_posn_iter_and_read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value ) + { + typedef spirit_namespace::position_iterator< Iter_type > Posn_iter_t; + + const Posn_iter_t posn_begin( begin, end ); + const Posn_iter_t posn_end( end, end ); + + read_range_or_throw( posn_begin, posn_end, value ); + } + + template< class Iter_type, class Value_type > + bool read_range( Iter_type& begin, Iter_type end, Value_type& value ) + { + try + { + begin = read_range_or_throw( begin, end, value ); + + return true; + } + catch( ... ) + { + return false; + } + } + + template< class String_type, class Value_type > + void read_string_or_throw( const String_type& s, Value_type& value ) + { + add_posn_iter_and_read_range_or_throw( s.begin(), s.end(), value ); + } + + template< class String_type, class Value_type > + bool read_string( const String_type& s, Value_type& value ) + { + typename String_type::const_iterator begin = s.begin(); + + return read_range( begin, s.end(), value ); + } + + template< class Istream_type > + struct Multi_pass_iters + { + typedef typename Istream_type::char_type Char_type; + typedef std::istream_iterator< Char_type, Char_type > istream_iter; + typedef spirit_namespace::multi_pass< istream_iter > Mp_iter; + + Multi_pass_iters( Istream_type& is ) + { + is.unsetf( std::ios::skipws ); + + begin_ = spirit_namespace::make_multi_pass( istream_iter( is ) ); + end_ = spirit_namespace::make_multi_pass( istream_iter() ); + } + + Mp_iter begin_; + Mp_iter end_; + }; + + template< class Istream_type, class Value_type > + bool read_stream( Istream_type& is, Value_type& value ) + { + Multi_pass_iters< Istream_type > mp_iters( is ); + + return read_range( mp_iters.begin_, mp_iters.end_, value ); + } + + template< class Istream_type, class Value_type > + void read_stream_or_throw( Istream_type& is, Value_type& value ) + { + const Multi_pass_iters< Istream_type > mp_iters( is ); + + add_posn_iter_and_read_range_or_throw( mp_iters.begin_, mp_iters.end_, value ); + } +} + +#endif diff --git a/json/json_spirit_stream_reader.h b/json/json_spirit_stream_reader.h index a9ceeacf00..7e59c9adc2 100644 --- a/json/json_spirit_stream_reader.h +++ b/json/json_spirit_stream_reader.h @@ -1,70 +1,70 @@ -#ifndef JSON_SPIRIT_READ_STREAM
-#define JSON_SPIRIT_READ_STREAM
-
-// Copyright John W. Wilkinson 2007 - 2009.
-// Distributed under the MIT License, see accompanying file LICENSE.txt
-
-// json spirit version 4.03
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1020)
-# pragma once
-#endif
-
-#include "json_spirit_reader_template.h"
-
-namespace json_spirit
-{
- // these classes allows you to read multiple top level contiguous values from a stream,
- // the normal stream read functions have a bug that prevent multiple top level values
- // from being read unless they are separated by spaces
-
- template< class Istream_type, class Value_type >
- class Stream_reader
- {
- public:
-
- Stream_reader( Istream_type& is )
- : iters_( is )
- {
- }
-
- bool read_next( Value_type& value )
- {
- return read_range( iters_.begin_, iters_.end_, value );
- }
-
- private:
-
- typedef Multi_pass_iters< Istream_type > Mp_iters;
-
- Mp_iters iters_;
- };
-
- template< class Istream_type, class Value_type >
- class Stream_reader_thrower
- {
- public:
-
- Stream_reader_thrower( Istream_type& is )
- : iters_( is )
- , posn_begin_( iters_.begin_, iters_.end_ )
- , posn_end_( iters_.end_, iters_.end_ )
- {
- }
-
- void read_next( Value_type& value )
- {
- posn_begin_ = read_range_or_throw( posn_begin_, posn_end_, value );
- }
-
- private:
-
- typedef Multi_pass_iters< Istream_type > Mp_iters;
- typedef spirit_namespace::position_iterator< typename Mp_iters::Mp_iter > Posn_iter_t;
-
- Mp_iters iters_;
- Posn_iter_t posn_begin_, posn_end_;
- };
-}
-
-#endif
+#ifndef JSON_SPIRIT_READ_STREAM +#define JSON_SPIRIT_READ_STREAM + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include "json_spirit_reader_template.h" + +namespace json_spirit +{ + // these classes allows you to read multiple top level contiguous values from a stream, + // the normal stream read functions have a bug that prevent multiple top level values + // from being read unless they are separated by spaces + + template< class Istream_type, class Value_type > + class Stream_reader + { + public: + + Stream_reader( Istream_type& is ) + : iters_( is ) + { + } + + bool read_next( Value_type& value ) + { + return read_range( iters_.begin_, iters_.end_, value ); + } + + private: + + typedef Multi_pass_iters< Istream_type > Mp_iters; + + Mp_iters iters_; + }; + + template< class Istream_type, class Value_type > + class Stream_reader_thrower + { + public: + + Stream_reader_thrower( Istream_type& is ) + : iters_( is ) + , posn_begin_( iters_.begin_, iters_.end_ ) + , posn_end_( iters_.end_, iters_.end_ ) + { + } + + void read_next( Value_type& value ) + { + posn_begin_ = read_range_or_throw( posn_begin_, posn_end_, value ); + } + + private: + + typedef Multi_pass_iters< Istream_type > Mp_iters; + typedef spirit_namespace::position_iterator< typename Mp_iters::Mp_iter > Posn_iter_t; + + Mp_iters iters_; + Posn_iter_t posn_begin_, posn_end_; + }; +} + +#endif diff --git a/json/json_spirit_utils.h b/json/json_spirit_utils.h index 7eb338e7c5..553e3b96a4 100644 --- a/json/json_spirit_utils.h +++ b/json/json_spirit_utils.h @@ -1,61 +1,61 @@ -#ifndef JSON_SPIRIT_UTILS
-#define JSON_SPIRIT_UTILS
-
-// Copyright John W. Wilkinson 2007 - 2009.
-// Distributed under the MIT License, see accompanying file LICENSE.txt
-
-// json spirit version 4.03
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1020)
-# pragma once
-#endif
-
-#include "json_spirit_value.h"
-#include <map>
-
-namespace json_spirit
-{
- template< class Obj_t, class Map_t >
- void obj_to_map( const Obj_t& obj, Map_t& mp_obj )
- {
- mp_obj.clear();
-
- for( typename Obj_t::const_iterator i = obj.begin(); i != obj.end(); ++i )
- {
- mp_obj[ i->name_ ] = i->value_;
- }
- }
-
- template< class Obj_t, class Map_t >
- void map_to_obj( const Map_t& mp_obj, Obj_t& obj )
- {
- obj.clear();
-
- for( typename Map_t::const_iterator i = mp_obj.begin(); i != mp_obj.end(); ++i )
- {
- obj.push_back( typename Obj_t::value_type( i->first, i->second ) );
- }
- }
-
- typedef std::map< std::string, Value > Mapped_obj;
-
-#ifndef BOOST_NO_STD_WSTRING
- typedef std::map< std::wstring, wValue > wMapped_obj;
-#endif
-
- template< class Object_type, class String_type >
- const typename Object_type::value_type::Value_type& find_value( const Object_type& obj, const String_type& name )
- {
- for( typename Object_type::const_iterator i = obj.begin(); i != obj.end(); ++i )
- {
- if( i->name_ == name )
- {
- return i->value_;
- }
- }
-
- return Object_type::value_type::Value_type::null;
- }
-}
-
-#endif
+#ifndef JSON_SPIRIT_UTILS +#define JSON_SPIRIT_UTILS + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include "json_spirit_value.h" +#include <map> + +namespace json_spirit +{ + template< class Obj_t, class Map_t > + void obj_to_map( const Obj_t& obj, Map_t& mp_obj ) + { + mp_obj.clear(); + + for( typename Obj_t::const_iterator i = obj.begin(); i != obj.end(); ++i ) + { + mp_obj[ i->name_ ] = i->value_; + } + } + + template< class Obj_t, class Map_t > + void map_to_obj( const Map_t& mp_obj, Obj_t& obj ) + { + obj.clear(); + + for( typename Map_t::const_iterator i = mp_obj.begin(); i != mp_obj.end(); ++i ) + { + obj.push_back( typename Obj_t::value_type( i->first, i->second ) ); + } + } + + typedef std::map< std::string, Value > Mapped_obj; + +#ifndef BOOST_NO_STD_WSTRING + typedef std::map< std::wstring, wValue > wMapped_obj; +#endif + + template< class Object_type, class String_type > + const typename Object_type::value_type::Value_type& find_value( const Object_type& obj, const String_type& name ) + { + for( typename Object_type::const_iterator i = obj.begin(); i != obj.end(); ++i ) + { + if( i->name_ == name ) + { + return i->value_; + } + } + + return Object_type::value_type::Value_type::null; + } +} + +#endif diff --git a/json/json_spirit_value.cpp b/json/json_spirit_value.cpp index dd5b50e5d5..44d2f06a01 100644 --- a/json/json_spirit_value.cpp +++ b/json/json_spirit_value.cpp @@ -1,8 +1,8 @@ -/* Copyright (c) 2007 John W Wilkinson
-
- This source code can be used for any purpose as long as
- this comment is retained. */
-
-// json spirit version 2.00
-
-#include "json_spirit_value.h"
+/* Copyright (c) 2007 John W Wilkinson + + This source code can be used for any purpose as long as + this comment is retained. */ + +// json spirit version 2.00 + +#include "json_spirit_value.h" diff --git a/json/json_spirit_value.h b/json/json_spirit_value.h index e9bcd36b80..6274df1095 100644 --- a/json/json_spirit_value.h +++ b/json/json_spirit_value.h @@ -1,534 +1,534 @@ -#ifndef JSON_SPIRIT_VALUE
-#define JSON_SPIRIT_VALUE
-
-// Copyright John W. Wilkinson 2007 - 2009.
-// Distributed under the MIT License, see accompanying file LICENSE.txt
-
-// json spirit version 4.03
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1020)
-# pragma once
-#endif
-
-#include <vector>
-#include <map>
-#include <string>
-#include <cassert>
-#include <sstream>
-#include <stdexcept>
-#include <boost/config.hpp>
-#include <boost/cstdint.hpp>
-#include <boost/shared_ptr.hpp>
-#include <boost/variant.hpp>
-
-namespace json_spirit
-{
- enum Value_type{ obj_type, array_type, str_type, bool_type, int_type, real_type, null_type };
- static const char* Value_type_name[]={"obj", "array", "str", "bool", "int", "real", "null"};
-
- template< class Config > // Config determines whether the value uses std::string or std::wstring and
- // whether JSON Objects are represented as vectors or maps
- class Value_impl
- {
- public:
-
- typedef Config Config_type;
- typedef typename Config::String_type String_type;
- typedef typename Config::Object_type Object;
- typedef typename Config::Array_type Array;
- typedef typename String_type::const_pointer Const_str_ptr; // eg const char*
-
- Value_impl(); // creates null value
- Value_impl( Const_str_ptr value );
- Value_impl( const String_type& value );
- Value_impl( const Object& value );
- Value_impl( const Array& value );
- Value_impl( bool value );
- Value_impl( int value );
- Value_impl( boost::int64_t value );
- Value_impl( boost::uint64_t value );
- Value_impl( double value );
-
- Value_impl( const Value_impl& other );
-
- bool operator==( const Value_impl& lhs ) const;
-
- Value_impl& operator=( const Value_impl& lhs );
-
- Value_type type() const;
-
- bool is_uint64() const;
- bool is_null() const;
-
- const String_type& get_str() const;
- const Object& get_obj() const;
- const Array& get_array() const;
- bool get_bool() const;
- int get_int() const;
- boost::int64_t get_int64() const;
- boost::uint64_t get_uint64() const;
- double get_real() const;
-
- Object& get_obj();
- Array& get_array();
-
- template< typename T > T get_value() const; // example usage: int i = value.get_value< int >();
- // or double d = value.get_value< double >();
-
- static const Value_impl null;
-
- private:
-
- void check_type( const Value_type vtype ) const;
-
- typedef boost::variant< String_type,
- boost::recursive_wrapper< Object >, boost::recursive_wrapper< Array >,
- bool, boost::int64_t, double > Variant;
-
- Value_type type_;
- Variant v_;
- bool is_uint64_;
- };
-
- // vector objects
-
- template< class Config >
- struct Pair_impl
- {
- typedef typename Config::String_type String_type;
- typedef typename Config::Value_type Value_type;
-
- Pair_impl( const String_type& name, const Value_type& value );
-
- bool operator==( const Pair_impl& lhs ) const;
-
- String_type name_;
- Value_type value_;
- };
-
- template< class String >
- struct Config_vector
- {
- typedef String String_type;
- typedef Value_impl< Config_vector > Value_type;
- typedef Pair_impl < Config_vector > Pair_type;
- typedef std::vector< Value_type > Array_type;
- typedef std::vector< Pair_type > Object_type;
-
- static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value )
- {
- obj.push_back( Pair_type( name , value ) );
-
- return obj.back().value_;
- }
-
- static String_type get_name( const Pair_type& pair )
- {
- return pair.name_;
- }
-
- static Value_type get_value( const Pair_type& pair )
- {
- return pair.value_;
- }
- };
-
- // typedefs for ASCII
-
- typedef Config_vector< std::string > Config;
-
- typedef Config::Value_type Value;
- typedef Config::Pair_type Pair;
- typedef Config::Object_type Object;
- typedef Config::Array_type Array;
-
- // typedefs for Unicode
-
-#ifndef BOOST_NO_STD_WSTRING
-
- typedef Config_vector< std::wstring > wConfig;
-
- typedef wConfig::Value_type wValue;
- typedef wConfig::Pair_type wPair;
- typedef wConfig::Object_type wObject;
- typedef wConfig::Array_type wArray;
-#endif
-
- // map objects
-
- template< class String >
- struct Config_map
- {
- typedef String String_type;
- typedef Value_impl< Config_map > Value_type;
- typedef std::vector< Value_type > Array_type;
- typedef std::map< String_type, Value_type > Object_type;
- typedef typename Object_type::value_type Pair_type;
-
- static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value )
- {
- return obj[ name ] = value;
- }
-
- static String_type get_name( const Pair_type& pair )
- {
- return pair.first;
- }
-
- static Value_type get_value( const Pair_type& pair )
- {
- return pair.second;
- }
- };
-
- // typedefs for ASCII
-
- typedef Config_map< std::string > mConfig;
-
- typedef mConfig::Value_type mValue;
- typedef mConfig::Object_type mObject;
- typedef mConfig::Array_type mArray;
-
- // typedefs for Unicode
-
-#ifndef BOOST_NO_STD_WSTRING
-
- typedef Config_map< std::wstring > wmConfig;
-
- typedef wmConfig::Value_type wmValue;
- typedef wmConfig::Object_type wmObject;
- typedef wmConfig::Array_type wmArray;
-
-#endif
-
- ///////////////////////////////////////////////////////////////////////////////////////////////
- //
- // implementation
-
- template< class Config >
- const Value_impl< Config > Value_impl< Config >::null;
-
- template< class Config >
- Value_impl< Config >::Value_impl()
- : type_( null_type )
- , is_uint64_( false )
- {
- }
-
- template< class Config >
- Value_impl< Config >::Value_impl( const Const_str_ptr value )
- : type_( str_type )
- , v_( String_type( value ) )
- , is_uint64_( false )
- {
- }
-
- template< class Config >
- Value_impl< Config >::Value_impl( const String_type& value )
- : type_( str_type )
- , v_( value )
- , is_uint64_( false )
- {
- }
-
- template< class Config >
- Value_impl< Config >::Value_impl( const Object& value )
- : type_( obj_type )
- , v_( value )
- , is_uint64_( false )
- {
- }
-
- template< class Config >
- Value_impl< Config >::Value_impl( const Array& value )
- : type_( array_type )
- , v_( value )
- , is_uint64_( false )
- {
- }
-
- template< class Config >
- Value_impl< Config >::Value_impl( bool value )
- : type_( bool_type )
- , v_( value )
- , is_uint64_( false )
- {
- }
-
- template< class Config >
- Value_impl< Config >::Value_impl( int value )
- : type_( int_type )
- , v_( static_cast< boost::int64_t >( value ) )
- , is_uint64_( false )
- {
- }
-
- template< class Config >
- Value_impl< Config >::Value_impl( boost::int64_t value )
- : type_( int_type )
- , v_( value )
- , is_uint64_( false )
- {
- }
-
- template< class Config >
- Value_impl< Config >::Value_impl( boost::uint64_t value )
- : type_( int_type )
- , v_( static_cast< boost::int64_t >( value ) )
- , is_uint64_( true )
- {
- }
-
- template< class Config >
- Value_impl< Config >::Value_impl( double value )
- : type_( real_type )
- , v_( value )
- , is_uint64_( false )
- {
- }
-
- template< class Config >
- Value_impl< Config >::Value_impl( const Value_impl< Config >& other )
- : type_( other.type() )
- , v_( other.v_ )
- , is_uint64_( other.is_uint64_ )
- {
- }
-
- template< class Config >
- Value_impl< Config >& Value_impl< Config >::operator=( const Value_impl& lhs )
- {
- Value_impl tmp( lhs );
-
- std::swap( type_, tmp.type_ );
- std::swap( v_, tmp.v_ );
- std::swap( is_uint64_, tmp.is_uint64_ );
-
- return *this;
- }
-
- template< class Config >
- bool Value_impl< Config >::operator==( const Value_impl& lhs ) const
- {
- if( this == &lhs ) return true;
-
- if( type() != lhs.type() ) return false;
-
- return v_ == lhs.v_;
- }
-
- template< class Config >
- Value_type Value_impl< Config >::type() const
- {
- return type_;
- }
-
- template< class Config >
- bool Value_impl< Config >::is_uint64() const
- {
- return is_uint64_;
- }
-
- template< class Config >
- bool Value_impl< Config >::is_null() const
- {
- return type() == null_type;
- }
-
- template< class Config >
- void Value_impl< Config >::check_type( const Value_type vtype ) const
- {
- if( type() != vtype )
- {
- std::ostringstream os;
-
- /// satoshi: tell the types by name instead of by number
- os << "value is type " << Value_type_name[type()] << ", expected " << Value_type_name[vtype];
-
- throw std::runtime_error( os.str() );
- }
- }
-
- template< class Config >
- const typename Config::String_type& Value_impl< Config >::get_str() const
- {
- check_type( str_type );
-
- return *boost::get< String_type >( &v_ );
- }
-
- template< class Config >
- const typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() const
- {
- check_type( obj_type );
-
- return *boost::get< Object >( &v_ );
- }
-
- template< class Config >
- const typename Value_impl< Config >::Array& Value_impl< Config >::get_array() const
- {
- check_type( array_type );
-
- return *boost::get< Array >( &v_ );
- }
-
- template< class Config >
- bool Value_impl< Config >::get_bool() const
- {
- check_type( bool_type );
-
- return boost::get< bool >( v_ );
- }
-
- template< class Config >
- int Value_impl< Config >::get_int() const
- {
- check_type( int_type );
-
- return static_cast< int >( get_int64() );
- }
-
- template< class Config >
- boost::int64_t Value_impl< Config >::get_int64() const
- {
- check_type( int_type );
-
- return boost::get< boost::int64_t >( v_ );
- }
-
- template< class Config >
- boost::uint64_t Value_impl< Config >::get_uint64() const
- {
- check_type( int_type );
-
- return static_cast< boost::uint64_t >( get_int64() );
- }
-
- template< class Config >
- double Value_impl< Config >::get_real() const
- {
- if( type() == int_type )
- {
- return is_uint64() ? static_cast< double >( get_uint64() )
- : static_cast< double >( get_int64() );
- }
-
- check_type( real_type );
-
- return boost::get< double >( v_ );
- }
-
- template< class Config >
- typename Value_impl< Config >::Object& Value_impl< Config >::get_obj()
- {
- check_type( obj_type );
-
- return *boost::get< Object >( &v_ );
- }
-
- template< class Config >
- typename Value_impl< Config >::Array& Value_impl< Config >::get_array()
- {
- check_type( array_type );
-
- return *boost::get< Array >( &v_ );
- }
-
- template< class Config >
- Pair_impl< Config >::Pair_impl( const String_type& name, const Value_type& value )
- : name_( name )
- , value_( value )
- {
- }
-
- template< class Config >
- bool Pair_impl< Config >::operator==( const Pair_impl< Config >& lhs ) const
- {
- if( this == &lhs ) return true;
-
- return ( name_ == lhs.name_ ) && ( value_ == lhs.value_ );
- }
-
- // converts a C string, ie. 8 bit char array, to a string object
- //
- template < class String_type >
- String_type to_str( const char* c_str )
- {
- String_type result;
-
- for( const char* p = c_str; *p != 0; ++p )
- {
- result += *p;
- }
-
- return result;
- }
-
- //
-
- namespace internal_
- {
- template< typename T >
- struct Type_to_type
- {
- };
-
- template< class Value >
- int get_value( const Value& value, Type_to_type< int > )
- {
- return value.get_int();
- }
-
- template< class Value >
- boost::int64_t get_value( const Value& value, Type_to_type< boost::int64_t > )
- {
- return value.get_int64();
- }
-
- template< class Value >
- boost::uint64_t get_value( const Value& value, Type_to_type< boost::uint64_t > )
- {
- return value.get_uint64();
- }
-
- template< class Value >
- double get_value( const Value& value, Type_to_type< double > )
- {
- return value.get_real();
- }
-
- template< class Value >
- typename Value::String_type get_value( const Value& value, Type_to_type< typename Value::String_type > )
- {
- return value.get_str();
- }
-
- template< class Value >
- typename Value::Array get_value( const Value& value, Type_to_type< typename Value::Array > )
- {
- return value.get_array();
- }
-
- template< class Value >
- typename Value::Object get_value( const Value& value, Type_to_type< typename Value::Object > )
- {
- return value.get_obj();
- }
-
- template< class Value >
- bool get_value( const Value& value, Type_to_type< bool > )
- {
- return value.get_bool();
- }
- }
-
- template< class Config >
- template< typename T >
- T Value_impl< Config >::get_value() const
- {
- return internal_::get_value( *this, internal_::Type_to_type< T >() );
- }
-}
-
-#endif
+#ifndef JSON_SPIRIT_VALUE +#define JSON_SPIRIT_VALUE + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include <vector> +#include <map> +#include <string> +#include <cassert> +#include <sstream> +#include <stdexcept> +#include <boost/config.hpp> +#include <boost/cstdint.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/variant.hpp> + +namespace json_spirit +{ + enum Value_type{ obj_type, array_type, str_type, bool_type, int_type, real_type, null_type }; + static const char* Value_type_name[]={"obj", "array", "str", "bool", "int", "real", "null"}; + + template< class Config > // Config determines whether the value uses std::string or std::wstring and + // whether JSON Objects are represented as vectors or maps + class Value_impl + { + public: + + typedef Config Config_type; + typedef typename Config::String_type String_type; + typedef typename Config::Object_type Object; + typedef typename Config::Array_type Array; + typedef typename String_type::const_pointer Const_str_ptr; // eg const char* + + Value_impl(); // creates null value + Value_impl( Const_str_ptr value ); + Value_impl( const String_type& value ); + Value_impl( const Object& value ); + Value_impl( const Array& value ); + Value_impl( bool value ); + Value_impl( int value ); + Value_impl( boost::int64_t value ); + Value_impl( boost::uint64_t value ); + Value_impl( double value ); + + Value_impl( const Value_impl& other ); + + bool operator==( const Value_impl& lhs ) const; + + Value_impl& operator=( const Value_impl& lhs ); + + Value_type type() const; + + bool is_uint64() const; + bool is_null() const; + + const String_type& get_str() const; + const Object& get_obj() const; + const Array& get_array() const; + bool get_bool() const; + int get_int() const; + boost::int64_t get_int64() const; + boost::uint64_t get_uint64() const; + double get_real() const; + + Object& get_obj(); + Array& get_array(); + + template< typename T > T get_value() const; // example usage: int i = value.get_value< int >(); + // or double d = value.get_value< double >(); + + static const Value_impl null; + + private: + + void check_type( const Value_type vtype ) const; + + typedef boost::variant< String_type, + boost::recursive_wrapper< Object >, boost::recursive_wrapper< Array >, + bool, boost::int64_t, double > Variant; + + Value_type type_; + Variant v_; + bool is_uint64_; + }; + + // vector objects + + template< class Config > + struct Pair_impl + { + typedef typename Config::String_type String_type; + typedef typename Config::Value_type Value_type; + + Pair_impl( const String_type& name, const Value_type& value ); + + bool operator==( const Pair_impl& lhs ) const; + + String_type name_; + Value_type value_; + }; + + template< class String > + struct Config_vector + { + typedef String String_type; + typedef Value_impl< Config_vector > Value_type; + typedef Pair_impl < Config_vector > Pair_type; + typedef std::vector< Value_type > Array_type; + typedef std::vector< Pair_type > Object_type; + + static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value ) + { + obj.push_back( Pair_type( name , value ) ); + + return obj.back().value_; + } + + static String_type get_name( const Pair_type& pair ) + { + return pair.name_; + } + + static Value_type get_value( const Pair_type& pair ) + { + return pair.value_; + } + }; + + // typedefs for ASCII + + typedef Config_vector< std::string > Config; + + typedef Config::Value_type Value; + typedef Config::Pair_type Pair; + typedef Config::Object_type Object; + typedef Config::Array_type Array; + + // typedefs for Unicode + +#ifndef BOOST_NO_STD_WSTRING + + typedef Config_vector< std::wstring > wConfig; + + typedef wConfig::Value_type wValue; + typedef wConfig::Pair_type wPair; + typedef wConfig::Object_type wObject; + typedef wConfig::Array_type wArray; +#endif + + // map objects + + template< class String > + struct Config_map + { + typedef String String_type; + typedef Value_impl< Config_map > Value_type; + typedef std::vector< Value_type > Array_type; + typedef std::map< String_type, Value_type > Object_type; + typedef typename Object_type::value_type Pair_type; + + static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value ) + { + return obj[ name ] = value; + } + + static String_type get_name( const Pair_type& pair ) + { + return pair.first; + } + + static Value_type get_value( const Pair_type& pair ) + { + return pair.second; + } + }; + + // typedefs for ASCII + + typedef Config_map< std::string > mConfig; + + typedef mConfig::Value_type mValue; + typedef mConfig::Object_type mObject; + typedef mConfig::Array_type mArray; + + // typedefs for Unicode + +#ifndef BOOST_NO_STD_WSTRING + + typedef Config_map< std::wstring > wmConfig; + + typedef wmConfig::Value_type wmValue; + typedef wmConfig::Object_type wmObject; + typedef wmConfig::Array_type wmArray; + +#endif + + /////////////////////////////////////////////////////////////////////////////////////////////// + // + // implementation + + template< class Config > + const Value_impl< Config > Value_impl< Config >::null; + + template< class Config > + Value_impl< Config >::Value_impl() + : type_( null_type ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( const Const_str_ptr value ) + : type_( str_type ) + , v_( String_type( value ) ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( const String_type& value ) + : type_( str_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( const Object& value ) + : type_( obj_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( const Array& value ) + : type_( array_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( bool value ) + : type_( bool_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( int value ) + : type_( int_type ) + , v_( static_cast< boost::int64_t >( value ) ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( boost::int64_t value ) + : type_( int_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( boost::uint64_t value ) + : type_( int_type ) + , v_( static_cast< boost::int64_t >( value ) ) + , is_uint64_( true ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( double value ) + : type_( real_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( const Value_impl< Config >& other ) + : type_( other.type() ) + , v_( other.v_ ) + , is_uint64_( other.is_uint64_ ) + { + } + + template< class Config > + Value_impl< Config >& Value_impl< Config >::operator=( const Value_impl& lhs ) + { + Value_impl tmp( lhs ); + + std::swap( type_, tmp.type_ ); + std::swap( v_, tmp.v_ ); + std::swap( is_uint64_, tmp.is_uint64_ ); + + return *this; + } + + template< class Config > + bool Value_impl< Config >::operator==( const Value_impl& lhs ) const + { + if( this == &lhs ) return true; + + if( type() != lhs.type() ) return false; + + return v_ == lhs.v_; + } + + template< class Config > + Value_type Value_impl< Config >::type() const + { + return type_; + } + + template< class Config > + bool Value_impl< Config >::is_uint64() const + { + return is_uint64_; + } + + template< class Config > + bool Value_impl< Config >::is_null() const + { + return type() == null_type; + } + + template< class Config > + void Value_impl< Config >::check_type( const Value_type vtype ) const + { + if( type() != vtype ) + { + std::ostringstream os; + + /// satoshi: tell the types by name instead of by number + os << "value is type " << Value_type_name[type()] << ", expected " << Value_type_name[vtype]; + + throw std::runtime_error( os.str() ); + } + } + + template< class Config > + const typename Config::String_type& Value_impl< Config >::get_str() const + { + check_type( str_type ); + + return *boost::get< String_type >( &v_ ); + } + + template< class Config > + const typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() const + { + check_type( obj_type ); + + return *boost::get< Object >( &v_ ); + } + + template< class Config > + const typename Value_impl< Config >::Array& Value_impl< Config >::get_array() const + { + check_type( array_type ); + + return *boost::get< Array >( &v_ ); + } + + template< class Config > + bool Value_impl< Config >::get_bool() const + { + check_type( bool_type ); + + return boost::get< bool >( v_ ); + } + + template< class Config > + int Value_impl< Config >::get_int() const + { + check_type( int_type ); + + return static_cast< int >( get_int64() ); + } + + template< class Config > + boost::int64_t Value_impl< Config >::get_int64() const + { + check_type( int_type ); + + return boost::get< boost::int64_t >( v_ ); + } + + template< class Config > + boost::uint64_t Value_impl< Config >::get_uint64() const + { + check_type( int_type ); + + return static_cast< boost::uint64_t >( get_int64() ); + } + + template< class Config > + double Value_impl< Config >::get_real() const + { + if( type() == int_type ) + { + return is_uint64() ? static_cast< double >( get_uint64() ) + : static_cast< double >( get_int64() ); + } + + check_type( real_type ); + + return boost::get< double >( v_ ); + } + + template< class Config > + typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() + { + check_type( obj_type ); + + return *boost::get< Object >( &v_ ); + } + + template< class Config > + typename Value_impl< Config >::Array& Value_impl< Config >::get_array() + { + check_type( array_type ); + + return *boost::get< Array >( &v_ ); + } + + template< class Config > + Pair_impl< Config >::Pair_impl( const String_type& name, const Value_type& value ) + : name_( name ) + , value_( value ) + { + } + + template< class Config > + bool Pair_impl< Config >::operator==( const Pair_impl< Config >& lhs ) const + { + if( this == &lhs ) return true; + + return ( name_ == lhs.name_ ) && ( value_ == lhs.value_ ); + } + + // converts a C string, ie. 8 bit char array, to a string object + // + template < class String_type > + String_type to_str( const char* c_str ) + { + String_type result; + + for( const char* p = c_str; *p != 0; ++p ) + { + result += *p; + } + + return result; + } + + // + + namespace internal_ + { + template< typename T > + struct Type_to_type + { + }; + + template< class Value > + int get_value( const Value& value, Type_to_type< int > ) + { + return value.get_int(); + } + + template< class Value > + boost::int64_t get_value( const Value& value, Type_to_type< boost::int64_t > ) + { + return value.get_int64(); + } + + template< class Value > + boost::uint64_t get_value( const Value& value, Type_to_type< boost::uint64_t > ) + { + return value.get_uint64(); + } + + template< class Value > + double get_value( const Value& value, Type_to_type< double > ) + { + return value.get_real(); + } + + template< class Value > + typename Value::String_type get_value( const Value& value, Type_to_type< typename Value::String_type > ) + { + return value.get_str(); + } + + template< class Value > + typename Value::Array get_value( const Value& value, Type_to_type< typename Value::Array > ) + { + return value.get_array(); + } + + template< class Value > + typename Value::Object get_value( const Value& value, Type_to_type< typename Value::Object > ) + { + return value.get_obj(); + } + + template< class Value > + bool get_value( const Value& value, Type_to_type< bool > ) + { + return value.get_bool(); + } + } + + template< class Config > + template< typename T > + T Value_impl< Config >::get_value() const + { + return internal_::get_value( *this, internal_::Type_to_type< T >() ); + } +} + +#endif diff --git a/json/json_spirit_writer.cpp b/json/json_spirit_writer.cpp index f3367b68de..d24a632cf3 100644 --- a/json/json_spirit_writer.cpp +++ b/json/json_spirit_writer.cpp @@ -1,95 +1,95 @@ -// Copyright John W. Wilkinson 2007 - 2009.
-// Distributed under the MIT License, see accompanying file LICENSE.txt
-
-// json spirit version 4.03
-
-#include "json_spirit_writer.h"
-#include "json_spirit_writer_template.h"
-
-void json_spirit::write( const Value& value, std::ostream& os )
-{
- write_stream( value, os, false );
-}
-
-void json_spirit::write_formatted( const Value& value, std::ostream& os )
-{
- write_stream( value, os, true );
-}
-
-std::string json_spirit::write( const Value& value )
-{
- return write_string( value, false );
-}
-
-std::string json_spirit::write_formatted( const Value& value )
-{
- return write_string( value, true );
-}
-
-#ifndef BOOST_NO_STD_WSTRING
-
-void json_spirit::write( const wValue& value, std::wostream& os )
-{
- write_stream( value, os, false );
-}
-
-void json_spirit::write_formatted( const wValue& value, std::wostream& os )
-{
- write_stream( value, os, true );
-}
-
-std::wstring json_spirit::write( const wValue& value )
-{
- return write_string( value, false );
-}
-
-std::wstring json_spirit::write_formatted( const wValue& value )
-{
- return write_string( value, true );
-}
-
-#endif
-
-void json_spirit::write( const mValue& value, std::ostream& os )
-{
- write_stream( value, os, false );
-}
-
-void json_spirit::write_formatted( const mValue& value, std::ostream& os )
-{
- write_stream( value, os, true );
-}
-
-std::string json_spirit::write( const mValue& value )
-{
- return write_string( value, false );
-}
-
-std::string json_spirit::write_formatted( const mValue& value )
-{
- return write_string( value, true );
-}
-
-#ifndef BOOST_NO_STD_WSTRING
-
-void json_spirit::write( const wmValue& value, std::wostream& os )
-{
- write_stream( value, os, false );
-}
-
-void json_spirit::write_formatted( const wmValue& value, std::wostream& os )
-{
- write_stream( value, os, true );
-}
-
-std::wstring json_spirit::write( const wmValue& value )
-{
- return write_string( value, false );
-}
-
-std::wstring json_spirit::write_formatted( const wmValue& value )
-{
- return write_string( value, true );
-}
-
-#endif
+// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#include "json_spirit_writer.h" +#include "json_spirit_writer_template.h" + +void json_spirit::write( const Value& value, std::ostream& os ) +{ + write_stream( value, os, false ); +} + +void json_spirit::write_formatted( const Value& value, std::ostream& os ) +{ + write_stream( value, os, true ); +} + +std::string json_spirit::write( const Value& value ) +{ + return write_string( value, false ); +} + +std::string json_spirit::write_formatted( const Value& value ) +{ + return write_string( value, true ); +} + +#ifndef BOOST_NO_STD_WSTRING + +void json_spirit::write( const wValue& value, std::wostream& os ) +{ + write_stream( value, os, false ); +} + +void json_spirit::write_formatted( const wValue& value, std::wostream& os ) +{ + write_stream( value, os, true ); +} + +std::wstring json_spirit::write( const wValue& value ) +{ + return write_string( value, false ); +} + +std::wstring json_spirit::write_formatted( const wValue& value ) +{ + return write_string( value, true ); +} + +#endif + +void json_spirit::write( const mValue& value, std::ostream& os ) +{ + write_stream( value, os, false ); +} + +void json_spirit::write_formatted( const mValue& value, std::ostream& os ) +{ + write_stream( value, os, true ); +} + +std::string json_spirit::write( const mValue& value ) +{ + return write_string( value, false ); +} + +std::string json_spirit::write_formatted( const mValue& value ) +{ + return write_string( value, true ); +} + +#ifndef BOOST_NO_STD_WSTRING + +void json_spirit::write( const wmValue& value, std::wostream& os ) +{ + write_stream( value, os, false ); +} + +void json_spirit::write_formatted( const wmValue& value, std::wostream& os ) +{ + write_stream( value, os, true ); +} + +std::wstring json_spirit::write( const wmValue& value ) +{ + return write_string( value, false ); +} + +std::wstring json_spirit::write_formatted( const wmValue& value ) +{ + return write_string( value, true ); +} + +#endif diff --git a/json/json_spirit_writer.h b/json/json_spirit_writer.h index 1b67b512df..52e14068e7 100644 --- a/json/json_spirit_writer.h +++ b/json/json_spirit_writer.h @@ -1,50 +1,50 @@ -#ifndef JSON_SPIRIT_WRITER
-#define JSON_SPIRIT_WRITER
-
-// Copyright John W. Wilkinson 2007 - 2009.
-// Distributed under the MIT License, see accompanying file LICENSE.txt
-
-// json spirit version 4.03
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1020)
-# pragma once
-#endif
-
-#include "json_spirit_value.h"
-#include <iostream>
-
-namespace json_spirit
-{
- // functions to convert JSON Values to text,
- // the "formatted" versions add whitespace to format the output nicely
-
- void write ( const Value& value, std::ostream& os );
- void write_formatted( const Value& value, std::ostream& os );
- std::string write ( const Value& value );
- std::string write_formatted( const Value& value );
-
-#ifndef BOOST_NO_STD_WSTRING
-
- void write ( const wValue& value, std::wostream& os );
- void write_formatted( const wValue& value, std::wostream& os );
- std::wstring write ( const wValue& value );
- std::wstring write_formatted( const wValue& value );
-
-#endif
-
- void write ( const mValue& value, std::ostream& os );
- void write_formatted( const mValue& value, std::ostream& os );
- std::string write ( const mValue& value );
- std::string write_formatted( const mValue& value );
-
-#ifndef BOOST_NO_STD_WSTRING
-
- void write ( const wmValue& value, std::wostream& os );
- void write_formatted( const wmValue& value, std::wostream& os );
- std::wstring write ( const wmValue& value );
- std::wstring write_formatted( const wmValue& value );
-
-#endif
-}
-
-#endif
+#ifndef JSON_SPIRIT_WRITER +#define JSON_SPIRIT_WRITER + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include "json_spirit_value.h" +#include <iostream> + +namespace json_spirit +{ + // functions to convert JSON Values to text, + // the "formatted" versions add whitespace to format the output nicely + + void write ( const Value& value, std::ostream& os ); + void write_formatted( const Value& value, std::ostream& os ); + std::string write ( const Value& value ); + std::string write_formatted( const Value& value ); + +#ifndef BOOST_NO_STD_WSTRING + + void write ( const wValue& value, std::wostream& os ); + void write_formatted( const wValue& value, std::wostream& os ); + std::wstring write ( const wValue& value ); + std::wstring write_formatted( const wValue& value ); + +#endif + + void write ( const mValue& value, std::ostream& os ); + void write_formatted( const mValue& value, std::ostream& os ); + std::string write ( const mValue& value ); + std::string write_formatted( const mValue& value ); + +#ifndef BOOST_NO_STD_WSTRING + + void write ( const wmValue& value, std::wostream& os ); + void write_formatted( const wmValue& value, std::wostream& os ); + std::wstring write ( const wmValue& value ); + std::wstring write_formatted( const wmValue& value ); + +#endif +} + +#endif diff --git a/json/json_spirit_writer_template.h b/json/json_spirit_writer_template.h index c993756555..33bd0ff867 100644 --- a/json/json_spirit_writer_template.h +++ b/json/json_spirit_writer_template.h @@ -1,245 +1,245 @@ -#ifndef JSON_SPIRIT_WRITER_TEMPLATE
-#define JSON_SPIRIT_WRITER_TEMPLATE
-
-// Copyright John W. Wilkinson 2007 - 2009.
-// Distributed under the MIT License, see accompanying file LICENSE.txt
-
-// json spirit version 4.03
-
-#include "json_spirit_value.h"
-
-#include <cassert>
-#include <sstream>
-#include <iomanip>
-
-namespace json_spirit
-{
- inline char to_hex_char( unsigned int c )
- {
- assert( c <= 0xF );
-
- const char ch = static_cast< char >( c );
-
- if( ch < 10 ) return '0' + ch;
-
- return 'A' - 10 + ch;
- }
-
- template< class String_type >
- String_type non_printable_to_string( unsigned int c )
- {
- typedef typename String_type::value_type Char_type;
-
- String_type result( 6, '\\' );
-
- result[1] = 'u';
-
- result[ 5 ] = to_hex_char( c & 0x000F ); c >>= 4;
- result[ 4 ] = to_hex_char( c & 0x000F ); c >>= 4;
- result[ 3 ] = to_hex_char( c & 0x000F ); c >>= 4;
- result[ 2 ] = to_hex_char( c & 0x000F );
-
- return result;
- }
-
- template< typename Char_type, class String_type >
- bool add_esc_char( Char_type c, String_type& s )
- {
- switch( c )
- {
- case '"': s += to_str< String_type >( "\\\"" ); return true;
- case '\\': s += to_str< String_type >( "\\\\" ); return true;
- case '\b': s += to_str< String_type >( "\\b" ); return true;
- case '\f': s += to_str< String_type >( "\\f" ); return true;
- case '\n': s += to_str< String_type >( "\\n" ); return true;
- case '\r': s += to_str< String_type >( "\\r" ); return true;
- case '\t': s += to_str< String_type >( "\\t" ); return true;
- }
-
- return false;
- }
-
- template< class String_type >
- String_type add_esc_chars( const String_type& s )
- {
- typedef typename String_type::const_iterator Iter_type;
- typedef typename String_type::value_type Char_type;
-
- String_type result;
-
- const Iter_type end( s.end() );
-
- for( Iter_type i = s.begin(); i != end; ++i )
- {
- const Char_type c( *i );
-
- if( add_esc_char( c, result ) ) continue;
-
- const wint_t unsigned_c( ( c >= 0 ) ? c : 256 + c );
-
- if( iswprint( unsigned_c ) )
- {
- result += c;
- }
- else
- {
- result += non_printable_to_string< String_type >( unsigned_c );
- }
- }
-
- return result;
- }
-
- // this class generates the JSON text,
- // it keeps track of the indentation level etc.
- //
- template< class Value_type, class Ostream_type >
- class Generator
- {
- typedef typename Value_type::Config_type Config_type;
- typedef typename Config_type::String_type String_type;
- typedef typename Config_type::Object_type Object_type;
- typedef typename Config_type::Array_type Array_type;
- typedef typename String_type::value_type Char_type;
- typedef typename Object_type::value_type Obj_member_type;
-
- public:
-
- Generator( const Value_type& value, Ostream_type& os, bool pretty )
- : os_( os )
- , indentation_level_( 0 )
- , pretty_( pretty )
- {
- output( value );
- }
-
- private:
-
- void output( const Value_type& value )
- {
- switch( value.type() )
- {
- case obj_type: output( value.get_obj() ); break;
- case array_type: output( value.get_array() ); break;
- case str_type: output( value.get_str() ); break;
- case bool_type: output( value.get_bool() ); break;
- case int_type: output_int( value ); break;
- case real_type: os_ << std::showpoint << std::setprecision( 16 )
- << value.get_real(); break;
- case null_type: os_ << "null"; break;
- default: assert( false );
- }
- }
-
- void output( const Object_type& obj )
- {
- output_array_or_obj( obj, '{', '}' );
- }
-
- void output( const Array_type& arr )
- {
- output_array_or_obj( arr, '[', ']' );
- }
-
- void output( const Obj_member_type& member )
- {
- output( Config_type::get_name( member ) ); space();
- os_ << ':'; space();
- output( Config_type::get_value( member ) );
- }
-
- void output_int( const Value_type& value )
- {
- if( value.is_uint64() )
- {
- os_ << value.get_uint64();
- }
- else
- {
- os_ << value.get_int64();
- }
- }
-
- void output( const String_type& s )
- {
- os_ << '"' << add_esc_chars( s ) << '"';
- }
-
- void output( bool b )
- {
- os_ << to_str< String_type >( b ? "true" : "false" );
- }
-
- template< class T >
- void output_array_or_obj( const T& t, Char_type start_char, Char_type end_char )
- {
- os_ << start_char; new_line();
-
- ++indentation_level_;
-
- for( typename T::const_iterator i = t.begin(); i != t.end(); ++i )
- {
- indent(); output( *i );
-
- typename T::const_iterator next = i;
-
- if( ++next != t.end())
- {
- os_ << ',';
- }
-
- new_line();
- }
-
- --indentation_level_;
-
- indent(); os_ << end_char;
- }
-
- void indent()
- {
- if( !pretty_ ) return;
-
- for( int i = 0; i < indentation_level_; ++i )
- {
- os_ << " ";
- }
- }
-
- void space()
- {
- if( pretty_ ) os_ << ' ';
- }
-
- void new_line()
- {
- if( pretty_ ) os_ << '\n';
- }
-
- Generator& operator=( const Generator& ); // to prevent "assignment operator could not be generated" warning
-
- Ostream_type& os_;
- int indentation_level_;
- bool pretty_;
- };
-
- template< class Value_type, class Ostream_type >
- void write_stream( const Value_type& value, Ostream_type& os, bool pretty )
- {
- Generator< Value_type, Ostream_type >( value, os, pretty );
- }
-
- template< class Value_type >
- typename Value_type::String_type write_string( const Value_type& value, bool pretty )
- {
- typedef typename Value_type::String_type::value_type Char_type;
-
- std::basic_ostringstream< Char_type > os;
-
- write_stream( value, os, pretty );
-
- return os.str();
- }
-}
-
-#endif
+#ifndef JSON_SPIRIT_WRITER_TEMPLATE +#define JSON_SPIRIT_WRITER_TEMPLATE + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#include "json_spirit_value.h" + +#include <cassert> +#include <sstream> +#include <iomanip> + +namespace json_spirit +{ + inline char to_hex_char( unsigned int c ) + { + assert( c <= 0xF ); + + const char ch = static_cast< char >( c ); + + if( ch < 10 ) return '0' + ch; + + return 'A' - 10 + ch; + } + + template< class String_type > + String_type non_printable_to_string( unsigned int c ) + { + typedef typename String_type::value_type Char_type; + + String_type result( 6, '\\' ); + + result[1] = 'u'; + + result[ 5 ] = to_hex_char( c & 0x000F ); c >>= 4; + result[ 4 ] = to_hex_char( c & 0x000F ); c >>= 4; + result[ 3 ] = to_hex_char( c & 0x000F ); c >>= 4; + result[ 2 ] = to_hex_char( c & 0x000F ); + + return result; + } + + template< typename Char_type, class String_type > + bool add_esc_char( Char_type c, String_type& s ) + { + switch( c ) + { + case '"': s += to_str< String_type >( "\\\"" ); return true; + case '\\': s += to_str< String_type >( "\\\\" ); return true; + case '\b': s += to_str< String_type >( "\\b" ); return true; + case '\f': s += to_str< String_type >( "\\f" ); return true; + case '\n': s += to_str< String_type >( "\\n" ); return true; + case '\r': s += to_str< String_type >( "\\r" ); return true; + case '\t': s += to_str< String_type >( "\\t" ); return true; + } + + return false; + } + + template< class String_type > + String_type add_esc_chars( const String_type& s ) + { + typedef typename String_type::const_iterator Iter_type; + typedef typename String_type::value_type Char_type; + + String_type result; + + const Iter_type end( s.end() ); + + for( Iter_type i = s.begin(); i != end; ++i ) + { + const Char_type c( *i ); + + if( add_esc_char( c, result ) ) continue; + + const wint_t unsigned_c( ( c >= 0 ) ? c : 256 + c ); + + if( iswprint( unsigned_c ) ) + { + result += c; + } + else + { + result += non_printable_to_string< String_type >( unsigned_c ); + } + } + + return result; + } + + // this class generates the JSON text, + // it keeps track of the indentation level etc. + // + template< class Value_type, class Ostream_type > + class Generator + { + typedef typename Value_type::Config_type Config_type; + typedef typename Config_type::String_type String_type; + typedef typename Config_type::Object_type Object_type; + typedef typename Config_type::Array_type Array_type; + typedef typename String_type::value_type Char_type; + typedef typename Object_type::value_type Obj_member_type; + + public: + + Generator( const Value_type& value, Ostream_type& os, bool pretty ) + : os_( os ) + , indentation_level_( 0 ) + , pretty_( pretty ) + { + output( value ); + } + + private: + + void output( const Value_type& value ) + { + switch( value.type() ) + { + case obj_type: output( value.get_obj() ); break; + case array_type: output( value.get_array() ); break; + case str_type: output( value.get_str() ); break; + case bool_type: output( value.get_bool() ); break; + case int_type: output_int( value ); break; + case real_type: os_ << std::showpoint << std::setprecision( 16 ) + << value.get_real(); break; + case null_type: os_ << "null"; break; + default: assert( false ); + } + } + + void output( const Object_type& obj ) + { + output_array_or_obj( obj, '{', '}' ); + } + + void output( const Array_type& arr ) + { + output_array_or_obj( arr, '[', ']' ); + } + + void output( const Obj_member_type& member ) + { + output( Config_type::get_name( member ) ); space(); + os_ << ':'; space(); + output( Config_type::get_value( member ) ); + } + + void output_int( const Value_type& value ) + { + if( value.is_uint64() ) + { + os_ << value.get_uint64(); + } + else + { + os_ << value.get_int64(); + } + } + + void output( const String_type& s ) + { + os_ << '"' << add_esc_chars( s ) << '"'; + } + + void output( bool b ) + { + os_ << to_str< String_type >( b ? "true" : "false" ); + } + + template< class T > + void output_array_or_obj( const T& t, Char_type start_char, Char_type end_char ) + { + os_ << start_char; new_line(); + + ++indentation_level_; + + for( typename T::const_iterator i = t.begin(); i != t.end(); ++i ) + { + indent(); output( *i ); + + typename T::const_iterator next = i; + + if( ++next != t.end()) + { + os_ << ','; + } + + new_line(); + } + + --indentation_level_; + + indent(); os_ << end_char; + } + + void indent() + { + if( !pretty_ ) return; + + for( int i = 0; i < indentation_level_; ++i ) + { + os_ << " "; + } + } + + void space() + { + if( pretty_ ) os_ << ' '; + } + + void new_line() + { + if( pretty_ ) os_ << '\n'; + } + + Generator& operator=( const Generator& ); // to prevent "assignment operator could not be generated" warning + + Ostream_type& os_; + int indentation_level_; + bool pretty_; + }; + + template< class Value_type, class Ostream_type > + void write_stream( const Value_type& value, Ostream_type& os, bool pretty ) + { + Generator< Value_type, Ostream_type >( value, os, pretty ); + } + + template< class Value_type > + typename Value_type::String_type write_string( const Value_type& value, bool pretty ) + { + typedef typename Value_type::String_type::value_type Char_type; + + std::basic_ostringstream< Char_type > os; + + write_stream( value, os, pretty ); + + return os.str(); + } +} + +#endif @@ -1,168 +1,168 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
-
-
-// secp160k1
-// const unsigned int PRIVATE_KEY_SIZE = 192;
-// const unsigned int PUBLIC_KEY_SIZE = 41;
-// const unsigned int SIGNATURE_SIZE = 48;
-//
-// secp192k1
-// const unsigned int PRIVATE_KEY_SIZE = 222;
-// const unsigned int PUBLIC_KEY_SIZE = 49;
-// const unsigned int SIGNATURE_SIZE = 57;
-//
-// secp224k1
-// const unsigned int PRIVATE_KEY_SIZE = 250;
-// const unsigned int PUBLIC_KEY_SIZE = 57;
-// const unsigned int SIGNATURE_SIZE = 66;
-//
-// secp256k1:
-// const unsigned int PRIVATE_KEY_SIZE = 279;
-// const unsigned int PUBLIC_KEY_SIZE = 65;
-// const unsigned int SIGNATURE_SIZE = 72;
-//
-// see www.keylength.com
-// script supports up to 75 for single byte push
-
-
-
-class key_error : public std::runtime_error
-{
-public:
- explicit key_error(const std::string& str) : std::runtime_error(str) {}
-};
-
-
-// secure_allocator is defined in serialize.h
-typedef vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
-
-
-
-class CKey
-{
-protected:
- EC_KEY* pkey;
- bool fSet;
-
-public:
- CKey()
- {
- pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
- if (pkey == NULL)
- throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed");
- fSet = false;
- }
-
- CKey(const CKey& b)
- {
- pkey = EC_KEY_dup(b.pkey);
- if (pkey == NULL)
- throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed");
- fSet = b.fSet;
- }
-
- CKey& operator=(const CKey& b)
- {
- if (!EC_KEY_copy(pkey, b.pkey))
- throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed");
- fSet = b.fSet;
- return (*this);
- }
-
- ~CKey()
- {
- EC_KEY_free(pkey);
- }
-
- bool IsNull() const
- {
- return !fSet;
- }
-
- void MakeNewKey()
- {
- if (!EC_KEY_generate_key(pkey))
- throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed");
- fSet = true;
- }
-
- bool SetPrivKey(const CPrivKey& vchPrivKey)
- {
- const unsigned char* pbegin = &vchPrivKey[0];
- if (!d2i_ECPrivateKey(&pkey, &pbegin, vchPrivKey.size()))
- return false;
- fSet = true;
- return true;
- }
-
- CPrivKey GetPrivKey() const
- {
- unsigned int nSize = i2d_ECPrivateKey(pkey, NULL);
- if (!nSize)
- throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey failed");
- CPrivKey vchPrivKey(nSize, 0);
- unsigned char* pbegin = &vchPrivKey[0];
- if (i2d_ECPrivateKey(pkey, &pbegin) != nSize)
- throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey returned unexpected size");
- return vchPrivKey;
- }
-
- bool SetPubKey(const vector<unsigned char>& vchPubKey)
- {
- const unsigned char* pbegin = &vchPubKey[0];
- if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size()))
- return false;
- fSet = true;
- return true;
- }
-
- vector<unsigned char> GetPubKey() const
- {
- unsigned int nSize = i2o_ECPublicKey(pkey, NULL);
- if (!nSize)
- throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed");
- vector<unsigned char> vchPubKey(nSize, 0);
- unsigned char* pbegin = &vchPubKey[0];
- if (i2o_ECPublicKey(pkey, &pbegin) != nSize)
- throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size");
- return vchPubKey;
- }
-
- bool Sign(uint256 hash, vector<unsigned char>& vchSig)
- {
- vchSig.clear();
- unsigned char pchSig[10000];
- unsigned int nSize = 0;
- if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), pchSig, &nSize, pkey))
- return false;
- vchSig.resize(nSize);
- memcpy(&vchSig[0], pchSig, nSize);
- return true;
- }
-
- bool Verify(uint256 hash, const vector<unsigned char>& vchSig)
- {
- // -1 = error, 0 = bad sig, 1 = good
- if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1)
- return false;
- return true;
- }
-
- static bool Sign(const CPrivKey& vchPrivKey, uint256 hash, vector<unsigned char>& vchSig)
- {
- CKey key;
- if (!key.SetPrivKey(vchPrivKey))
- return false;
- return key.Sign(hash, vchSig);
- }
-
- static bool Verify(const vector<unsigned char>& vchPubKey, uint256 hash, const vector<unsigned char>& vchSig)
- {
- CKey key;
- if (!key.SetPubKey(vchPubKey))
- return false;
- return key.Verify(hash, vchSig);
- }
-};
+// Copyright (c) 2009-2010 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + + +// secp160k1 +// const unsigned int PRIVATE_KEY_SIZE = 192; +// const unsigned int PUBLIC_KEY_SIZE = 41; +// const unsigned int SIGNATURE_SIZE = 48; +// +// secp192k1 +// const unsigned int PRIVATE_KEY_SIZE = 222; +// const unsigned int PUBLIC_KEY_SIZE = 49; +// const unsigned int SIGNATURE_SIZE = 57; +// +// secp224k1 +// const unsigned int PRIVATE_KEY_SIZE = 250; +// const unsigned int PUBLIC_KEY_SIZE = 57; +// const unsigned int SIGNATURE_SIZE = 66; +// +// secp256k1: +// const unsigned int PRIVATE_KEY_SIZE = 279; +// const unsigned int PUBLIC_KEY_SIZE = 65; +// const unsigned int SIGNATURE_SIZE = 72; +// +// see www.keylength.com +// script supports up to 75 for single byte push + + + +class key_error : public std::runtime_error +{ +public: + explicit key_error(const std::string& str) : std::runtime_error(str) {} +}; + + +// secure_allocator is defined in serialize.h +typedef vector<unsigned char, secure_allocator<unsigned char> > CPrivKey; + + + +class CKey +{ +protected: + EC_KEY* pkey; + bool fSet; + +public: + CKey() + { + pkey = EC_KEY_new_by_curve_name(NID_secp256k1); + if (pkey == NULL) + throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed"); + fSet = false; + } + + CKey(const CKey& b) + { + pkey = EC_KEY_dup(b.pkey); + if (pkey == NULL) + throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed"); + fSet = b.fSet; + } + + CKey& operator=(const CKey& b) + { + if (!EC_KEY_copy(pkey, b.pkey)) + throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed"); + fSet = b.fSet; + return (*this); + } + + ~CKey() + { + EC_KEY_free(pkey); + } + + bool IsNull() const + { + return !fSet; + } + + void MakeNewKey() + { + if (!EC_KEY_generate_key(pkey)) + throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed"); + fSet = true; + } + + bool SetPrivKey(const CPrivKey& vchPrivKey) + { + const unsigned char* pbegin = &vchPrivKey[0]; + if (!d2i_ECPrivateKey(&pkey, &pbegin, vchPrivKey.size())) + return false; + fSet = true; + return true; + } + + CPrivKey GetPrivKey() const + { + unsigned int nSize = i2d_ECPrivateKey(pkey, NULL); + if (!nSize) + throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey failed"); + CPrivKey vchPrivKey(nSize, 0); + unsigned char* pbegin = &vchPrivKey[0]; + if (i2d_ECPrivateKey(pkey, &pbegin) != nSize) + throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey returned unexpected size"); + return vchPrivKey; + } + + bool SetPubKey(const vector<unsigned char>& vchPubKey) + { + const unsigned char* pbegin = &vchPubKey[0]; + if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size())) + return false; + fSet = true; + return true; + } + + vector<unsigned char> GetPubKey() const + { + unsigned int nSize = i2o_ECPublicKey(pkey, NULL); + if (!nSize) + throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed"); + vector<unsigned char> vchPubKey(nSize, 0); + unsigned char* pbegin = &vchPubKey[0]; + if (i2o_ECPublicKey(pkey, &pbegin) != nSize) + throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size"); + return vchPubKey; + } + + bool Sign(uint256 hash, vector<unsigned char>& vchSig) + { + vchSig.clear(); + unsigned char pchSig[10000]; + unsigned int nSize = 0; + if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), pchSig, &nSize, pkey)) + return false; + vchSig.resize(nSize); + memcpy(&vchSig[0], pchSig, nSize); + return true; + } + + bool Verify(uint256 hash, const vector<unsigned char>& vchSig) + { + // -1 = error, 0 = bad sig, 1 = good + if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1) + return false; + return true; + } + + static bool Sign(const CPrivKey& vchPrivKey, uint256 hash, vector<unsigned char>& vchSig) + { + CKey key; + if (!key.SetPrivKey(vchPrivKey)) + return false; + return key.Sign(hash, vchSig); + } + + static bool Verify(const vector<unsigned char>& vchPubKey, uint256 hash, const vector<unsigned char>& vchSig) + { + CKey key; + if (!key.SetPubKey(vchPubKey)) + return false; + return key.Verify(hash, vchSig); + } +}; diff --git a/license.txt b/license.txt index f96fa98f4c..ed7435014b 100644 --- a/license.txt +++ b/license.txt @@ -1,19 +1,19 @@ -Copyright (c) 2009-2010 Satoshi Nakamoto
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
+Copyright (c) 2009-2010 Satoshi Nakamoto + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/locale/pt/LC_MESSAGES/bitcoin.po b/locale/pt/LC_MESSAGES/bitcoin.po index b6aceff724..827f14a5ac 100644 --- a/locale/pt/LC_MESSAGES/bitcoin.po +++ b/locale/pt/LC_MESSAGES/bitcoin.po @@ -1,807 +1,807 @@ -msgid ""
-msgstr ""
-"Project-Id-Version: \n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-05-26 22:02-0000\n"
-"PO-Revision-Date: 2010-07-05 09:06+0100\n"
-"Last-Translator: Tiago Faria\n"
-"Language-Team: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Poedit-KeywordsList: _;gettext;gettext_noop\n"
-"X-Poedit-Basepath: .\n"
-"X-Poedit-SearchPath-0: ../../..\n"
-
-#: ../../../init.cpp:342
-msgid "Usage: bitcoin [options]"
-msgstr "Utilização Bitcoin [opções]"
-
-#: ../../../init.cpp:343
-msgid "Options:\n"
-msgstr "Opções:\n"
-
-#: ../../../init.cpp:344
-msgid "Generate coins\n"
-msgstr "Gerar moedas\n"
-
-#: ../../../init.cpp:345
-msgid "Don't generate coins\n"
-msgstr "Não gerar moedas\n"
-
-#: ../../../init.cpp:346
-msgid "Start minimized\n"
-msgstr "Iniciar minimizado\n"
-
-#: ../../../init.cpp:347
-msgid "Specify data directory\n"
-msgstr "Especificar localização dos dados\n"
-
-#: ../../../init.cpp:348
-msgid "Connect through socks4 proxy\n"
-msgstr "Ligar através de um proxy socks4\n"
-
-#: ../../../init.cpp:349
-msgid "Add a node to connect to\n"
-msgstr "Adicionar um nó para efectuar ligação\n"
-
-#: ../../../init.cpp:350
-msgid "Connect only to the specified node\n"
-msgstr "Ligar apenas ao nó especificado\n"
-
-#: ../../../init.cpp:351
-msgid "This help message\n"
-msgstr "Esta mensagem de ajuda\n"
-
-#: ../../../init.cpp:455
-msgid "Error loading addr.dat \n"
-msgstr "Erro ao carregar addr.dat \n"
-
-#: ../../../init.cpp:461
-msgid "Error loading blkindex.dat \n"
-msgstr "Erro ao carregar blkindex.dat \n"
-
-#: ../../../init.cpp:468
-msgid "Error loading wallet.dat \n"
-msgstr "Erro ao carregar wallet.dat \n"
-
-#: ../../../init.cpp:536
-msgid "Invalid -proxy address"
-msgstr "Endereço -proxy inválido"
-
-#: ../../../init.cpp:629
-msgid "Program has crashed and will terminate. "
-msgstr "A aplicação bloqueou e vai terminar. "
-
-#: ../../../main.cpp:1465
-msgid "Warning: Disk space is low "
-msgstr "Aviso: Espaço em disco limitado "
-
-#: ../../../main.cpp:2994
-#, c-format
-msgid "Error: This is an oversized transaction that requires a transaction fee of %s "
-msgstr "Erro: Esta transacção necessita de uma percentagem de transferência no valor de %s "
-
-#: ../../../main.cpp:2996
-msgid "Error: Transaction creation failed "
-msgstr "Erro: Criação da transacção falhou "
-
-#: ../../../main.cpp:3001
-#: ../../../ui.cpp:1761
-#: ../../../ui.cpp:1763
-#: ../../../ui.cpp:1904
-#: ../../../ui.cpp:2053
-msgid "Sending..."
-msgstr "A enviar ..."
-
-#: ../../../main.cpp:3005
-msgid "Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."
-msgstr "Erro: A transacção foi rejeitada. Isto pode acontecer se algumas das moedas na sua carteira já tenham sido gastas, como por exemplo na utilização de uma cópia do wallet.dat onde as moedas foram gastas na cópia mas não aqui."
-
-#: ../../../main.cpp:3017
-msgid "Invalid amount"
-msgstr "Montante inválido"
-
-#: ../../../main.cpp:3019
-#: ../../../ui.cpp:1971
-#: ../../../ui.cpp:2038
-msgid "Insufficient funds"
-msgstr "Fundos insuficientes"
-
-#: ../../../main.cpp:3024
-msgid "Invalid bitcoin address"
-msgstr "Endereço Bitcoin inválido"
-
-#: ../../../ui.cpp:189
-#, c-format
-msgid "This transaction is over the size limit. You can still send it for a fee of %s, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee?"
-msgstr "Esta transacção ultrapassa o limite. Pode, mesmo assim, efectuá-la, no entanto, uma percentagem de %s será enviada para os nós da rede que processam este pagamento. Quer pagar a percentagem?"
-
-#: ../../../ui.cpp:285
-msgid "Status"
-msgstr "Estado"
-
-#: ../../../ui.cpp:286
-msgid "Date"
-msgstr "Data"
-
-#: ../../../ui.cpp:287
-msgid "Description"
-msgstr "Descrição"
-
-#: ../../../ui.cpp:288
-msgid "Debit"
-msgstr "Débito"
-
-#: ../../../ui.cpp:289
-msgid "Credit"
-msgstr "Crédito"
-
-#: ../../../ui.cpp:489
-#, c-format
-msgid "Open for %d blocks"
-msgstr "Aberto para %d blocos"
-
-#: ../../../ui.cpp:491
-#, c-format
-msgid "Open until %s"
-msgstr "Aberto até %s"
-
-#: ../../../ui.cpp:497
-#, c-format
-msgid "%d/offline?"
-msgstr "%d/offline?"
-
-#: ../../../ui.cpp:499
-#, c-format
-msgid "%d/unconfirmed"
-msgstr "%d/não confirmado"
-
-#: ../../../ui.cpp:501
-#, c-format
-msgid "%d confirmations"
-msgstr "%d confirmados"
-
-#: ../../../ui.cpp:584
-msgid "Generated"
-msgstr "Gerado"
-
-#: ../../../ui.cpp:592
-#, c-format
-msgid "Generated (%s matures in %d more blocks)"
-msgstr "Gerado (%s maduras em mais %d blocos)"
-
-#: ../../../ui.cpp:596
-msgid "Generated - Warning: This block was not received by any other nodes and will probably not be accepted!"
-msgstr "Gerado - Aviso: Este bloco não foi recebido por mais nenhum nó da rede e provavelmente não será aceite."
-
-#: ../../../ui.cpp:600
-msgid "Generated (not accepted)"
-msgstr "Gerado (não aceite)"
-
-#: ../../../ui.cpp:610
-msgid "From: "
-msgstr "Remetente: "
-
-#: ../../../ui.cpp:634
-msgid "From: unknown, Received with: "
-msgstr "Remetente: desconhecido, Recebido por: "
-
-#: ../../../ui.cpp:676
-msgid "Payment to yourself"
-msgstr "Pagamento ao próprio"
-
-#: ../../../ui.cpp:713
-msgid "To: "
-msgstr "Destinatário: "
-
-#: ../../../ui.cpp:1009
-msgid " Generating"
-msgstr " A gerar"
-
-#: ../../../ui.cpp:1011
-msgid "(not connected)"
-msgstr "(sem ligação)"
-
-#: ../../../ui.cpp:1014
-#, c-format
-msgid " %d connections %d blocks %d transactions"
-msgstr " %d ligações %d blocos %d transacções"
-
-#: ../../../ui.cpp:1123
-#: ../../../ui.cpp:2351
-msgid "New Receiving Address"
-msgstr "Novo Endereço de Recepção"
-
-#: ../../../ui.cpp:1124
-#: ../../../ui.cpp:2352
-msgid ""
-"It's good policy to use a new address for each payment you receive.\n"
-"\n"
-"Label"
-msgstr ""
-"É uma boa polÃtica utilizar um endereço diferente para cada pagamento que recebe.\n"
-"\n"
-"Etiqueta"
-
-#: ../../../ui.cpp:1193
-msgid "<b>Status:</b> "
-msgstr "<b>Estado:</b> "
-
-#: ../../../ui.cpp:1198
-msgid ", has not been successfully broadcast yet"
-msgstr ", ainda não foram anunciadas com sucesso"
-
-#: ../../../ui.cpp:1200
-#, c-format
-msgid ", broadcast through %d node"
-msgstr ", anunciar por %d nó"
-
-#: ../../../ui.cpp:1202
-#, c-format
-msgid ", broadcast through %d nodes"
-msgstr ", anunciar por %d nós"
-
-#: ../../../ui.cpp:1206
-msgid "<b>Date:</b> "
-msgstr "<b>Data:</b> "
-
-#: ../../../ui.cpp:1214
-msgid "<b>Source:</b> Generated<br>"
-msgstr "<b>Fonte:</b> Gerado<br>"
-
-#: ../../../ui.cpp:1220
-#: ../../../ui.cpp:1238
-msgid "<b>From:</b> "
-msgstr "<b>Remetente:</b> "
-
-#: ../../../ui.cpp:1238
-msgid "unknown"
-msgstr "desconhecido"
-
-#: ../../../ui.cpp:1239
-#: ../../../ui.cpp:1263
-#: ../../../ui.cpp:1322
-msgid "<b>To:</b> "
-msgstr "<b>Destinatário:</b> "
-
-#: ../../../ui.cpp:1242
-msgid " (yours, label: "
-msgstr " (seu, etiqueta: "
-
-#: ../../../ui.cpp:1244
-msgid " (yours)"
-msgstr " (seu)"
-
-#: ../../../ui.cpp:1281
-#: ../../../ui.cpp:1293
-#: ../../../ui.cpp:1356
-msgid "<b>Credit:</b> "
-msgstr "<b>Crédito:</b> "
-
-#: ../../../ui.cpp:1283
-#, c-format
-msgid "(%s matures in %d more blocks)"
-msgstr "(%s maduras em mais %d blocos)"
-
-#: ../../../ui.cpp:1285
-msgid "(not accepted)"
-msgstr "(não aceite)"
-
-#: ../../../ui.cpp:1330
-#: ../../../ui.cpp:1353
-msgid "<b>Debit:</b> "
-msgstr "<b>Débito:</b> "
-
-#: ../../../ui.cpp:1344
-msgid "<b>Transaction fee:</b> "
-msgstr "<b>Percentagem da transacção:</b> "
-
-#: ../../../ui.cpp:1360
-msgid "<b>Net amount:</b> "
-msgstr "<b>Quantia Net:</b> "
-
-#: ../../../ui.cpp:1367
-msgid "Message:"
-msgstr "Mensagem:"
-
-#: ../../../ui.cpp:1370
-msgid "Generated coins must wait 120 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, it will change to \"not accepted\" and not be spendable. This may occasionally happen if another node generates a block within a few seconds of yours."
-msgstr "As moedas geradas necessitam de 120 blocos para que possam ser gastas. Quando gera um bloco, ele será anunciado pela rede para ser adicionado à cadeia de blocos. Se falhar, mudará para \"não aceite\" e não será possÃvel utilizá-lo. Isto pode acontecer se um nó gerar outro bloco após alguns segundos do seu."
-
-#: ../../../ui.cpp:1437
-msgid "Main"
-msgstr "Principal"
-
-#: ../../../ui.cpp:1442
-msgid "&Minimize on close"
-msgstr "&Minimizar ao fechar"
-
-#: ../../../ui.cpp:1595
-#, c-format
-msgid "version 0.%d.%d beta"
-msgstr "versão 0.%d.%d beta"
-
-#: ../../../ui.cpp:1681
-msgid "Will appear as \"From: Unknown\""
-msgstr "Irá aparecer como \"De: Desconhecido\""
-
-#: ../../../ui.cpp:1682
-msgid "Can't include a message when sending to a Bitcoin address"
-msgstr "Não é possÃvel incluir uma mensagem ao enviar para um endereço Bitcoin"
-
-#: ../../../ui.cpp:1735
-msgid "Error in amount "
-msgstr "Erro na quantia "
-
-#: ../../../ui.cpp:1735
-#: ../../../ui.cpp:1740
-#: ../../../ui.cpp:1745
-#: ../../../ui.cpp:1771
-#: ../../../uibase.cpp:61
-msgid "Send Coins"
-msgstr "Enviar Moedas"
-
-#: ../../../ui.cpp:1740
-msgid "Amount exceeds your balance "
-msgstr "A quantia excede o seu saldo "
-
-#: ../../../ui.cpp:1745
-msgid "Total exceeds your balance when the "
-msgstr "O total excede o seu saldo quando a "
-
-#: ../../../ui.cpp:1745
-msgid " transaction fee is included "
-msgstr " taxa de transacção for incluÃda "
-
-#: ../../../ui.cpp:1761
-msgid "Payment sent "
-msgstr "Pagamento enviado "
-
-#: ../../../ui.cpp:1771
-msgid "Invalid address "
-msgstr "Endereço inválido "
-
-#: ../../../ui.cpp:1825
-#, c-format
-msgid "Sending %s to %s"
-msgstr "A enviar %s para %s"
-
-#: ../../../ui.cpp:1898
-#: ../../../ui.cpp:1931
-msgid "CANCELLED"
-msgstr "CANCELADO"
-
-#: ../../../ui.cpp:1902
-msgid "Cancelled"
-msgstr "Cancelado"
-
-#: ../../../ui.cpp:1904
-msgid "Transfer cancelled "
-msgstr "Transferência cancelada "
-
-#: ../../../ui.cpp:1957
-msgid "Error: "
-msgstr "Erro: "
-
-#: ../../../ui.cpp:1976
-msgid "Connecting..."
-msgstr "A estabelecer ligação ..."
-
-#: ../../../ui.cpp:1981
-msgid "Unable to connect"
-msgstr "ImpossÃvel estabelecer ligação"
-
-#: ../../../ui.cpp:1986
-msgid "Requesting public key..."
-msgstr "A requisitar a chave pública ..."
-
-#: ../../../ui.cpp:1998
-msgid "Received public key..."
-msgstr "Chave pública recebida"
-
-#: ../../../ui.cpp:2010
-msgid "Transfer was not accepted"
-msgstr "A transferência não foi aceite"
-
-#: ../../../ui.cpp:2019
-msgid "Invalid response received"
-msgstr "Resposta inválida recebida"
-
-#: ../../../ui.cpp:2034
-msgid "Creating transaction..."
-msgstr "A criar a transacção ..."
-
-#: ../../../ui.cpp:2046
-#, c-format
-msgid "This is an oversized transaction that requires a transaction fee of %s"
-msgstr "Esta transferência requer o pagamento de uma taxa de transacção de %s"
-
-#: ../../../ui.cpp:2048
-msgid "Transaction creation failed"
-msgstr "A criação da transacção falhou"
-
-#: ../../../ui.cpp:2055
-msgid "Transaction aborted"
-msgstr "Transacção cancelada"
-
-#: ../../../ui.cpp:2063
-msgid "Lost connection, transaction cancelled"
-msgstr "Perca de ligação, transacção cancelada"
-
-#: ../../../ui.cpp:2079
-msgid "Sending payment..."
-msgstr "A enviar pagamento ..."
-
-#: ../../../ui.cpp:2085
-msgid "The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."
-msgstr "A transacção foi rejeitada. Isto pode acontecer se algumas das moedas na sua carteira já foram utilizadas, como na utilização de uma cópia do wallet.dat, onde as moedas foram utilizadas na cópia do ficheiro e essas alterações não reflectem o estado desta carteira."
-
-#: ../../../ui.cpp:2092
-msgid "Waiting for confirmation..."
-msgstr "A aguardar confirmação ..."
-
-#: ../../../ui.cpp:2110
-msgid ""
-"The payment was sent, but the recipient was unable to verify it.\n"
-"The transaction is recorded and will credit to the recipient,\n"
-"but the comment information will be blank."
-msgstr ""
-"O pagamento foi enviado, mas o remetente não consegiu verificar o seu pagamento.\n"
-"A transacção foi entregue, e o remetente receberá as modeas,\n"
-"no entanto, o comentário de transacção estará vazio."
-
-#: ../../../ui.cpp:2119
-msgid "Payment was sent, but an invalid response was received"
-msgstr "O pagamento foi enviado, mas foi recebida uma resposta inválida"
-
-#: ../../../ui.cpp:2125
-msgid "Payment completed"
-msgstr "Pagamento completo"
-
-#: ../../../ui.cpp:2156
-#: ../../../ui.cpp:2302
-#: ../../../ui.cpp:2339
-msgid "Name"
-msgstr "Nome"
-
-#: ../../../ui.cpp:2157
-#: ../../../ui.cpp:2302
-#: ../../../ui.cpp:2339
-msgid "Address"
-msgstr "Endereço"
-
-#: ../../../ui.cpp:2159
-#: ../../../ui.cpp:2314
-msgid "Label"
-msgstr "Nota"
-
-#: ../../../ui.cpp:2160
-#: ../../../uibase.cpp:908
-msgid "Bitcoin Address"
-msgstr "Endereço Bitcoin"
-
-#: ../../../ui.cpp:2284
-msgid "This is one of your own addresses for receiving payments and cannot be entered in the address book. "
-msgstr "Este endereço é seu (onde recebe pagamentos) e não pode ser introduzido no seu livros de endereços. "
-
-#: ../../../ui.cpp:2302
-#: ../../../ui.cpp:2308
-msgid "Edit Address"
-msgstr "Editar endereço"
-
-#: ../../../ui.cpp:2314
-msgid "Edit Address Label"
-msgstr "Editar nota de endereço"
-
-#: ../../../ui.cpp:2339
-#: ../../../ui.cpp:2345
-msgid "Add Address"
-msgstr "Adicionar endereço"
-
-#: ../../../ui.cpp:2421
-msgid "Bitcoin"
-msgstr "Bitcoin"
-
-#: ../../../ui.cpp:2423
-msgid "Bitcoin - Generating"
-msgstr "Bitcoin - A gerar"
-
-#: ../../../ui.cpp:2425
-msgid "Bitcoin - (not connected)"
-msgstr "Bitcoin - (sem ligação)"
-
-#: ../../../ui.cpp:2500
-msgid "&Open Bitcoin"
-msgstr "&Abrir Bitcoin"
-
-#: ../../../ui.cpp:2501
-msgid "O&ptions..."
-msgstr "O&pções"
-
-#: ../../../ui.cpp:2502
-#: ../../../uibase.cpp:34
-msgid "&Generate Coins"
-msgstr "&Gerar Moedas"
-
-#: ../../../ui.cpp:2505
-#: ../../../uibase.cpp:27
-msgid "E&xit"
-msgstr "S&air"
-
-#: ../../../uibase.cpp:30
-msgid "&File"
-msgstr "&Ficheiro"
-
-#: ../../../uibase.cpp:38
-msgid "&Your Receiving Addresses..."
-msgstr "&Os seus endereços"
-
-#: ../../../uibase.cpp:42
-msgid "&Options..."
-msgstr "&Opções ..."
-
-#: ../../../uibase.cpp:45
-msgid "&Settings"
-msgstr "&Definições"
-
-#: ../../../uibase.cpp:49
-msgid "&About..."
-msgstr "&Sobre ..."
-
-#: ../../../uibase.cpp:52
-msgid "&Help"
-msgstr "&Ajuda"
-
-#: ../../../uibase.cpp:62
-msgid "Address Book"
-msgstr "Livro de Endereços"
-
-#: ../../../uibase.cpp:77
-msgid "Your Bitcoin Address:"
-msgstr "O seu endereço Bitcoin:"
-
-#: ../../../uibase.cpp:84
-msgid " &New... "
-msgstr " &Novo ... "
-
-#: ../../../uibase.cpp:87
-#: ../../../uibase.cpp:851
-#: ../../../uibase.cpp:954
-msgid " &Copy to Clipboard "
-msgstr " &Copiar para o Clipboard "
-
-#: ../../../uibase.cpp:102
-msgid "Balance:"
-msgstr "Saldo:"
-
-#: ../../../uibase.cpp:121
-msgid " All"
-msgstr " Todos"
-
-#: ../../../uibase.cpp:121
-msgid " Sent"
-msgstr " Enviado"
-
-#: ../../../uibase.cpp:121
-msgid " Received"
-msgstr " Recebido"
-
-#: ../../../uibase.cpp:121
-msgid " In Progress"
-msgstr " Em progresso"
-
-#: ../../../uibase.cpp:142
-msgid "All Transactions"
-msgstr "Todas as transacções"
-
-#: ../../../uibase.cpp:153
-msgid "Sent/Received"
-msgstr "Enviadas/Recebidas"
-
-#: ../../../uibase.cpp:164
-msgid "Sent"
-msgstr "Enviado"
-
-#: ../../../uibase.cpp:175
-msgid "Received"
-msgstr "Recebido"
-
-#: ../../../uibase.cpp:318
-#: ../../../uibase.cpp:479
-#: ../../../uibase.cpp:580
-#: ../../../uibase.cpp:793
-#: ../../../uibase.cpp:854
-#: ../../../uibase.cpp:963
-#: ../../../uibase.cpp:1052
-msgid "OK"
-msgstr "OK"
-
-#: ../../../uibase.cpp:361
-msgid "Optional transaction fee you give to the nodes that process your transactions."
-msgstr "Pagamento de taxa de transacção opcional que é entregue aos nós que ajudam a processar o seu pagamento"
-
-#: ../../../uibase.cpp:370
-msgid "Transaction fee:"
-msgstr "Taxa de transacção:"
-
-#: ../../../uibase.cpp:386
-msgid "&Limit coin generation to"
-msgstr "&Limitar a geração de moedas a"
-
-#: ../../../uibase.cpp:393
-msgid "processors"
-msgstr "processadores"
-
-#: ../../../uibase.cpp:399
-msgid "&Start Bitcoin on system startup"
-msgstr "&Iniciar o Bitcoin no arranque do sistema"
-
-#: ../../../uibase.cpp:403
-msgid "&Minimize to the tray instead of the taskbar"
-msgstr "&Minimizar para a zona do relógio em vez da barra de janelas"
-
-#: ../../../uibase.cpp:407
-msgid "M&inimize to the tray on close"
-msgstr "M&inimizar para a zona do relógio ao fechar"
-
-#: ../../../uibase.cpp:414
-msgid "&Connect through socks4 proxy: "
-msgstr "&Ligar através de um prozy socks4: "
-
-#: ../../../uibase.cpp:426
-msgid "Proxy &IP:"
-msgstr "Proxy &IP:"
-
-#: ../../../uibase.cpp:434
-msgid " &Port:"
-msgstr " &Porto:"
-
-#: ../../../uibase.cpp:456
-msgid "// [don't translate] Test panel 2 for future expansion"
-msgstr ""
-
-#: ../../../uibase.cpp:460
-msgid "// [don't translate] Let's not start multiple pages until the first page is filled up"
-msgstr ""
-
-#: ../../../uibase.cpp:482
-#: ../../../uibase.cpp:735
-#: ../../../uibase.cpp:798
-#: ../../../uibase.cpp:857
-#: ../../../uibase.cpp:966
-#: ../../../uibase.cpp:1055
-msgid "Cancel"
-msgstr "Cancelar"
-
-#: ../../../uibase.cpp:485
-msgid "&Apply"
-msgstr "&Aplicar"
-
-#: ../../../uibase.cpp:546
-msgid "Bitcoin "
-msgstr "Bitcoin "
-
-#: ../../../uibase.cpp:552
-msgid "version"
-msgstr "versão"
-
-#: ../../../uibase.cpp:563
-msgid ""
-"Copyright (c) 2009-2010 Satoshi Nakamoto.\n"
-"\n"
-"This is experimental software.\n"
-"\n"
-"Distributed under the MIT/X11 software license, see the accompanying file \n"
-"license.txt or http://www.opensource.org/licenses/mit-license.php.\n"
-"\n"
-"This product includes software developed by the OpenSSL Project for use in the \n"
-"OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by \n"
-"Eric Young (eay@cryptsoft.com)."
-msgstr ""
-"Copyright (c) 2009-2010 Satoshi Nakamoto.\n"
-"\n"
-"Este software é experimental.\n"
-"\n"
-"DistribuÃdo sob a licença de software MIT/X11. Veja os seguintes ficheiros \n"
-"para mais informações license.txt ou \n"
-"http://www.opensource.org/licenses/mit-license.php.\n"
-"Este producto inclui software desenvolvido pelo projecto OpenSSL, para \n"
-"ser utilizado no OpenSSL Toolkit (http://www.openssl.org) e software de \n"
-"criptografia desenvolvido por Eric Young (eay@cryptsoft.com)."
-
-#: ../../../uibase.cpp:619
-msgid "Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJED9L) or IP address (e.g. 123.45.6.7)"
-msgstr "Introduza um endereço Bitcoin (exemplo: 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJED9L) ou um endereço de IP (exemplo: 123.45.6.7)"
-
-#: ../../../uibase.cpp:633
-msgid "Pay &To:"
-msgstr "Pagar &a:"
-
-#: ../../../uibase.cpp:648
-msgid "&Paste"
-msgstr "&Colar"
-
-#: ../../../uibase.cpp:651
-msgid " Address &Book..."
-msgstr " Livro de endereços ..."
-
-#: ../../../uibase.cpp:658
-msgid "&Amount:"
-msgstr "&Quantia:"
-
-#: ../../../uibase.cpp:668
-msgid "T&ransfer:"
-msgstr "T&ransferência:"
-
-#: ../../../uibase.cpp:674
-msgid " Standard"
-msgstr " Standard"
-
-#: ../../../uibase.cpp:696
-msgid "&From:"
-msgstr "&De:"
-
-#: ../../../uibase.cpp:713
-msgid "&Message:"
-msgstr "&Mensagem:"
-
-#: ../../../uibase.cpp:730
-msgid "&Send"
-msgstr "&Enviar"
-
-#: ../../../uibase.cpp:782
-msgid ""
-"\n"
-"\n"
-"Connecting..."
-msgstr ""
-"\n"
-"\n"
-"A estabelecer ligação ..."
-
-#: ../../../uibase.cpp:832
-msgid "These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. The highlighted address is displayed in the main window."
-msgstr "Estes são os seus endereços de Bitcoin onde poderá receber os seus pagamentos. Pode dar um endereço diferente a cada pessoa ou identidade para ter uma melhor ideia sobre quem o está a pagar. O endereço seleccionado será o que aparecerá na janela principal."
-
-#: ../../../uibase.cpp:845
-#: ../../../uibase.cpp:957
-msgid "&Edit..."
-msgstr "&Editar ..."
-
-#: ../../../uibase.cpp:848
-#: ../../../uibase.cpp:960
-msgid " &New Address... "
-msgstr " &Novo endereço ... "
-
-#: ../../../uibase.cpp:920
-msgid "Sending"
-msgstr "A enviar"
-
-#: ../../../uibase.cpp:928
-msgid "These are your Bitcoin addresses for receiving payments. You can give a different one to each sender to keep track of who is paying you. The highlighted address will be displayed in the main window."
-msgstr "Estes são os seus endereços de Bitcoin onde poderá receber os seus pagamentos. Pode dar um endereço diferente a cada pessoa ou identidade para ter uma melhor ideia sobre quem o está a pagar. O endereço seleccionado será o que aparecerá na janela principal."
-
-#: ../../../uibase.cpp:941
-msgid "Receiving"
-msgstr "A receber"
-
-#: ../../../uibase.cpp:951
-msgid "&Delete"
-msgstr "&Remover"
-
-#: ../../../uibase.h:150
-msgid "Transaction Details"
-msgstr "Detalhes da transacção"
-
-#: ../../../uibase.h:203
-msgid "Options"
-msgstr "Opções"
-
-#: ../../../uibase.h:231
-msgid "About Bitcoin"
-msgstr "Sobre o Bitcoin"
-
-#: ../../../uibase.h:341
-msgid "Your Bitcoin Addresses"
-msgstr "O seu endereço de Bitcoin"
+msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2010-05-26 22:02-0000\n" +"PO-Revision-Date: 2010-07-05 09:06+0100\n" +"Last-Translator: Tiago Faria\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-KeywordsList: _;gettext;gettext_noop\n" +"X-Poedit-Basepath: .\n" +"X-Poedit-SearchPath-0: ../../..\n" + +#: ../../../init.cpp:342 +msgid "Usage: bitcoin [options]" +msgstr "Utilização Bitcoin [opções]" + +#: ../../../init.cpp:343 +msgid "Options:\n" +msgstr "Opções:\n" + +#: ../../../init.cpp:344 +msgid "Generate coins\n" +msgstr "Gerar moedas\n" + +#: ../../../init.cpp:345 +msgid "Don't generate coins\n" +msgstr "Não gerar moedas\n" + +#: ../../../init.cpp:346 +msgid "Start minimized\n" +msgstr "Iniciar minimizado\n" + +#: ../../../init.cpp:347 +msgid "Specify data directory\n" +msgstr "Especificar localização dos dados\n" + +#: ../../../init.cpp:348 +msgid "Connect through socks4 proxy\n" +msgstr "Ligar através de um proxy socks4\n" + +#: ../../../init.cpp:349 +msgid "Add a node to connect to\n" +msgstr "Adicionar um nó para efectuar ligação\n" + +#: ../../../init.cpp:350 +msgid "Connect only to the specified node\n" +msgstr "Ligar apenas ao nó especificado\n" + +#: ../../../init.cpp:351 +msgid "This help message\n" +msgstr "Esta mensagem de ajuda\n" + +#: ../../../init.cpp:455 +msgid "Error loading addr.dat \n" +msgstr "Erro ao carregar addr.dat \n" + +#: ../../../init.cpp:461 +msgid "Error loading blkindex.dat \n" +msgstr "Erro ao carregar blkindex.dat \n" + +#: ../../../init.cpp:468 +msgid "Error loading wallet.dat \n" +msgstr "Erro ao carregar wallet.dat \n" + +#: ../../../init.cpp:536 +msgid "Invalid -proxy address" +msgstr "Endereço -proxy inválido" + +#: ../../../init.cpp:629 +msgid "Program has crashed and will terminate. " +msgstr "A aplicação bloqueou e vai terminar. " + +#: ../../../main.cpp:1465 +msgid "Warning: Disk space is low " +msgstr "Aviso: Espaço em disco limitado " + +#: ../../../main.cpp:2994 +#, c-format +msgid "Error: This is an oversized transaction that requires a transaction fee of %s " +msgstr "Erro: Esta transacção necessita de uma percentagem de transferência no valor de %s " + +#: ../../../main.cpp:2996 +msgid "Error: Transaction creation failed " +msgstr "Erro: Criação da transacção falhou " + +#: ../../../main.cpp:3001 +#: ../../../ui.cpp:1761 +#: ../../../ui.cpp:1763 +#: ../../../ui.cpp:1904 +#: ../../../ui.cpp:2053 +msgid "Sending..." +msgstr "A enviar ..." + +#: ../../../main.cpp:3005 +msgid "Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here." +msgstr "Erro: A transacção foi rejeitada. Isto pode acontecer se algumas das moedas na sua carteira já tenham sido gastas, como por exemplo na utilização de uma cópia do wallet.dat onde as moedas foram gastas na cópia mas não aqui." + +#: ../../../main.cpp:3017 +msgid "Invalid amount" +msgstr "Montante inválido" + +#: ../../../main.cpp:3019 +#: ../../../ui.cpp:1971 +#: ../../../ui.cpp:2038 +msgid "Insufficient funds" +msgstr "Fundos insuficientes" + +#: ../../../main.cpp:3024 +msgid "Invalid bitcoin address" +msgstr "Endereço Bitcoin inválido" + +#: ../../../ui.cpp:189 +#, c-format +msgid "This transaction is over the size limit. You can still send it for a fee of %s, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee?" +msgstr "Esta transacção ultrapassa o limite. Pode, mesmo assim, efectuá-la, no entanto, uma percentagem de %s será enviada para os nós da rede que processam este pagamento. Quer pagar a percentagem?" + +#: ../../../ui.cpp:285 +msgid "Status" +msgstr "Estado" + +#: ../../../ui.cpp:286 +msgid "Date" +msgstr "Data" + +#: ../../../ui.cpp:287 +msgid "Description" +msgstr "Descrição" + +#: ../../../ui.cpp:288 +msgid "Debit" +msgstr "Débito" + +#: ../../../ui.cpp:289 +msgid "Credit" +msgstr "Crédito" + +#: ../../../ui.cpp:489 +#, c-format +msgid "Open for %d blocks" +msgstr "Aberto para %d blocos" + +#: ../../../ui.cpp:491 +#, c-format +msgid "Open until %s" +msgstr "Aberto até %s" + +#: ../../../ui.cpp:497 +#, c-format +msgid "%d/offline?" +msgstr "%d/offline?" + +#: ../../../ui.cpp:499 +#, c-format +msgid "%d/unconfirmed" +msgstr "%d/não confirmado" + +#: ../../../ui.cpp:501 +#, c-format +msgid "%d confirmations" +msgstr "%d confirmados" + +#: ../../../ui.cpp:584 +msgid "Generated" +msgstr "Gerado" + +#: ../../../ui.cpp:592 +#, c-format +msgid "Generated (%s matures in %d more blocks)" +msgstr "Gerado (%s maduras em mais %d blocos)" + +#: ../../../ui.cpp:596 +msgid "Generated - Warning: This block was not received by any other nodes and will probably not be accepted!" +msgstr "Gerado - Aviso: Este bloco não foi recebido por mais nenhum nó da rede e provavelmente não será aceite." + +#: ../../../ui.cpp:600 +msgid "Generated (not accepted)" +msgstr "Gerado (não aceite)" + +#: ../../../ui.cpp:610 +msgid "From: " +msgstr "Remetente: " + +#: ../../../ui.cpp:634 +msgid "From: unknown, Received with: " +msgstr "Remetente: desconhecido, Recebido por: " + +#: ../../../ui.cpp:676 +msgid "Payment to yourself" +msgstr "Pagamento ao próprio" + +#: ../../../ui.cpp:713 +msgid "To: " +msgstr "Destinatário: " + +#: ../../../ui.cpp:1009 +msgid " Generating" +msgstr " A gerar" + +#: ../../../ui.cpp:1011 +msgid "(not connected)" +msgstr "(sem ligação)" + +#: ../../../ui.cpp:1014 +#, c-format +msgid " %d connections %d blocks %d transactions" +msgstr " %d ligações %d blocos %d transacções" + +#: ../../../ui.cpp:1123 +#: ../../../ui.cpp:2351 +msgid "New Receiving Address" +msgstr "Novo Endereço de Recepção" + +#: ../../../ui.cpp:1124 +#: ../../../ui.cpp:2352 +msgid "" +"It's good policy to use a new address for each payment you receive.\n" +"\n" +"Label" +msgstr "" +"É uma boa polÃtica utilizar um endereço diferente para cada pagamento que recebe.\n" +"\n" +"Etiqueta" + +#: ../../../ui.cpp:1193 +msgid "<b>Status:</b> " +msgstr "<b>Estado:</b> " + +#: ../../../ui.cpp:1198 +msgid ", has not been successfully broadcast yet" +msgstr ", ainda não foram anunciadas com sucesso" + +#: ../../../ui.cpp:1200 +#, c-format +msgid ", broadcast through %d node" +msgstr ", anunciar por %d nó" + +#: ../../../ui.cpp:1202 +#, c-format +msgid ", broadcast through %d nodes" +msgstr ", anunciar por %d nós" + +#: ../../../ui.cpp:1206 +msgid "<b>Date:</b> " +msgstr "<b>Data:</b> " + +#: ../../../ui.cpp:1214 +msgid "<b>Source:</b> Generated<br>" +msgstr "<b>Fonte:</b> Gerado<br>" + +#: ../../../ui.cpp:1220 +#: ../../../ui.cpp:1238 +msgid "<b>From:</b> " +msgstr "<b>Remetente:</b> " + +#: ../../../ui.cpp:1238 +msgid "unknown" +msgstr "desconhecido" + +#: ../../../ui.cpp:1239 +#: ../../../ui.cpp:1263 +#: ../../../ui.cpp:1322 +msgid "<b>To:</b> " +msgstr "<b>Destinatário:</b> " + +#: ../../../ui.cpp:1242 +msgid " (yours, label: " +msgstr " (seu, etiqueta: " + +#: ../../../ui.cpp:1244 +msgid " (yours)" +msgstr " (seu)" + +#: ../../../ui.cpp:1281 +#: ../../../ui.cpp:1293 +#: ../../../ui.cpp:1356 +msgid "<b>Credit:</b> " +msgstr "<b>Crédito:</b> " + +#: ../../../ui.cpp:1283 +#, c-format +msgid "(%s matures in %d more blocks)" +msgstr "(%s maduras em mais %d blocos)" + +#: ../../../ui.cpp:1285 +msgid "(not accepted)" +msgstr "(não aceite)" + +#: ../../../ui.cpp:1330 +#: ../../../ui.cpp:1353 +msgid "<b>Debit:</b> " +msgstr "<b>Débito:</b> " + +#: ../../../ui.cpp:1344 +msgid "<b>Transaction fee:</b> " +msgstr "<b>Percentagem da transacção:</b> " + +#: ../../../ui.cpp:1360 +msgid "<b>Net amount:</b> " +msgstr "<b>Quantia Net:</b> " + +#: ../../../ui.cpp:1367 +msgid "Message:" +msgstr "Mensagem:" + +#: ../../../ui.cpp:1370 +msgid "Generated coins must wait 120 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, it will change to \"not accepted\" and not be spendable. This may occasionally happen if another node generates a block within a few seconds of yours." +msgstr "As moedas geradas necessitam de 120 blocos para que possam ser gastas. Quando gera um bloco, ele será anunciado pela rede para ser adicionado à cadeia de blocos. Se falhar, mudará para \"não aceite\" e não será possÃvel utilizá-lo. Isto pode acontecer se um nó gerar outro bloco após alguns segundos do seu." + +#: ../../../ui.cpp:1437 +msgid "Main" +msgstr "Principal" + +#: ../../../ui.cpp:1442 +msgid "&Minimize on close" +msgstr "&Minimizar ao fechar" + +#: ../../../ui.cpp:1595 +#, c-format +msgid "version 0.%d.%d beta" +msgstr "versão 0.%d.%d beta" + +#: ../../../ui.cpp:1681 +msgid "Will appear as \"From: Unknown\"" +msgstr "Irá aparecer como \"De: Desconhecido\"" + +#: ../../../ui.cpp:1682 +msgid "Can't include a message when sending to a Bitcoin address" +msgstr "Não é possÃvel incluir uma mensagem ao enviar para um endereço Bitcoin" + +#: ../../../ui.cpp:1735 +msgid "Error in amount " +msgstr "Erro na quantia " + +#: ../../../ui.cpp:1735 +#: ../../../ui.cpp:1740 +#: ../../../ui.cpp:1745 +#: ../../../ui.cpp:1771 +#: ../../../uibase.cpp:61 +msgid "Send Coins" +msgstr "Enviar Moedas" + +#: ../../../ui.cpp:1740 +msgid "Amount exceeds your balance " +msgstr "A quantia excede o seu saldo " + +#: ../../../ui.cpp:1745 +msgid "Total exceeds your balance when the " +msgstr "O total excede o seu saldo quando a " + +#: ../../../ui.cpp:1745 +msgid " transaction fee is included " +msgstr " taxa de transacção for incluÃda " + +#: ../../../ui.cpp:1761 +msgid "Payment sent " +msgstr "Pagamento enviado " + +#: ../../../ui.cpp:1771 +msgid "Invalid address " +msgstr "Endereço inválido " + +#: ../../../ui.cpp:1825 +#, c-format +msgid "Sending %s to %s" +msgstr "A enviar %s para %s" + +#: ../../../ui.cpp:1898 +#: ../../../ui.cpp:1931 +msgid "CANCELLED" +msgstr "CANCELADO" + +#: ../../../ui.cpp:1902 +msgid "Cancelled" +msgstr "Cancelado" + +#: ../../../ui.cpp:1904 +msgid "Transfer cancelled " +msgstr "Transferência cancelada " + +#: ../../../ui.cpp:1957 +msgid "Error: " +msgstr "Erro: " + +#: ../../../ui.cpp:1976 +msgid "Connecting..." +msgstr "A estabelecer ligação ..." + +#: ../../../ui.cpp:1981 +msgid "Unable to connect" +msgstr "ImpossÃvel estabelecer ligação" + +#: ../../../ui.cpp:1986 +msgid "Requesting public key..." +msgstr "A requisitar a chave pública ..." + +#: ../../../ui.cpp:1998 +msgid "Received public key..." +msgstr "Chave pública recebida" + +#: ../../../ui.cpp:2010 +msgid "Transfer was not accepted" +msgstr "A transferência não foi aceite" + +#: ../../../ui.cpp:2019 +msgid "Invalid response received" +msgstr "Resposta inválida recebida" + +#: ../../../ui.cpp:2034 +msgid "Creating transaction..." +msgstr "A criar a transacção ..." + +#: ../../../ui.cpp:2046 +#, c-format +msgid "This is an oversized transaction that requires a transaction fee of %s" +msgstr "Esta transferência requer o pagamento de uma taxa de transacção de %s" + +#: ../../../ui.cpp:2048 +msgid "Transaction creation failed" +msgstr "A criação da transacção falhou" + +#: ../../../ui.cpp:2055 +msgid "Transaction aborted" +msgstr "Transacção cancelada" + +#: ../../../ui.cpp:2063 +msgid "Lost connection, transaction cancelled" +msgstr "Perca de ligação, transacção cancelada" + +#: ../../../ui.cpp:2079 +msgid "Sending payment..." +msgstr "A enviar pagamento ..." + +#: ../../../ui.cpp:2085 +msgid "The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here." +msgstr "A transacção foi rejeitada. Isto pode acontecer se algumas das moedas na sua carteira já foram utilizadas, como na utilização de uma cópia do wallet.dat, onde as moedas foram utilizadas na cópia do ficheiro e essas alterações não reflectem o estado desta carteira." + +#: ../../../ui.cpp:2092 +msgid "Waiting for confirmation..." +msgstr "A aguardar confirmação ..." + +#: ../../../ui.cpp:2110 +msgid "" +"The payment was sent, but the recipient was unable to verify it.\n" +"The transaction is recorded and will credit to the recipient,\n" +"but the comment information will be blank." +msgstr "" +"O pagamento foi enviado, mas o remetente não consegiu verificar o seu pagamento.\n" +"A transacção foi entregue, e o remetente receberá as modeas,\n" +"no entanto, o comentário de transacção estará vazio." + +#: ../../../ui.cpp:2119 +msgid "Payment was sent, but an invalid response was received" +msgstr "O pagamento foi enviado, mas foi recebida uma resposta inválida" + +#: ../../../ui.cpp:2125 +msgid "Payment completed" +msgstr "Pagamento completo" + +#: ../../../ui.cpp:2156 +#: ../../../ui.cpp:2302 +#: ../../../ui.cpp:2339 +msgid "Name" +msgstr "Nome" + +#: ../../../ui.cpp:2157 +#: ../../../ui.cpp:2302 +#: ../../../ui.cpp:2339 +msgid "Address" +msgstr "Endereço" + +#: ../../../ui.cpp:2159 +#: ../../../ui.cpp:2314 +msgid "Label" +msgstr "Nota" + +#: ../../../ui.cpp:2160 +#: ../../../uibase.cpp:908 +msgid "Bitcoin Address" +msgstr "Endereço Bitcoin" + +#: ../../../ui.cpp:2284 +msgid "This is one of your own addresses for receiving payments and cannot be entered in the address book. " +msgstr "Este endereço é seu (onde recebe pagamentos) e não pode ser introduzido no seu livros de endereços. " + +#: ../../../ui.cpp:2302 +#: ../../../ui.cpp:2308 +msgid "Edit Address" +msgstr "Editar endereço" + +#: ../../../ui.cpp:2314 +msgid "Edit Address Label" +msgstr "Editar nota de endereço" + +#: ../../../ui.cpp:2339 +#: ../../../ui.cpp:2345 +msgid "Add Address" +msgstr "Adicionar endereço" + +#: ../../../ui.cpp:2421 +msgid "Bitcoin" +msgstr "Bitcoin" + +#: ../../../ui.cpp:2423 +msgid "Bitcoin - Generating" +msgstr "Bitcoin - A gerar" + +#: ../../../ui.cpp:2425 +msgid "Bitcoin - (not connected)" +msgstr "Bitcoin - (sem ligação)" + +#: ../../../ui.cpp:2500 +msgid "&Open Bitcoin" +msgstr "&Abrir Bitcoin" + +#: ../../../ui.cpp:2501 +msgid "O&ptions..." +msgstr "O&pções" + +#: ../../../ui.cpp:2502 +#: ../../../uibase.cpp:34 +msgid "&Generate Coins" +msgstr "&Gerar Moedas" + +#: ../../../ui.cpp:2505 +#: ../../../uibase.cpp:27 +msgid "E&xit" +msgstr "S&air" + +#: ../../../uibase.cpp:30 +msgid "&File" +msgstr "&Ficheiro" + +#: ../../../uibase.cpp:38 +msgid "&Your Receiving Addresses..." +msgstr "&Os seus endereços" + +#: ../../../uibase.cpp:42 +msgid "&Options..." +msgstr "&Opções ..." + +#: ../../../uibase.cpp:45 +msgid "&Settings" +msgstr "&Definições" + +#: ../../../uibase.cpp:49 +msgid "&About..." +msgstr "&Sobre ..." + +#: ../../../uibase.cpp:52 +msgid "&Help" +msgstr "&Ajuda" + +#: ../../../uibase.cpp:62 +msgid "Address Book" +msgstr "Livro de Endereços" + +#: ../../../uibase.cpp:77 +msgid "Your Bitcoin Address:" +msgstr "O seu endereço Bitcoin:" + +#: ../../../uibase.cpp:84 +msgid " &New... " +msgstr " &Novo ... " + +#: ../../../uibase.cpp:87 +#: ../../../uibase.cpp:851 +#: ../../../uibase.cpp:954 +msgid " &Copy to Clipboard " +msgstr " &Copiar para o Clipboard " + +#: ../../../uibase.cpp:102 +msgid "Balance:" +msgstr "Saldo:" + +#: ../../../uibase.cpp:121 +msgid " All" +msgstr " Todos" + +#: ../../../uibase.cpp:121 +msgid " Sent" +msgstr " Enviado" + +#: ../../../uibase.cpp:121 +msgid " Received" +msgstr " Recebido" + +#: ../../../uibase.cpp:121 +msgid " In Progress" +msgstr " Em progresso" + +#: ../../../uibase.cpp:142 +msgid "All Transactions" +msgstr "Todas as transacções" + +#: ../../../uibase.cpp:153 +msgid "Sent/Received" +msgstr "Enviadas/Recebidas" + +#: ../../../uibase.cpp:164 +msgid "Sent" +msgstr "Enviado" + +#: ../../../uibase.cpp:175 +msgid "Received" +msgstr "Recebido" + +#: ../../../uibase.cpp:318 +#: ../../../uibase.cpp:479 +#: ../../../uibase.cpp:580 +#: ../../../uibase.cpp:793 +#: ../../../uibase.cpp:854 +#: ../../../uibase.cpp:963 +#: ../../../uibase.cpp:1052 +msgid "OK" +msgstr "OK" + +#: ../../../uibase.cpp:361 +msgid "Optional transaction fee you give to the nodes that process your transactions." +msgstr "Pagamento de taxa de transacção opcional que é entregue aos nós que ajudam a processar o seu pagamento" + +#: ../../../uibase.cpp:370 +msgid "Transaction fee:" +msgstr "Taxa de transacção:" + +#: ../../../uibase.cpp:386 +msgid "&Limit coin generation to" +msgstr "&Limitar a geração de moedas a" + +#: ../../../uibase.cpp:393 +msgid "processors" +msgstr "processadores" + +#: ../../../uibase.cpp:399 +msgid "&Start Bitcoin on system startup" +msgstr "&Iniciar o Bitcoin no arranque do sistema" + +#: ../../../uibase.cpp:403 +msgid "&Minimize to the tray instead of the taskbar" +msgstr "&Minimizar para a zona do relógio em vez da barra de janelas" + +#: ../../../uibase.cpp:407 +msgid "M&inimize to the tray on close" +msgstr "M&inimizar para a zona do relógio ao fechar" + +#: ../../../uibase.cpp:414 +msgid "&Connect through socks4 proxy: " +msgstr "&Ligar através de um prozy socks4: " + +#: ../../../uibase.cpp:426 +msgid "Proxy &IP:" +msgstr "Proxy &IP:" + +#: ../../../uibase.cpp:434 +msgid " &Port:" +msgstr " &Porto:" + +#: ../../../uibase.cpp:456 +msgid "// [don't translate] Test panel 2 for future expansion" +msgstr "" + +#: ../../../uibase.cpp:460 +msgid "// [don't translate] Let's not start multiple pages until the first page is filled up" +msgstr "" + +#: ../../../uibase.cpp:482 +#: ../../../uibase.cpp:735 +#: ../../../uibase.cpp:798 +#: ../../../uibase.cpp:857 +#: ../../../uibase.cpp:966 +#: ../../../uibase.cpp:1055 +msgid "Cancel" +msgstr "Cancelar" + +#: ../../../uibase.cpp:485 +msgid "&Apply" +msgstr "&Aplicar" + +#: ../../../uibase.cpp:546 +msgid "Bitcoin " +msgstr "Bitcoin " + +#: ../../../uibase.cpp:552 +msgid "version" +msgstr "versão" + +#: ../../../uibase.cpp:563 +msgid "" +"Copyright (c) 2009-2010 Satoshi Nakamoto.\n" +"\n" +"This is experimental software.\n" +"\n" +"Distributed under the MIT/X11 software license, see the accompanying file \n" +"license.txt or http://www.opensource.org/licenses/mit-license.php.\n" +"\n" +"This product includes software developed by the OpenSSL Project for use in the \n" +"OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by \n" +"Eric Young (eay@cryptsoft.com)." +msgstr "" +"Copyright (c) 2009-2010 Satoshi Nakamoto.\n" +"\n" +"Este software é experimental.\n" +"\n" +"DistribuÃdo sob a licença de software MIT/X11. Veja os seguintes ficheiros \n" +"para mais informações license.txt ou \n" +"http://www.opensource.org/licenses/mit-license.php.\n" +"Este producto inclui software desenvolvido pelo projecto OpenSSL, para \n" +"ser utilizado no OpenSSL Toolkit (http://www.openssl.org) e software de \n" +"criptografia desenvolvido por Eric Young (eay@cryptsoft.com)." + +#: ../../../uibase.cpp:619 +msgid "Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJED9L) or IP address (e.g. 123.45.6.7)" +msgstr "Introduza um endereço Bitcoin (exemplo: 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJED9L) ou um endereço de IP (exemplo: 123.45.6.7)" + +#: ../../../uibase.cpp:633 +msgid "Pay &To:" +msgstr "Pagar &a:" + +#: ../../../uibase.cpp:648 +msgid "&Paste" +msgstr "&Colar" + +#: ../../../uibase.cpp:651 +msgid " Address &Book..." +msgstr " Livro de endereços ..." + +#: ../../../uibase.cpp:658 +msgid "&Amount:" +msgstr "&Quantia:" + +#: ../../../uibase.cpp:668 +msgid "T&ransfer:" +msgstr "T&ransferência:" + +#: ../../../uibase.cpp:674 +msgid " Standard" +msgstr " Standard" + +#: ../../../uibase.cpp:696 +msgid "&From:" +msgstr "&De:" + +#: ../../../uibase.cpp:713 +msgid "&Message:" +msgstr "&Mensagem:" + +#: ../../../uibase.cpp:730 +msgid "&Send" +msgstr "&Enviar" + +#: ../../../uibase.cpp:782 +msgid "" +"\n" +"\n" +"Connecting..." +msgstr "" +"\n" +"\n" +"A estabelecer ligação ..." + +#: ../../../uibase.cpp:832 +msgid "These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. The highlighted address is displayed in the main window." +msgstr "Estes são os seus endereços de Bitcoin onde poderá receber os seus pagamentos. Pode dar um endereço diferente a cada pessoa ou identidade para ter uma melhor ideia sobre quem o está a pagar. O endereço seleccionado será o que aparecerá na janela principal." + +#: ../../../uibase.cpp:845 +#: ../../../uibase.cpp:957 +msgid "&Edit..." +msgstr "&Editar ..." + +#: ../../../uibase.cpp:848 +#: ../../../uibase.cpp:960 +msgid " &New Address... " +msgstr " &Novo endereço ... " + +#: ../../../uibase.cpp:920 +msgid "Sending" +msgstr "A enviar" + +#: ../../../uibase.cpp:928 +msgid "These are your Bitcoin addresses for receiving payments. You can give a different one to each sender to keep track of who is paying you. The highlighted address will be displayed in the main window." +msgstr "Estes são os seus endereços de Bitcoin onde poderá receber os seus pagamentos. Pode dar um endereço diferente a cada pessoa ou identidade para ter uma melhor ideia sobre quem o está a pagar. O endereço seleccionado será o que aparecerá na janela principal." + +#: ../../../uibase.cpp:941 +msgid "Receiving" +msgstr "A receber" + +#: ../../../uibase.cpp:951 +msgid "&Delete" +msgstr "&Remover" + +#: ../../../uibase.h:150 +msgid "Transaction Details" +msgstr "Detalhes da transacção" + +#: ../../../uibase.h:203 +msgid "Options" +msgstr "Opções" + +#: ../../../uibase.h:231 +msgid "About Bitcoin" +msgstr "Sobre o Bitcoin" + +#: ../../../uibase.h:341 +msgid "Your Bitcoin Addresses" +msgstr "O seu endereço de Bitcoin" diff --git a/locale/readme.txt b/locale/readme.txt index 9fca3ce657..45b101afc9 100644 --- a/locale/readme.txt +++ b/locale/readme.txt @@ -1,5 +1,5 @@ -put bitcoin.po and bitcoin.mo files at:
-locale/<langcode>/LC_MESSAGES/bitcoin.mo and .po
-
-.po is the sourcefile
-.mo is the compiled translation
+put bitcoin.po and bitcoin.mo files at: +locale/<langcode>/LC_MESSAGES/bitcoin.mo and .po + +.po is the sourcefile +.mo is the compiled translation @@ -1,3124 +1,3124 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
-
-#include "headers.h"
-#include "sha.h"
-
-
-
-
-
-//
-// Global state
-//
-
-CCriticalSection cs_main;
-
-map<uint256, CTransaction> mapTransactions;
-CCriticalSection cs_mapTransactions;
-unsigned int nTransactionsUpdated = 0;
-map<COutPoint, CInPoint> mapNextTx;
-
-map<uint256, CBlockIndex*> mapBlockIndex;
-const uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f");
-CBlockIndex* pindexGenesisBlock = NULL;
-int nBestHeight = -1;
-uint256 hashBestChain = 0;
-CBlockIndex* pindexBest = NULL;
-int64 nTimeBestReceived = 0;
-
-map<uint256, CBlock*> mapOrphanBlocks;
-multimap<uint256, CBlock*> mapOrphanBlocksByPrev;
-
-map<uint256, CDataStream*> mapOrphanTransactions;
-multimap<uint256, CDataStream*> mapOrphanTransactionsByPrev;
-
-map<uint256, CWalletTx> mapWallet;
-vector<uint256> vWalletUpdated;
-CCriticalSection cs_mapWallet;
-
-map<vector<unsigned char>, CPrivKey> mapKeys;
-map<uint160, vector<unsigned char> > mapPubKeys;
-CCriticalSection cs_mapKeys;
-CKey keyUser;
-
-map<uint256, int> mapRequestCount;
-CCriticalSection cs_mapRequestCount;
-
-map<string, string> mapAddressBook;
-CCriticalSection cs_mapAddressBook;
-
-vector<unsigned char> vchDefaultKey;
-
-// Settings
-int fGenerateBitcoins = false;
-int64 nTransactionFee = 0;
-CAddress addrIncoming;
-int fLimitProcessors = false;
-int nLimitProcessors = 1;
-int fMinimizeToTray = true;
-int fMinimizeOnClose = true;
-
-
-
-
-
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// mapKeys
-//
-
-bool AddKey(const CKey& key)
-{
- CRITICAL_BLOCK(cs_mapKeys)
- {
- mapKeys[key.GetPubKey()] = key.GetPrivKey();
- mapPubKeys[Hash160(key.GetPubKey())] = key.GetPubKey();
- }
- return CWalletDB().WriteKey(key.GetPubKey(), key.GetPrivKey());
-}
-
-vector<unsigned char> GenerateNewKey()
-{
- CKey key;
- key.MakeNewKey();
- if (!AddKey(key))
- throw runtime_error("GenerateNewKey() : AddKey failed\n");
- return key.GetPubKey();
-}
-
-
-
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// mapWallet
-//
-
-bool AddToWallet(const CWalletTx& wtxIn)
-{
- uint256 hash = wtxIn.GetHash();
- CRITICAL_BLOCK(cs_mapWallet)
- {
- // Inserts only if not already there, returns tx inserted or tx found
- pair<map<uint256, CWalletTx>::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn));
- CWalletTx& wtx = (*ret.first).second;
- bool fInsertedNew = ret.second;
- if (fInsertedNew)
- wtx.nTimeReceived = GetAdjustedTime();
-
- bool fUpdated = false;
- if (!fInsertedNew)
- {
- // Merge
- if (wtxIn.hashBlock != 0 && wtxIn.hashBlock != wtx.hashBlock)
- {
- wtx.hashBlock = wtxIn.hashBlock;
- fUpdated = true;
- }
- if (wtxIn.nIndex != -1 && (wtxIn.vMerkleBranch != wtx.vMerkleBranch || wtxIn.nIndex != wtx.nIndex))
- {
- wtx.vMerkleBranch = wtxIn.vMerkleBranch;
- wtx.nIndex = wtxIn.nIndex;
- fUpdated = true;
- }
- if (wtxIn.fFromMe && wtxIn.fFromMe != wtx.fFromMe)
- {
- wtx.fFromMe = wtxIn.fFromMe;
- fUpdated = true;
- }
- if (wtxIn.fSpent && wtxIn.fSpent != wtx.fSpent)
- {
- wtx.fSpent = wtxIn.fSpent;
- fUpdated = true;
- }
- }
-
- //// debug print
- printf("AddToWallet %s %s%s\n", wtxIn.GetHash().ToString().substr(0,6).c_str(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : ""));
-
- // Write to disk
- if (fInsertedNew || fUpdated)
- if (!wtx.WriteToDisk())
- return false;
-
- // If default receiving address gets used, replace it with a new one
- CScript scriptDefaultKey;
- scriptDefaultKey.SetBitcoinAddress(vchDefaultKey);
- foreach(const CTxOut& txout, wtx.vout)
- {
- if (txout.scriptPubKey == scriptDefaultKey)
- {
- CWalletDB walletdb;
- walletdb.WriteDefaultKey(GenerateNewKey());
- walletdb.WriteName(PubKeyToAddress(vchDefaultKey), "");
- }
- }
-
- // Notify UI
- vWalletUpdated.push_back(hash);
- }
-
- // Refresh UI
- MainFrameRepaint();
- return true;
-}
-
-bool AddToWalletIfMine(const CTransaction& tx, const CBlock* pblock)
-{
- if (tx.IsMine() || mapWallet.count(tx.GetHash()))
- {
- CWalletTx wtx(tx);
- // Get merkle branch if transaction was found in a block
- if (pblock)
- wtx.SetMerkleBranch(pblock);
- return AddToWallet(wtx);
- }
- return true;
-}
-
-bool EraseFromWallet(uint256 hash)
-{
- CRITICAL_BLOCK(cs_mapWallet)
- {
- if (mapWallet.erase(hash))
- CWalletDB().EraseTx(hash);
- }
- return true;
-}
-
-void WalletUpdateSpent(const COutPoint& prevout)
-{
- // Anytime a signature is successfully verified, it's proof the outpoint is spent.
- // Update the wallet spent flag if it doesn't know due to wallet.dat being
- // restored from backup or the user making copies of wallet.dat.
- CRITICAL_BLOCK(cs_mapWallet)
- {
- map<uint256, CWalletTx>::iterator mi = mapWallet.find(prevout.hash);
- if (mi != mapWallet.end())
- {
- CWalletTx& wtx = (*mi).second;
- if (!wtx.fSpent && wtx.vout[prevout.n].IsMine())
- {
- printf("WalletUpdateSpent found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str());
- wtx.fSpent = true;
- wtx.WriteToDisk();
- vWalletUpdated.push_back(prevout.hash);
- }
- }
- }
-}
-
-
-
-
-
-
-
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// mapOrphanTransactions
-//
-
-void AddOrphanTx(const CDataStream& vMsg)
-{
- CTransaction tx;
- CDataStream(vMsg) >> tx;
- uint256 hash = tx.GetHash();
- if (mapOrphanTransactions.count(hash))
- return;
- CDataStream* pvMsg = mapOrphanTransactions[hash] = new CDataStream(vMsg);
- foreach(const CTxIn& txin, tx.vin)
- mapOrphanTransactionsByPrev.insert(make_pair(txin.prevout.hash, pvMsg));
-}
-
-void EraseOrphanTx(uint256 hash)
-{
- if (!mapOrphanTransactions.count(hash))
- return;
- const CDataStream* pvMsg = mapOrphanTransactions[hash];
- CTransaction tx;
- CDataStream(*pvMsg) >> tx;
- foreach(const CTxIn& txin, tx.vin)
- {
- for (multimap<uint256, CDataStream*>::iterator mi = mapOrphanTransactionsByPrev.lower_bound(txin.prevout.hash);
- mi != mapOrphanTransactionsByPrev.upper_bound(txin.prevout.hash);)
- {
- if ((*mi).second == pvMsg)
- mapOrphanTransactionsByPrev.erase(mi++);
- else
- mi++;
- }
- }
- delete pvMsg;
- mapOrphanTransactions.erase(hash);
-}
-
-
-
-
-
-
-
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// CTransaction
-//
-
-bool CTxIn::IsMine() const
-{
- CRITICAL_BLOCK(cs_mapWallet)
- {
- map<uint256, CWalletTx>::iterator mi = mapWallet.find(prevout.hash);
- if (mi != mapWallet.end())
- {
- const CWalletTx& prev = (*mi).second;
- if (prevout.n < prev.vout.size())
- if (prev.vout[prevout.n].IsMine())
- return true;
- }
- }
- return false;
-}
-
-int64 CTxIn::GetDebit() const
-{
- CRITICAL_BLOCK(cs_mapWallet)
- {
- map<uint256, CWalletTx>::iterator mi = mapWallet.find(prevout.hash);
- if (mi != mapWallet.end())
- {
- const CWalletTx& prev = (*mi).second;
- if (prevout.n < prev.vout.size())
- if (prev.vout[prevout.n].IsMine())
- return prev.vout[prevout.n].nValue;
- }
- }
- return 0;
-}
-
-int64 CWalletTx::GetTxTime() const
-{
- if (!fTimeReceivedIsTxTime && hashBlock != 0)
- {
- // If we did not receive the transaction directly, we rely on the block's
- // time to figure out when it happened. We use the median over a range
- // of blocks to try to filter out inaccurate block times.
- map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
- if (mi != mapBlockIndex.end())
- {
- CBlockIndex* pindex = (*mi).second;
- if (pindex)
- return pindex->GetMedianTime();
- }
- }
- return nTimeReceived;
-}
-
-int CWalletTx::GetRequestCount() const
-{
- // Returns -1 if it wasn't being tracked
- int nRequests = -1;
- CRITICAL_BLOCK(cs_mapRequestCount)
- {
- if (IsCoinBase())
- {
- // Generated block
- if (hashBlock != 0)
- {
- map<uint256, int>::iterator mi = mapRequestCount.find(hashBlock);
- if (mi != mapRequestCount.end())
- nRequests = (*mi).second;
- }
- }
- else
- {
- // Did anyone request this transaction?
- map<uint256, int>::iterator mi = mapRequestCount.find(GetHash());
- if (mi != mapRequestCount.end())
- {
- nRequests = (*mi).second;
-
- // How about the block it's in?
- if (nRequests == 0 && hashBlock != 0)
- {
- map<uint256, int>::iterator mi = mapRequestCount.find(hashBlock);
- if (mi != mapRequestCount.end())
- nRequests = (*mi).second;
- else
- nRequests = 1; // If it's in someone else's block it must have got out
- }
- }
- }
- }
- return nRequests;
-}
-
-
-
-
-int CMerkleTx::SetMerkleBranch(const CBlock* pblock)
-{
- if (fClient)
- {
- if (hashBlock == 0)
- return 0;
- }
- else
- {
- CBlock blockTmp;
- if (pblock == NULL)
- {
- // Load the block this tx is in
- CTxIndex txindex;
- if (!CTxDB("r").ReadTxIndex(GetHash(), txindex))
- return 0;
- if (!blockTmp.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos))
- return 0;
- pblock = &blockTmp;
- }
-
- // Update the tx's hashBlock
- hashBlock = pblock->GetHash();
-
- // Locate the transaction
- for (nIndex = 0; nIndex < pblock->vtx.size(); nIndex++)
- if (pblock->vtx[nIndex] == *(CTransaction*)this)
- break;
- if (nIndex == pblock->vtx.size())
- {
- vMerkleBranch.clear();
- nIndex = -1;
- printf("ERROR: SetMerkleBranch() : couldn't find tx in block\n");
- return 0;
- }
-
- // Fill in merkle branch
- vMerkleBranch = pblock->GetMerkleBranch(nIndex);
- }
-
- // Is the tx in a block that's in the main chain
- map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
- if (mi == mapBlockIndex.end())
- return 0;
- CBlockIndex* pindex = (*mi).second;
- if (!pindex || !pindex->IsInMainChain())
- return 0;
-
- return pindexBest->nHeight - pindex->nHeight + 1;
-}
-
-
-
-void CWalletTx::AddSupportingTransactions(CTxDB& txdb)
-{
- vtxPrev.clear();
-
- const int COPY_DEPTH = 3;
- if (SetMerkleBranch() < COPY_DEPTH)
- {
- vector<uint256> vWorkQueue;
- foreach(const CTxIn& txin, vin)
- vWorkQueue.push_back(txin.prevout.hash);
-
- // This critsect is OK because txdb is already open
- CRITICAL_BLOCK(cs_mapWallet)
- {
- map<uint256, const CMerkleTx*> mapWalletPrev;
- set<uint256> setAlreadyDone;
- for (int i = 0; i < vWorkQueue.size(); i++)
- {
- uint256 hash = vWorkQueue[i];
- if (setAlreadyDone.count(hash))
- continue;
- setAlreadyDone.insert(hash);
-
- CMerkleTx tx;
- if (mapWallet.count(hash))
- {
- tx = mapWallet[hash];
- foreach(const CMerkleTx& txWalletPrev, mapWallet[hash].vtxPrev)
- mapWalletPrev[txWalletPrev.GetHash()] = &txWalletPrev;
- }
- else if (mapWalletPrev.count(hash))
- {
- tx = *mapWalletPrev[hash];
- }
- else if (!fClient && txdb.ReadDiskTx(hash, tx))
- {
- ;
- }
- else
- {
- printf("ERROR: AddSupportingTransactions() : unsupported transaction\n");
- continue;
- }
-
- int nDepth = tx.SetMerkleBranch();
- vtxPrev.push_back(tx);
-
- if (nDepth < COPY_DEPTH)
- foreach(const CTxIn& txin, tx.vin)
- vWorkQueue.push_back(txin.prevout.hash);
- }
- }
- }
-
- reverse(vtxPrev.begin(), vtxPrev.end());
-}
-
-
-
-
-
-
-
-
-
-
-
-bool CTransaction::AcceptTransaction(CTxDB& txdb, bool fCheckInputs, bool* pfMissingInputs)
-{
- if (pfMissingInputs)
- *pfMissingInputs = false;
-
- // Coinbase is only valid in a block, not as a loose transaction
- if (IsCoinBase())
- return error("AcceptTransaction() : coinbase as individual tx");
-
- if (!CheckTransaction())
- return error("AcceptTransaction() : CheckTransaction failed");
-
- // To help v0.1.5 clients who would see it as a negative number
- if (nLockTime > INT_MAX)
- return error("AcceptTransaction() : not accepting nLockTime beyond 2038");
-
- // Do we already have it?
- uint256 hash = GetHash();
- CRITICAL_BLOCK(cs_mapTransactions)
- if (mapTransactions.count(hash))
- return false;
- if (fCheckInputs)
- if (txdb.ContainsTx(hash))
- return false;
-
- // Check for conflicts with in-memory transactions
- CTransaction* ptxOld = NULL;
- for (int i = 0; i < vin.size(); i++)
- {
- COutPoint outpoint = vin[i].prevout;
- if (mapNextTx.count(outpoint))
- {
- // Allow replacing with a newer version of the same transaction
- if (i != 0)
- return false;
- ptxOld = mapNextTx[outpoint].ptx;
- if (!IsNewerThan(*ptxOld))
- return false;
- for (int i = 0; i < vin.size(); i++)
- {
- COutPoint outpoint = vin[i].prevout;
- if (!mapNextTx.count(outpoint) || mapNextTx[outpoint].ptx != ptxOld)
- return false;
- }
- break;
- }
- }
-
- // Check against previous transactions
- map<uint256, CTxIndex> mapUnused;
- int64 nFees = 0;
- if (fCheckInputs && !ConnectInputs(txdb, mapUnused, CDiskTxPos(1,1,1), 0, nFees, false, false))
- {
- if (pfMissingInputs)
- *pfMissingInputs = true;
- return error("AcceptTransaction() : ConnectInputs failed %s", hash.ToString().substr(0,6).c_str());
- }
-
- // Store transaction in memory
- CRITICAL_BLOCK(cs_mapTransactions)
- {
- if (ptxOld)
- {
- printf("mapTransaction.erase(%s) replacing with new version\n", ptxOld->GetHash().ToString().c_str());
- mapTransactions.erase(ptxOld->GetHash());
- }
- AddToMemoryPool();
- }
-
- ///// are we sure this is ok when loading transactions or restoring block txes
- // If updated, erase old tx from wallet
- if (ptxOld)
- EraseFromWallet(ptxOld->GetHash());
-
- printf("AcceptTransaction(): accepted %s\n", hash.ToString().substr(0,6).c_str());
- return true;
-}
-
-
-bool CTransaction::AddToMemoryPool()
-{
- // Add to memory pool without checking anything. Don't call this directly,
- // call AcceptTransaction to properly check the transaction first.
- CRITICAL_BLOCK(cs_mapTransactions)
- {
- uint256 hash = GetHash();
- mapTransactions[hash] = *this;
- for (int i = 0; i < vin.size(); i++)
- mapNextTx[vin[i].prevout] = CInPoint(&mapTransactions[hash], i);
- nTransactionsUpdated++;
- }
- return true;
-}
-
-
-bool CTransaction::RemoveFromMemoryPool()
-{
- // Remove transaction from memory pool
- CRITICAL_BLOCK(cs_mapTransactions)
- {
- foreach(const CTxIn& txin, vin)
- mapNextTx.erase(txin.prevout);
- mapTransactions.erase(GetHash());
- nTransactionsUpdated++;
- }
- return true;
-}
-
-
-
-
-
-
-int CMerkleTx::GetDepthInMainChain(int& nHeightRet) const
-{
- if (hashBlock == 0 || nIndex == -1)
- return 0;
-
- // Find the block it claims to be in
- map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
- if (mi == mapBlockIndex.end())
- return 0;
- CBlockIndex* pindex = (*mi).second;
- if (!pindex || !pindex->IsInMainChain())
- return 0;
-
- // Make sure the merkle branch connects to this block
- if (!fMerkleVerified)
- {
- if (CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex) != pindex->hashMerkleRoot)
- return 0;
- fMerkleVerified = true;
- }
-
- nHeightRet = pindex->nHeight;
- return pindexBest->nHeight - pindex->nHeight + 1;
-}
-
-
-int CMerkleTx::GetBlocksToMaturity() const
-{
- if (!IsCoinBase())
- return 0;
- return max(0, (COINBASE_MATURITY+20) - GetDepthInMainChain());
-}
-
-
-bool CMerkleTx::AcceptTransaction(CTxDB& txdb, bool fCheckInputs)
-{
- if (fClient)
- {
- if (!IsInMainChain() && !ClientConnectInputs())
- return false;
- return CTransaction::AcceptTransaction(txdb, false);
- }
- else
- {
- return CTransaction::AcceptTransaction(txdb, fCheckInputs);
- }
-}
-
-
-
-bool CWalletTx::AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs)
-{
- CRITICAL_BLOCK(cs_mapTransactions)
- {
- foreach(CMerkleTx& tx, vtxPrev)
- {
- if (!tx.IsCoinBase())
- {
- uint256 hash = tx.GetHash();
- if (!mapTransactions.count(hash) && !txdb.ContainsTx(hash))
- tx.AcceptTransaction(txdb, fCheckInputs);
- }
- }
- if (!IsCoinBase())
- return AcceptTransaction(txdb, fCheckInputs);
- }
- return true;
-}
-
-void ReacceptWalletTransactions()
-{
- CTxDB txdb("r");
- CRITICAL_BLOCK(cs_mapWallet)
- {
- foreach(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
- {
- CWalletTx& wtx = item.second;
- if (wtx.fSpent && wtx.IsCoinBase())
- continue;
-
- CTxIndex txindex;
- if (txdb.ReadTxIndex(wtx.GetHash(), txindex))
- {
- // Update fSpent if a tx got spent somewhere else by a copy of wallet.dat
- if (!wtx.fSpent)
- {
- if (txindex.vSpent.size() != wtx.vout.size())
- {
- printf("ERROR: ReacceptWalletTransactions() : txindex.vSpent.size() %d != wtx.vout.size() %d\n", txindex.vSpent.size(), wtx.vout.size());
- continue;
- }
- for (int i = 0; i < txindex.vSpent.size(); i++)
- {
- if (!txindex.vSpent[i].IsNull() && wtx.vout[i].IsMine())
- {
- printf("ReacceptWalletTransactions found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str());
- wtx.fSpent = true;
- wtx.WriteToDisk();
- break;
- }
- }
- }
- }
- else
- {
- // Reaccept any txes of ours that aren't already in a block
- if (!wtx.IsCoinBase())
- wtx.AcceptWalletTransaction(txdb, false);
- }
- }
- }
-}
-
-
-void CWalletTx::RelayWalletTransaction(CTxDB& txdb)
-{
- foreach(const CMerkleTx& tx, vtxPrev)
- {
- if (!tx.IsCoinBase())
- {
- uint256 hash = tx.GetHash();
- if (!txdb.ContainsTx(hash))
- RelayMessage(CInv(MSG_TX, hash), (CTransaction)tx);
- }
- }
- if (!IsCoinBase())
- {
- uint256 hash = GetHash();
- if (!txdb.ContainsTx(hash))
- {
- printf("Relaying wtx %s\n", hash.ToString().substr(0,6).c_str());
- RelayMessage(CInv(MSG_TX, hash), (CTransaction)*this);
- }
- }
-}
-
-void ResendWalletTransactions()
-{
- // Do this infrequently and randomly to avoid giving away
- // that these are our transactions.
- static int64 nNextTime;
- if (GetTime() < nNextTime)
- return;
- bool fFirst = (nNextTime == 0);
- nNextTime = GetTime() + GetRand(120 * 60);
- if (fFirst)
- return;
-
- // Rebroadcast any of our txes that aren't in a block yet
- printf("ResendWalletTransactions()\n");
- CTxDB txdb("r");
- CRITICAL_BLOCK(cs_mapWallet)
- {
- // Sort them in chronological order
- multimap<unsigned int, CWalletTx*> mapSorted;
- foreach(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
- {
- CWalletTx& wtx = item.second;
- // Don't rebroadcast until it's had plenty of time that
- // it should have gotten in already by now.
- if (nTimeBestReceived - wtx.nTimeReceived > 60 * 60)
- mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx));
- }
- foreach(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted)
- {
- CWalletTx& wtx = *item.second;
- wtx.RelayWalletTransaction(txdb);
- }
- }
-}
-
-
-
-
-
-
-
-
-
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// CBlock and CBlockIndex
-//
-
-bool CBlock::ReadFromDisk(const CBlockIndex* pblockindex, bool fReadTransactions)
-{
- return ReadFromDisk(pblockindex->nFile, pblockindex->nBlockPos, fReadTransactions);
-}
-
-uint256 GetOrphanRoot(const CBlock* pblock)
-{
- // Work back to the first block in the orphan chain
- while (mapOrphanBlocks.count(pblock->hashPrevBlock))
- pblock = mapOrphanBlocks[pblock->hashPrevBlock];
- return pblock->GetHash();
-}
-
-int64 CBlock::GetBlockValue(int64 nFees) const
-{
- int64 nSubsidy = 50 * COIN;
-
- // Subsidy is cut in half every 4 years
- nSubsidy >>= (nBestHeight / 210000);
-
- return nSubsidy + nFees;
-}
-
-unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast)
-{
- const unsigned int nTargetTimespan = 14 * 24 * 60 * 60; // two weeks
- const unsigned int nTargetSpacing = 10 * 60;
- const unsigned int nInterval = nTargetTimespan / nTargetSpacing;
-
- // Genesis block
- if (pindexLast == NULL)
- return bnProofOfWorkLimit.GetCompact();
-
- // Only change once per interval
- if ((pindexLast->nHeight+1) % nInterval != 0)
- return pindexLast->nBits;
-
- // Go back by what we want to be 14 days worth of blocks
- const CBlockIndex* pindexFirst = pindexLast;
- for (int i = 0; pindexFirst && i < nInterval-1; i++)
- pindexFirst = pindexFirst->pprev;
- assert(pindexFirst);
-
- // Limit adjustment step
- unsigned int nActualTimespan = pindexLast->nTime - pindexFirst->nTime;
- printf(" nActualTimespan = %d before bounds\n", nActualTimespan);
- if (nActualTimespan < nTargetTimespan/4)
- nActualTimespan = nTargetTimespan/4;
- if (nActualTimespan > nTargetTimespan*4)
- nActualTimespan = nTargetTimespan*4;
-
- // Retarget
- CBigNum bnNew;
- bnNew.SetCompact(pindexLast->nBits);
- bnNew *= nActualTimespan;
- bnNew /= nTargetTimespan;
-
- if (bnNew > bnProofOfWorkLimit)
- bnNew = bnProofOfWorkLimit;
-
- /// debug print
- printf("GetNextWorkRequired RETARGET\n");
- printf("nTargetTimespan = %d nActualTimespan = %d\n", nTargetTimespan, nActualTimespan);
- printf("Before: %08x %s\n", pindexLast->nBits, CBigNum().SetCompact(pindexLast->nBits).getuint256().ToString().c_str());
- printf("After: %08x %s\n", bnNew.GetCompact(), bnNew.getuint256().ToString().c_str());
-
- return bnNew.GetCompact();
-}
-
-
-
-
-
-
-
-
-
-bool CTransaction::DisconnectInputs(CTxDB& txdb)
-{
- // Relinquish previous transactions' spent pointers
- if (!IsCoinBase())
- {
- foreach(const CTxIn& txin, vin)
- {
- COutPoint prevout = txin.prevout;
-
- // Get prev txindex from disk
- CTxIndex txindex;
- if (!txdb.ReadTxIndex(prevout.hash, txindex))
- return error("DisconnectInputs() : ReadTxIndex failed");
-
- if (prevout.n >= txindex.vSpent.size())
- return error("DisconnectInputs() : prevout.n out of range");
-
- // Mark outpoint as not spent
- txindex.vSpent[prevout.n].SetNull();
-
- // Write back
- txdb.UpdateTxIndex(prevout.hash, txindex);
- }
- }
-
- // Remove transaction from index
- if (!txdb.EraseTxIndex(*this))
- return error("DisconnectInputs() : EraseTxPos failed");
-
- return true;
-}
-
-
-bool CTransaction::ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPool, CDiskTxPos posThisTx, int nHeight, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee)
-{
- // Take over previous transactions' spent pointers
- if (!IsCoinBase())
- {
- int64 nValueIn = 0;
- for (int i = 0; i < vin.size(); i++)
- {
- COutPoint prevout = vin[i].prevout;
-
- // Read txindex
- CTxIndex txindex;
- bool fFound = true;
- if (fMiner && mapTestPool.count(prevout.hash))
- {
- // Get txindex from current proposed changes
- txindex = mapTestPool[prevout.hash];
- }
- else
- {
- // Read txindex from txdb
- fFound = txdb.ReadTxIndex(prevout.hash, txindex);
- }
- if (!fFound && (fBlock || fMiner))
- return fMiner ? false : error("ConnectInputs() : %s prev tx %s index entry not found", GetHash().ToString().substr(0,6).c_str(), prevout.hash.ToString().substr(0,6).c_str());
-
- // Read txPrev
- CTransaction txPrev;
- if (!fFound || txindex.pos == CDiskTxPos(1,1,1))
- {
- // Get prev tx from single transactions in memory
- CRITICAL_BLOCK(cs_mapTransactions)
- {
- if (!mapTransactions.count(prevout.hash))
- return error("ConnectInputs() : %s mapTransactions prev not found %s", GetHash().ToString().substr(0,6).c_str(), prevout.hash.ToString().substr(0,6).c_str());
- txPrev = mapTransactions[prevout.hash];
- }
- if (!fFound)
- txindex.vSpent.resize(txPrev.vout.size());
- }
- else
- {
- // Get prev tx from disk
- if (!txPrev.ReadFromDisk(txindex.pos))
- return error("ConnectInputs() : %s ReadFromDisk prev tx %s failed", GetHash().ToString().substr(0,6).c_str(), prevout.hash.ToString().substr(0,6).c_str());
- }
-
- if (prevout.n >= txPrev.vout.size() || prevout.n >= txindex.vSpent.size())
- return error("ConnectInputs() : %s prevout.n out of range %d %d %d prev tx %s\n%s", GetHash().ToString().substr(0,6).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size(), prevout.hash.ToString().substr(0,6).c_str(), txPrev.ToString().c_str());
-
- // If prev is coinbase, check that it's matured
- if (txPrev.IsCoinBase())
- for (CBlockIndex* pindex = pindexBest; pindex && nBestHeight - pindex->nHeight < COINBASE_MATURITY-1; pindex = pindex->pprev)
- if (pindex->nBlockPos == txindex.pos.nBlockPos && pindex->nFile == txindex.pos.nFile)
- return error("ConnectInputs() : tried to spend coinbase at depth %d", nBestHeight - pindex->nHeight);
-
- // Verify signature
- if (!VerifySignature(txPrev, *this, i))
- return error("ConnectInputs() : %s VerifySignature failed", GetHash().ToString().substr(0,6).c_str());
-
- // Check for conflicts
- if (!txindex.vSpent[prevout.n].IsNull())
- return fMiner ? false : error("ConnectInputs() : %s prev tx already used at %s", GetHash().ToString().substr(0,6).c_str(), txindex.vSpent[prevout.n].ToString().c_str());
-
- // Mark outpoints as spent
- txindex.vSpent[prevout.n] = posThisTx;
-
- // Write back
- if (fBlock)
- txdb.UpdateTxIndex(prevout.hash, txindex);
- else if (fMiner)
- mapTestPool[prevout.hash] = txindex;
-
- nValueIn += txPrev.vout[prevout.n].nValue;
- }
-
- // Tally transaction fees
- int64 nTxFee = nValueIn - GetValueOut();
- if (nTxFee < 0)
- return error("ConnectInputs() : %s nTxFee < 0", GetHash().ToString().substr(0,6).c_str());
- if (nTxFee < nMinFee)
- return false;
- nFees += nTxFee;
- }
-
- if (fBlock)
- {
- // Add transaction to disk index
- if (!txdb.AddTxIndex(*this, posThisTx, nHeight))
- return error("ConnectInputs() : AddTxPos failed");
- }
- else if (fMiner)
- {
- // Add transaction to test pool
- mapTestPool[GetHash()] = CTxIndex(CDiskTxPos(1,1,1), vout.size());
- }
-
- return true;
-}
-
-
-bool CTransaction::ClientConnectInputs()
-{
- if (IsCoinBase())
- return false;
-
- // Take over previous transactions' spent pointers
- CRITICAL_BLOCK(cs_mapTransactions)
- {
- int64 nValueIn = 0;
- for (int i = 0; i < vin.size(); i++)
- {
- // Get prev tx from single transactions in memory
- COutPoint prevout = vin[i].prevout;
- if (!mapTransactions.count(prevout.hash))
- return false;
- CTransaction& txPrev = mapTransactions[prevout.hash];
-
- if (prevout.n >= txPrev.vout.size())
- return false;
-
- // Verify signature
- if (!VerifySignature(txPrev, *this, i))
- return error("ConnectInputs() : VerifySignature failed");
-
- ///// this is redundant with the mapNextTx stuff, not sure which I want to get rid of
- ///// this has to go away now that posNext is gone
- // // Check for conflicts
- // if (!txPrev.vout[prevout.n].posNext.IsNull())
- // return error("ConnectInputs() : prev tx already used");
- //
- // // Flag outpoints as used
- // txPrev.vout[prevout.n].posNext = posThisTx;
-
- nValueIn += txPrev.vout[prevout.n].nValue;
- }
- if (GetValueOut() > nValueIn)
- return false;
- }
-
- return true;
-}
-
-
-
-
-bool CBlock::DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex)
-{
- // Disconnect in reverse order
- for (int i = vtx.size()-1; i >= 0; i--)
- if (!vtx[i].DisconnectInputs(txdb))
- return false;
-
- // Update block index on disk without changing it in memory.
- // The memory index structure will be changed after the db commits.
- if (pindex->pprev)
- {
- CDiskBlockIndex blockindexPrev(pindex->pprev);
- blockindexPrev.hashNext = 0;
- txdb.WriteBlockIndex(blockindexPrev);
- }
-
- return true;
-}
-
-bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex)
-{
- //// issue here: it doesn't know the version
- unsigned int nTxPos = pindex->nBlockPos + ::GetSerializeSize(CBlock(), SER_DISK) - 1 + GetSizeOfCompactSize(vtx.size());
-
- map<uint256, CTxIndex> mapUnused;
- int64 nFees = 0;
- foreach(CTransaction& tx, vtx)
- {
- CDiskTxPos posThisTx(pindex->nFile, pindex->nBlockPos, nTxPos);
- nTxPos += ::GetSerializeSize(tx, SER_DISK);
-
- if (!tx.ConnectInputs(txdb, mapUnused, posThisTx, pindex->nHeight, nFees, true, false))
- return false;
- }
-
- if (vtx[0].GetValueOut() > GetBlockValue(nFees))
- return false;
-
- // Update block index on disk without changing it in memory.
- // The memory index structure will be changed after the db commits.
- if (pindex->pprev)
- {
- CDiskBlockIndex blockindexPrev(pindex->pprev);
- blockindexPrev.hashNext = pindex->GetBlockHash();
- txdb.WriteBlockIndex(blockindexPrev);
- }
-
- // Watch for transactions paying to me
- foreach(CTransaction& tx, vtx)
- AddToWalletIfMine(tx, this);
-
- return true;
-}
-
-
-
-bool Reorganize(CTxDB& txdb, CBlockIndex* pindexNew)
-{
- printf("REORGANIZE\n");
-
- // Find the fork
- CBlockIndex* pfork = pindexBest;
- CBlockIndex* plonger = pindexNew;
- while (pfork != plonger)
- {
- if (!(pfork = pfork->pprev))
- return error("Reorganize() : pfork->pprev is null");
- while (plonger->nHeight > pfork->nHeight)
- if (!(plonger = plonger->pprev))
- return error("Reorganize() : plonger->pprev is null");
- }
-
- // List of what to disconnect
- vector<CBlockIndex*> vDisconnect;
- for (CBlockIndex* pindex = pindexBest; pindex != pfork; pindex = pindex->pprev)
- vDisconnect.push_back(pindex);
-
- // List of what to connect
- vector<CBlockIndex*> vConnect;
- for (CBlockIndex* pindex = pindexNew; pindex != pfork; pindex = pindex->pprev)
- vConnect.push_back(pindex);
- reverse(vConnect.begin(), vConnect.end());
-
- // Disconnect shorter branch
- vector<CTransaction> vResurrect;
- foreach(CBlockIndex* pindex, vDisconnect)
- {
- CBlock block;
- if (!block.ReadFromDisk(pindex->nFile, pindex->nBlockPos))
- return error("Reorganize() : ReadFromDisk for disconnect failed");
- if (!block.DisconnectBlock(txdb, pindex))
- return error("Reorganize() : DisconnectBlock failed");
-
- // Queue memory transactions to resurrect
- foreach(const CTransaction& tx, block.vtx)
- if (!tx.IsCoinBase())
- vResurrect.push_back(tx);
- }
-
- // Connect longer branch
- vector<CTransaction> vDelete;
- for (int i = 0; i < vConnect.size(); i++)
- {
- CBlockIndex* pindex = vConnect[i];
- CBlock block;
- if (!block.ReadFromDisk(pindex->nFile, pindex->nBlockPos))
- return error("Reorganize() : ReadFromDisk for connect failed");
- if (!block.ConnectBlock(txdb, pindex))
- {
- // Invalid block, delete the rest of this branch
- txdb.TxnAbort();
- for (int j = i; j < vConnect.size(); j++)
- {
- CBlockIndex* pindex = vConnect[j];
- pindex->EraseBlockFromDisk();
- txdb.EraseBlockIndex(pindex->GetBlockHash());
- mapBlockIndex.erase(pindex->GetBlockHash());
- delete pindex;
- }
- return error("Reorganize() : ConnectBlock failed");
- }
-
- // Queue memory transactions to delete
- foreach(const CTransaction& tx, block.vtx)
- vDelete.push_back(tx);
- }
- if (!txdb.WriteHashBestChain(pindexNew->GetBlockHash()))
- return error("Reorganize() : WriteHashBestChain failed");
-
- // Commit now because resurrecting could take some time
- txdb.TxnCommit();
-
- // Disconnect shorter branch
- foreach(CBlockIndex* pindex, vDisconnect)
- if (pindex->pprev)
- pindex->pprev->pnext = NULL;
-
- // Connect longer branch
- foreach(CBlockIndex* pindex, vConnect)
- if (pindex->pprev)
- pindex->pprev->pnext = pindex;
-
- // Resurrect memory transactions that were in the disconnected branch
- foreach(CTransaction& tx, vResurrect)
- tx.AcceptTransaction(txdb, false);
-
- // Delete redundant memory transactions that are in the connected branch
- foreach(CTransaction& tx, vDelete)
- tx.RemoveFromMemoryPool();
-
- return true;
-}
-
-
-bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
-{
- // Check for duplicate
- uint256 hash = GetHash();
- if (mapBlockIndex.count(hash))
- return error("AddToBlockIndex() : %s already exists", hash.ToString().substr(0,16).c_str());
-
- // Construct new block index object
- CBlockIndex* pindexNew = new CBlockIndex(nFile, nBlockPos, *this);
- if (!pindexNew)
- return error("AddToBlockIndex() : new CBlockIndex failed");
- map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
- pindexNew->phashBlock = &((*mi).first);
- map<uint256, CBlockIndex*>::iterator miPrev = mapBlockIndex.find(hashPrevBlock);
- if (miPrev != mapBlockIndex.end())
- {
- pindexNew->pprev = (*miPrev).second;
- pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
- }
-
- CTxDB txdb;
- txdb.TxnBegin();
- txdb.WriteBlockIndex(CDiskBlockIndex(pindexNew));
-
- // New best
- if (pindexNew->nHeight > nBestHeight)
- {
- if (pindexGenesisBlock == NULL && hash == hashGenesisBlock)
- {
- pindexGenesisBlock = pindexNew;
- txdb.WriteHashBestChain(hash);
- }
- else if (hashPrevBlock == hashBestChain)
- {
- // Adding to current best branch
- if (!ConnectBlock(txdb, pindexNew) || !txdb.WriteHashBestChain(hash))
- {
- txdb.TxnAbort();
- pindexNew->EraseBlockFromDisk();
- mapBlockIndex.erase(pindexNew->GetBlockHash());
- delete pindexNew;
- return error("AddToBlockIndex() : ConnectBlock failed");
- }
- txdb.TxnCommit();
- pindexNew->pprev->pnext = pindexNew;
-
- // Delete redundant memory transactions
- foreach(CTransaction& tx, vtx)
- tx.RemoveFromMemoryPool();
- }
- else
- {
- // New best branch
- if (!Reorganize(txdb, pindexNew))
- {
- txdb.TxnAbort();
- return error("AddToBlockIndex() : Reorganize failed");
- }
- }
-
- // New best block
- hashBestChain = hash;
- pindexBest = pindexNew;
- nBestHeight = pindexBest->nHeight;
- nTimeBestReceived = GetTime();
- nTransactionsUpdated++;
- printf("AddToBlockIndex: new best=%s height=%d\n", hashBestChain.ToString().substr(0,16).c_str(), nBestHeight);
- }
-
- txdb.TxnCommit();
- txdb.Close();
-
- if (pindexNew == pindexBest)
- {
- // Notify UI to display prev block's coinbase if it was ours
- static uint256 hashPrevBestCoinBase;
- CRITICAL_BLOCK(cs_mapWallet)
- vWalletUpdated.push_back(hashPrevBestCoinBase);
- hashPrevBestCoinBase = vtx[0].GetHash();
- }
-
- MainFrameRepaint();
- return true;
-}
-
-
-
-
-bool CBlock::CheckBlock() const
-{
- // These are checks that are independent of context
- // that can be verified before saving an orphan block.
-
- // Size limits
- if (vtx.empty() || vtx.size() > MAX_SIZE || ::GetSerializeSize(*this, SER_DISK) > MAX_SIZE)
- return error("CheckBlock() : size limits failed");
-
- // Check timestamp
- if (nTime > GetAdjustedTime() + 2 * 60 * 60)
- return error("CheckBlock() : block timestamp too far in the future");
-
- // First transaction must be coinbase, the rest must not be
- if (vtx.empty() || !vtx[0].IsCoinBase())
- return error("CheckBlock() : first tx is not coinbase");
- for (int i = 1; i < vtx.size(); i++)
- if (vtx[i].IsCoinBase())
- return error("CheckBlock() : more than one coinbase");
-
- // Check transactions
- foreach(const CTransaction& tx, vtx)
- if (!tx.CheckTransaction())
- return error("CheckBlock() : CheckTransaction failed");
-
- // Check proof of work matches claimed amount
- if (CBigNum().SetCompact(nBits) > bnProofOfWorkLimit)
- return error("CheckBlock() : nBits below minimum work");
- if (GetHash() > CBigNum().SetCompact(nBits).getuint256())
- return error("CheckBlock() : hash doesn't match nBits");
-
- // Check merkleroot
- if (hashMerkleRoot != BuildMerkleTree())
- return error("CheckBlock() : hashMerkleRoot mismatch");
-
- return true;
-}
-
-bool CBlock::AcceptBlock()
-{
- // Check for duplicate
- uint256 hash = GetHash();
- if (mapBlockIndex.count(hash))
- return error("AcceptBlock() : block already in mapBlockIndex");
-
- // Get prev block index
- map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashPrevBlock);
- if (mi == mapBlockIndex.end())
- return error("AcceptBlock() : prev block not found");
- CBlockIndex* pindexPrev = (*mi).second;
-
- // Check timestamp against prev
- if (nTime <= pindexPrev->GetMedianTimePast())
- return error("AcceptBlock() : block's timestamp is too early");
-
- // Check that all transactions are finalized
- foreach(const CTransaction& tx, vtx)
- if (!tx.IsFinal(nTime))
- return error("AcceptBlock() : contains a non-final transaction");
-
- // Check proof of work
- if (nBits != GetNextWorkRequired(pindexPrev))
- return error("AcceptBlock() : incorrect proof of work");
-
- // Write block to history file
- if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK)))
- return error("AcceptBlock() : out of disk space");
- unsigned int nFile;
- unsigned int nBlockPos;
- if (!WriteToDisk(!fClient, nFile, nBlockPos))
- return error("AcceptBlock() : WriteToDisk failed");
- if (!AddToBlockIndex(nFile, nBlockPos))
- return error("AcceptBlock() : AddToBlockIndex failed");
-
- // Relay inventory, but don't relay old inventory during initial block download
- if (hashBestChain == hash)
- CRITICAL_BLOCK(cs_vNodes)
- foreach(CNode* pnode, vNodes)
- if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : 55000))
- pnode->PushInventory(CInv(MSG_BLOCK, hash));
-
- return true;
-}
-
-bool ProcessBlock(CNode* pfrom, CBlock* pblock)
-{
- // Check for duplicate
- uint256 hash = pblock->GetHash();
- if (mapBlockIndex.count(hash))
- return error("ProcessBlock() : already have block %d %s", mapBlockIndex[hash]->nHeight, hash.ToString().substr(0,16).c_str());
- if (mapOrphanBlocks.count(hash))
- return error("ProcessBlock() : already have block (orphan) %s", hash.ToString().substr(0,16).c_str());
-
- // Preliminary checks
- if (!pblock->CheckBlock())
- {
- delete pblock;
- return error("ProcessBlock() : CheckBlock FAILED");
- }
-
- // If don't already have its previous block, shunt it off to holding area until we get it
- if (!mapBlockIndex.count(pblock->hashPrevBlock))
- {
- printf("ProcessBlock: ORPHAN BLOCK, prev=%s\n", pblock->hashPrevBlock.ToString().substr(0,16).c_str());
- mapOrphanBlocks.insert(make_pair(hash, pblock));
- mapOrphanBlocksByPrev.insert(make_pair(pblock->hashPrevBlock, pblock));
-
- // Ask this guy to fill in what we're missing
- if (pfrom)
- pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(pblock));
- return true;
- }
-
- // Store to disk
- if (!pblock->AcceptBlock())
- {
- delete pblock;
- return error("ProcessBlock() : AcceptBlock FAILED");
- }
- delete pblock;
-
- // Recursively process any orphan blocks that depended on this one
- vector<uint256> vWorkQueue;
- vWorkQueue.push_back(hash);
- for (int i = 0; i < vWorkQueue.size(); i++)
- {
- uint256 hashPrev = vWorkQueue[i];
- for (multimap<uint256, CBlock*>::iterator mi = mapOrphanBlocksByPrev.lower_bound(hashPrev);
- mi != mapOrphanBlocksByPrev.upper_bound(hashPrev);
- ++mi)
- {
- CBlock* pblockOrphan = (*mi).second;
- if (pblockOrphan->AcceptBlock())
- vWorkQueue.push_back(pblockOrphan->GetHash());
- mapOrphanBlocks.erase(pblockOrphan->GetHash());
- delete pblockOrphan;
- }
- mapOrphanBlocksByPrev.erase(hashPrev);
- }
-
- printf("ProcessBlock: ACCEPTED\n");
- return true;
-}
-
-
-
-
-
-
-
-
-template<typename Stream>
-bool ScanMessageStart(Stream& s)
-{
- // Scan ahead to the next pchMessageStart, which should normally be immediately
- // at the file pointer. Leaves file pointer at end of pchMessageStart.
- s.clear(0);
- short prevmask = s.exceptions(0);
- const char* p = BEGIN(pchMessageStart);
- try
- {
- loop
- {
- char c;
- s.read(&c, 1);
- if (s.fail())
- {
- s.clear(0);
- s.exceptions(prevmask);
- return false;
- }
- if (*p != c)
- p = BEGIN(pchMessageStart);
- if (*p == c)
- {
- if (++p == END(pchMessageStart))
- {
- s.clear(0);
- s.exceptions(prevmask);
- return true;
- }
- }
- }
- }
- catch (...)
- {
- s.clear(0);
- s.exceptions(prevmask);
- return false;
- }
-}
-
-bool CheckDiskSpace(int64 nAdditionalBytes)
-{
- uint64 nFreeBytesAvailable = filesystem::space(GetDataDir()).available;
-
- // Check for 15MB because database could create another 10MB log file at any time
- if (nFreeBytesAvailable < (int64)15000000 + nAdditionalBytes)
- {
- fShutdown = true;
- printf("*** %s***\n", _("Warning: Disk space is low "));
-#if wxUSE_GUI
- ThreadSafeMessageBox(_("Warning: Disk space is low "), "Bitcoin", wxOK | wxICON_EXCLAMATION);
-#endif
- CreateThread(Shutdown, NULL);
- return false;
- }
- return true;
-}
-
-FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode)
-{
- if (nFile == -1)
- return NULL;
- FILE* file = fopen(strprintf("%s/blk%04d.dat", GetDataDir().c_str(), nFile).c_str(), pszMode);
- if (!file)
- return NULL;
- if (nBlockPos != 0 && !strchr(pszMode, 'a') && !strchr(pszMode, 'w'))
- {
- if (fseek(file, nBlockPos, SEEK_SET) != 0)
- {
- fclose(file);
- return NULL;
- }
- }
- return file;
-}
-
-static unsigned int nCurrentBlockFile = 1;
-
-FILE* AppendBlockFile(unsigned int& nFileRet)
-{
- nFileRet = 0;
- loop
- {
- FILE* file = OpenBlockFile(nCurrentBlockFile, 0, "ab");
- if (!file)
- return NULL;
- if (fseek(file, 0, SEEK_END) != 0)
- return NULL;
- // FAT32 filesize max 4GB, fseek and ftell max 2GB, so we must stay under 2GB
- if (ftell(file) < 0x7F000000 - MAX_SIZE)
- {
- nFileRet = nCurrentBlockFile;
- return file;
- }
- fclose(file);
- nCurrentBlockFile++;
- }
-}
-
-bool LoadBlockIndex(bool fAllowNew)
-{
- //
- // Load block index
- //
- CTxDB txdb("cr");
- if (!txdb.LoadBlockIndex())
- return false;
- txdb.Close();
-
- //
- // Init with genesis block
- //
- if (mapBlockIndex.empty())
- {
- if (!fAllowNew)
- return false;
-
-
- // Genesis Block:
- // GetHash() = 0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
- // hashMerkleRoot = 0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
- // txNew.vin[0].scriptSig = 486604799 4 0x736B6E616220726F662074756F6C69616220646E6F63657320666F206B6E697262206E6F20726F6C6C65636E61684320393030322F6E614A2F33302073656D695420656854
- // txNew.vout[0].nValue = 5000000000
- // txNew.vout[0].scriptPubKey = 0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704 OP_CHECKSIG
- // block.nVersion = 1
- // block.nTime = 1231006505
- // block.nBits = 0x1d00ffff
- // block.nNonce = 2083236893
- // CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=2083236893, vtx=1)
- // CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0)
- // CTxIn(COutPoint(000000, -1), coinbase 04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73)
- // CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B)
- // vMerkleTree: 4a5e1e
-
- // Genesis block
- const char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks";
- CTransaction txNew;
- txNew.vin.resize(1);
- txNew.vout.resize(1);
- txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
- txNew.vout[0].nValue = 50 * COIN;
- CBigNum bnPubKey;
- bnPubKey.SetHex("0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704");
- txNew.vout[0].scriptPubKey = CScript() << bnPubKey << OP_CHECKSIG;
- CBlock block;
- block.vtx.push_back(txNew);
- block.hashPrevBlock = 0;
- block.hashMerkleRoot = block.BuildMerkleTree();
- block.nVersion = 1;
- block.nTime = 1231006505;
- block.nBits = 0x1d00ffff;
- block.nNonce = 2083236893;
-
- //// debug print
- printf("%s\n", block.GetHash().ToString().c_str());
- printf("%s\n", block.hashMerkleRoot.ToString().c_str());
- printf("%s\n", hashGenesisBlock.ToString().c_str());
- txNew.vout[0].scriptPubKey.print();
- block.print();
- assert(block.hashMerkleRoot == uint256("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
-
- assert(block.GetHash() == hashGenesisBlock);
-
- // Start new block file
- unsigned int nFile;
- unsigned int nBlockPos;
- if (!block.WriteToDisk(!fClient, nFile, nBlockPos))
- return error("LoadBlockIndex() : writing genesis block to disk failed");
- if (!block.AddToBlockIndex(nFile, nBlockPos))
- return error("LoadBlockIndex() : genesis block not accepted");
- }
-
- return true;
-}
-
-
-
-void PrintBlockTree()
-{
- // precompute tree structure
- map<CBlockIndex*, vector<CBlockIndex*> > mapNext;
- for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi)
- {
- CBlockIndex* pindex = (*mi).second;
- mapNext[pindex->pprev].push_back(pindex);
- // test
- //while (rand() % 3 == 0)
- // mapNext[pindex->pprev].push_back(pindex);
- }
-
- vector<pair<int, CBlockIndex*> > vStack;
- vStack.push_back(make_pair(0, pindexGenesisBlock));
-
- int nPrevCol = 0;
- while (!vStack.empty())
- {
- int nCol = vStack.back().first;
- CBlockIndex* pindex = vStack.back().second;
- vStack.pop_back();
-
- // print split or gap
- if (nCol > nPrevCol)
- {
- for (int i = 0; i < nCol-1; i++)
- printf("| ");
- printf("|\\\n");
- }
- else if (nCol < nPrevCol)
- {
- for (int i = 0; i < nCol; i++)
- printf("| ");
- printf("|\n");
- }
- nPrevCol = nCol;
-
- // print columns
- for (int i = 0; i < nCol; i++)
- printf("| ");
-
- // print item
- CBlock block;
- block.ReadFromDisk(pindex);
- printf("%d (%u,%u) %s %s tx %d",
- pindex->nHeight,
- pindex->nFile,
- pindex->nBlockPos,
- block.GetHash().ToString().substr(0,16).c_str(),
- DateTimeStrFormat("%x %H:%M:%S", block.nTime).c_str(),
- block.vtx.size());
-
- CRITICAL_BLOCK(cs_mapWallet)
- {
- if (mapWallet.count(block.vtx[0].GetHash()))
- {
- CWalletTx& wtx = mapWallet[block.vtx[0].GetHash()];
- printf(" mine: %d %d %d", wtx.GetDepthInMainChain(), wtx.GetBlocksToMaturity(), wtx.GetCredit());
- }
- }
- printf("\n");
-
-
- // put the main timechain first
- vector<CBlockIndex*>& vNext = mapNext[pindex];
- for (int i = 0; i < vNext.size(); i++)
- {
- if (vNext[i]->pnext)
- {
- swap(vNext[0], vNext[i]);
- break;
- }
- }
-
- // iterate children
- for (int i = 0; i < vNext.size(); i++)
- vStack.push_back(make_pair(nCol+i, vNext[i]));
- }
-}
-
-
-
-
-
-
-
-
-
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// Messages
-//
-
-
-bool AlreadyHave(CTxDB& txdb, const CInv& inv)
-{
- switch (inv.type)
- {
- case MSG_TX: return mapTransactions.count(inv.hash) || txdb.ContainsTx(inv.hash);
- case MSG_BLOCK: return mapBlockIndex.count(inv.hash) || mapOrphanBlocks.count(inv.hash);
- }
- // Don't know what it is, just say we already got one
- return true;
-}
-
-
-
-
-
-
-
-bool ProcessMessages(CNode* pfrom)
-{
- CDataStream& vRecv = pfrom->vRecv;
- if (vRecv.empty())
- return true;
- //if (fDebug)
- // printf("ProcessMessages(%d bytes)\n", vRecv.size());
-
- //
- // Message format
- // (4) message start
- // (12) command
- // (4) size
- // (4) checksum
- // (x) data
- //
-
- loop
- {
- // Scan for message start
- CDataStream::iterator pstart = search(vRecv.begin(), vRecv.end(), BEGIN(pchMessageStart), END(pchMessageStart));
- int nHeaderSize = vRecv.GetSerializeSize(CMessageHeader());
- if (vRecv.end() - pstart < nHeaderSize)
- {
- if (vRecv.size() > nHeaderSize)
- {
- printf("\n\nPROCESSMESSAGE MESSAGESTART NOT FOUND\n\n");
- vRecv.erase(vRecv.begin(), vRecv.end() - nHeaderSize);
- }
- break;
- }
- if (pstart - vRecv.begin() > 0)
- printf("\n\nPROCESSMESSAGE SKIPPED %d BYTES\n\n", pstart - vRecv.begin());
- vRecv.erase(vRecv.begin(), pstart);
-
- // Read header
- vector<char> vHeaderSave(vRecv.begin(), vRecv.begin() + nHeaderSize);
- CMessageHeader hdr;
- vRecv >> hdr;
- if (!hdr.IsValid())
- {
- printf("\n\nPROCESSMESSAGE: ERRORS IN HEADER %s\n\n\n", hdr.GetCommand().c_str());
- continue;
- }
- string strCommand = hdr.GetCommand();
-
- // Message size
- unsigned int nMessageSize = hdr.nMessageSize;
- if (nMessageSize > vRecv.size())
- {
- // Rewind and wait for rest of message
- ///// need a mechanism to give up waiting for overlong message size error
- vRecv.insert(vRecv.begin(), vHeaderSave.begin(), vHeaderSave.end());
- break;
- }
-
- // Copy message to its own buffer
- CDataStream vMsg(vRecv.begin(), vRecv.begin() + nMessageSize, vRecv.nType, vRecv.nVersion);
- vRecv.ignore(nMessageSize);
-
- // Checksum
- if (vRecv.GetVersion() >= 209)
- {
- uint256 hash = Hash(vMsg.begin(), vMsg.end());
- unsigned int nChecksum = 0;
- memcpy(&nChecksum, &hash, sizeof(nChecksum));
- if (nChecksum != hdr.nChecksum)
- {
- printf("ProcessMessage(%s, %d bytes) : CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n",
- strCommand.c_str(), nMessageSize, nChecksum, hdr.nChecksum);
- continue;
- }
- }
-
- // Process message
- bool fRet = false;
- try
- {
- CRITICAL_BLOCK(cs_main)
- fRet = ProcessMessage(pfrom, strCommand, vMsg);
- if (fShutdown)
- return true;
- }
- catch (std::ios_base::failure& e)
- {
- if (strstr(e.what(), "CDataStream::read() : end of data"))
- {
- // Allow exceptions from underlength message on vRecv
- printf("ProcessMessage(%s, %d bytes) : Exception '%s' caught, normally caused by a message being shorter than its stated length\n", strCommand.c_str(), nMessageSize, e.what());
- }
- else if (strstr(e.what(), ": size too large"))
- {
- // Allow exceptions from overlong size
- printf("ProcessMessage(%s, %d bytes) : Exception '%s' caught\n", strCommand.c_str(), nMessageSize, e.what());
- }
- else
- {
- PrintException(&e, "ProcessMessage()");
- }
- }
- catch (std::exception& e) {
- PrintException(&e, "ProcessMessage()");
- } catch (...) {
- PrintException(NULL, "ProcessMessage()");
- }
-
- if (!fRet)
- printf("ProcessMessage(%s, %d bytes) FAILED\n", strCommand.c_str(), nMessageSize);
- }
-
- vRecv.Compact();
- return true;
-}
-
-
-
-
-bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
-{
- static map<unsigned int, vector<unsigned char> > mapReuseKey;
- RandAddSeedPerfmon();
- if (fDebug)
- printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
- printf("received: %s (%d bytes)\n", strCommand.c_str(), vRecv.size());
- if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
- {
- printf("dropmessagestest DROPPING RECV MESSAGE\n");
- return true;
- }
-
-
-
-
-
- if (strCommand == "version")
- {
- // Each connection can only send one version message
- if (pfrom->nVersion != 0)
- return false;
-
- int64 nTime;
- CAddress addrMe;
- CAddress addrFrom;
- uint64 nNonce = 1;
- string strSubVer;
- vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe;
- if (pfrom->nVersion == 10300)
- pfrom->nVersion = 300;
- if (pfrom->nVersion >= 106 && !vRecv.empty())
- vRecv >> addrFrom >> nNonce;
- if (pfrom->nVersion >= 106 && !vRecv.empty())
- vRecv >> strSubVer;
- if (pfrom->nVersion >= 209 && !vRecv.empty())
- vRecv >> pfrom->nStartingHeight;
-
- if (pfrom->nVersion == 0)
- return false;
-
- // Disconnect if we connected to ourself
- if (nNonce == nLocalHostNonce && nNonce > 1)
- {
- pfrom->fDisconnect = true;
- return true;
- }
-
- pfrom->fClient = !(pfrom->nServices & NODE_NETWORK);
- if (pfrom->fClient)
- {
- pfrom->vSend.nType |= SER_BLOCKHEADERONLY;
- pfrom->vRecv.nType |= SER_BLOCKHEADERONLY;
- }
-
- AddTimeData(pfrom->addr.ip, nTime);
-
- // Change version
- if (pfrom->nVersion >= 209)
- pfrom->PushMessage("verack");
- pfrom->vSend.SetVersion(min(pfrom->nVersion, VERSION));
- if (pfrom->nVersion < 209)
- pfrom->vRecv.SetVersion(min(pfrom->nVersion, VERSION));
-
- // Ask the first connected node for block updates
- static int nAskedForBlocks;
- if (!pfrom->fClient && (nAskedForBlocks < 1 || vNodes.size() <= 1))
- {
- nAskedForBlocks++;
- pfrom->PushGetBlocks(pindexBest, uint256(0));
- }
-
- pfrom->fSuccessfullyConnected = true;
-
- printf("version message: version %d, blocks=%d\n", pfrom->nVersion, pfrom->nStartingHeight);
- }
-
-
- else if (pfrom->nVersion == 0)
- {
- // Must have a version message before anything else
- return false;
- }
-
-
- else if (strCommand == "verack")
- {
- pfrom->vRecv.SetVersion(min(pfrom->nVersion, VERSION));
- }
-
-
- else if (strCommand == "addr")
- {
- vector<CAddress> vAddr;
- vRecv >> vAddr;
- if (pfrom->nVersion < 200) // don't want addresses from 0.1.5
- return true;
- if (vAddr.size() > 1000)
- return error("message addr size() = %d", vAddr.size());
-
- // Store the new addresses
- foreach(CAddress& addr, vAddr)
- {
- if (fShutdown)
- return true;
- addr.nTime = GetAdjustedTime() - 2 * 60 * 60;
- if (pfrom->fGetAddr || vAddr.size() > 10)
- addr.nTime -= 5 * 24 * 60 * 60;
- AddAddress(addr);
- pfrom->AddAddressKnown(addr);
- if (!pfrom->fGetAddr && addr.IsRoutable())
- {
- // Relay to a limited number of other nodes
- CRITICAL_BLOCK(cs_vNodes)
- {
- // Use deterministic randomness to send to
- // the same places for an hour at a time
- static uint256 hashSalt;
- if (hashSalt == 0)
- RAND_bytes((unsigned char*)&hashSalt, sizeof(hashSalt));
- uint256 hashRand = addr.ip ^ (GetTime()/3600) ^ hashSalt;
- multimap<uint256, CNode*> mapMix;
- foreach(CNode* pnode, vNodes)
- mapMix.insert(make_pair(hashRand = Hash(BEGIN(hashRand), END(hashRand)), pnode));
- int nRelayNodes = 10; // reduce this to 5 when the network is large
- for (multimap<uint256, CNode*>::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi)
- ((*mi).second)->PushAddress(addr);
- }
- }
- }
- if (vAddr.size() < 1000)
- pfrom->fGetAddr = false;
- }
-
-
- else if (strCommand == "inv")
- {
- vector<CInv> vInv;
- vRecv >> vInv;
- if (vInv.size() > 50000)
- return error("message inv size() = %d", vInv.size());
-
- CTxDB txdb("r");
- foreach(const CInv& inv, vInv)
- {
- if (fShutdown)
- return true;
- pfrom->AddInventoryKnown(inv);
-
- bool fAlreadyHave = AlreadyHave(txdb, inv);
- printf(" got inventory: %s %s\n", inv.ToString().c_str(), fAlreadyHave ? "have" : "new");
-
- if (!fAlreadyHave)
- pfrom->AskFor(inv);
- else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash))
- pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(mapOrphanBlocks[inv.hash]));
-
- // Track requests for our stuff
- CRITICAL_BLOCK(cs_mapRequestCount)
- {
- map<uint256, int>::iterator mi = mapRequestCount.find(inv.hash);
- if (mi != mapRequestCount.end())
- (*mi).second++;
- }
- }
- }
-
-
- else if (strCommand == "getdata")
- {
- vector<CInv> vInv;
- vRecv >> vInv;
- if (vInv.size() > 50000)
- return error("message getdata size() = %d", vInv.size());
-
- foreach(const CInv& inv, vInv)
- {
- if (fShutdown)
- return true;
- printf("received getdata for: %s\n", inv.ToString().c_str());
-
- if (inv.type == MSG_BLOCK)
- {
- // Send block from disk
- map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(inv.hash);
- if (mi != mapBlockIndex.end())
- {
- //// could optimize this to send header straight from blockindex for client
- CBlock block;
- block.ReadFromDisk((*mi).second, !pfrom->fClient);
- pfrom->PushMessage("block", block);
-
- // Trigger them to send a getblocks request for the next batch of inventory
- if (inv.hash == pfrom->hashContinue)
- {
- // Bypass PushInventory, this must send even if redundant,
- // and we want it right after the last block so they don't
- // wait for other stuff first.
- vector<CInv> vInv;
- vInv.push_back(CInv(MSG_BLOCK, hashBestChain));
- pfrom->PushMessage("inv", vInv);
- pfrom->hashContinue = 0;
- }
- }
- }
- else if (inv.IsKnownType())
- {
- // Send stream from relay memory
- CRITICAL_BLOCK(cs_mapRelay)
- {
- map<CInv, CDataStream>::iterator mi = mapRelay.find(inv);
- if (mi != mapRelay.end())
- pfrom->PushMessage(inv.GetCommand(), (*mi).second);
- }
- }
-
- // Track requests for our stuff
- CRITICAL_BLOCK(cs_mapRequestCount)
- {
- map<uint256, int>::iterator mi = mapRequestCount.find(inv.hash);
- if (mi != mapRequestCount.end())
- (*mi).second++;
- }
- }
- }
-
-
- else if (strCommand == "getblocks")
- {
- CBlockLocator locator;
- uint256 hashStop;
- vRecv >> locator >> hashStop;
-
- // Find the first block the caller has in the main chain
- CBlockIndex* pindex = locator.GetBlockIndex();
-
- // Send the rest of the chain
- if (pindex)
- pindex = pindex->pnext;
- int nLimit = 500 + locator.GetDistanceBack();
- printf("getblocks %d to %s limit %d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,16).c_str(), nLimit);
- for (; pindex; pindex = pindex->pnext)
- {
- if (pindex->GetBlockHash() == hashStop)
- {
- printf(" getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,16).c_str());
- break;
- }
- pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash()));
- if (--nLimit <= 0)
- {
- // When this block is requested, we'll send an inv that'll make them
- // getblocks the next batch of inventory.
- printf(" getblocks stopping at limit %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,16).c_str());
- pfrom->hashContinue = pindex->GetBlockHash();
- break;
- }
- }
- }
-
-
- else if (strCommand == "tx")
- {
- vector<uint256> vWorkQueue;
- CDataStream vMsg(vRecv);
- CTransaction tx;
- vRecv >> tx;
-
- CInv inv(MSG_TX, tx.GetHash());
- pfrom->AddInventoryKnown(inv);
-
- bool fMissingInputs = false;
- if (tx.AcceptTransaction(true, &fMissingInputs))
- {
- AddToWalletIfMine(tx, NULL);
- RelayMessage(inv, vMsg);
- mapAlreadyAskedFor.erase(inv);
- vWorkQueue.push_back(inv.hash);
-
- // Recursively process any orphan transactions that depended on this one
- for (int i = 0; i < vWorkQueue.size(); i++)
- {
- uint256 hashPrev = vWorkQueue[i];
- for (multimap<uint256, CDataStream*>::iterator mi = mapOrphanTransactionsByPrev.lower_bound(hashPrev);
- mi != mapOrphanTransactionsByPrev.upper_bound(hashPrev);
- ++mi)
- {
- const CDataStream& vMsg = *((*mi).second);
- CTransaction tx;
- CDataStream(vMsg) >> tx;
- CInv inv(MSG_TX, tx.GetHash());
-
- if (tx.AcceptTransaction(true))
- {
- printf(" accepted orphan tx %s\n", inv.hash.ToString().substr(0,6).c_str());
- AddToWalletIfMine(tx, NULL);
- RelayMessage(inv, vMsg);
- mapAlreadyAskedFor.erase(inv);
- vWorkQueue.push_back(inv.hash);
- }
- }
- }
-
- foreach(uint256 hash, vWorkQueue)
- EraseOrphanTx(hash);
- }
- else if (fMissingInputs)
- {
- printf("storing orphan tx %s\n", inv.hash.ToString().substr(0,6).c_str());
- AddOrphanTx(vMsg);
- }
- }
-
-
- else if (strCommand == "block")
- {
- auto_ptr<CBlock> pblock(new CBlock);
- vRecv >> *pblock;
-
- //// debug print
- printf("received block %s\n", pblock->GetHash().ToString().substr(0,16).c_str());
- // pblock->print();
-
- CInv inv(MSG_BLOCK, pblock->GetHash());
- pfrom->AddInventoryKnown(inv);
-
- if (ProcessBlock(pfrom, pblock.release()))
- mapAlreadyAskedFor.erase(inv);
- }
-
-
- else if (strCommand == "getaddr")
- {
- // This includes all nodes that are currently online,
- // since they rebroadcast an addr every 24 hours
- pfrom->vAddrToSend.clear();
- int64 nSince = GetAdjustedTime() - 24 * 60 * 60; // in the last 24 hours
- CRITICAL_BLOCK(cs_mapAddresses)
- {
- unsigned int nSize = mapAddresses.size();
- foreach(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
- {
- if (fShutdown)
- return true;
- const CAddress& addr = item.second;
- if (addr.nTime > nSince)
- pfrom->PushAddress(addr);
- }
- }
- }
-
-
- else if (strCommand == "checkorder")
- {
- uint256 hashReply;
- CWalletTx order;
- vRecv >> hashReply >> order;
-
- /// we have a chance to check the order here
-
- // Keep giving the same key to the same ip until they use it
- if (!mapReuseKey.count(pfrom->addr.ip))
- mapReuseKey[pfrom->addr.ip] = GenerateNewKey();
-
- // Send back approval of order and pubkey to use
- CScript scriptPubKey;
- scriptPubKey << mapReuseKey[pfrom->addr.ip] << OP_CHECKSIG;
- pfrom->PushMessage("reply", hashReply, (int)0, scriptPubKey);
- }
-
-
- else if (strCommand == "submitorder")
- {
- uint256 hashReply;
- CWalletTx wtxNew;
- vRecv >> hashReply >> wtxNew;
- wtxNew.fFromMe = false;
-
- // Broadcast
- if (!wtxNew.AcceptWalletTransaction())
- {
- pfrom->PushMessage("reply", hashReply, (int)1);
- return error("submitorder AcceptWalletTransaction() failed, returning error 1");
- }
- wtxNew.fTimeReceivedIsTxTime = true;
- AddToWallet(wtxNew);
- wtxNew.RelayWalletTransaction();
- mapReuseKey.erase(pfrom->addr.ip);
-
- // Send back confirmation
- pfrom->PushMessage("reply", hashReply, (int)0);
- }
-
-
- else if (strCommand == "reply")
- {
- uint256 hashReply;
- vRecv >> hashReply;
-
- CRequestTracker tracker;
- CRITICAL_BLOCK(pfrom->cs_mapRequests)
- {
- map<uint256, CRequestTracker>::iterator mi = pfrom->mapRequests.find(hashReply);
- if (mi != pfrom->mapRequests.end())
- {
- tracker = (*mi).second;
- pfrom->mapRequests.erase(mi);
- }
- }
- if (!tracker.IsNull())
- tracker.fn(tracker.param1, vRecv);
- }
-
-
- else if (strCommand == "ping")
- {
- }
-
-
- else
- {
- // Ignore unknown commands for extensibility
- }
-
-
- // Update the last seen time for this node's address
- if (pfrom->fNetworkNode)
- if (strCommand == "version" || strCommand == "addr" || strCommand == "inv" || strCommand == "getdata" || strCommand == "ping")
- AddressCurrentlyConnected(pfrom->addr);
-
-
- return true;
-}
-
-
-
-
-
-
-
-
-
-bool SendMessages(CNode* pto, bool fSendTrickle)
-{
- CRITICAL_BLOCK(cs_main)
- {
- // Don't send anything until we get their version message
- if (pto->nVersion == 0)
- return true;
-
- // Keep-alive ping
- if (pto->nLastSend && GetTime() - pto->nLastSend > 30 * 60 && pto->vSend.empty())
- pto->PushMessage("ping");
-
- // Address refresh broadcast
- static int64 nLastRebroadcast;
- if (GetTime() - nLastRebroadcast > 24 * 60 * 60) // every 24 hours
- {
- nLastRebroadcast = GetTime();
- CRITICAL_BLOCK(cs_vNodes)
- {
- foreach(CNode* pnode, vNodes)
- {
- // Periodically clear setAddrKnown to allow refresh broadcasts
- pnode->setAddrKnown.clear();
-
- // Rebroadcast our address
- if (addrLocalHost.IsRoutable() && !fUseProxy)
- pnode->PushAddress(addrLocalHost);
- }
- }
- }
-
- // Resend wallet transactions that haven't gotten in a block yet
- ResendWalletTransactions();
-
-
- //
- // Message: addr
- //
- if (fSendTrickle)
- {
- vector<CAddress> vAddr;
- vAddr.reserve(pto->vAddrToSend.size());
- foreach(const CAddress& addr, pto->vAddrToSend)
- {
- // returns true if wasn't already contained in the set
- if (pto->setAddrKnown.insert(addr).second)
- {
- vAddr.push_back(addr);
- // receiver rejects addr messages larger than 1000
- if (vAddr.size() >= 1000)
- {
- pto->PushMessage("addr", vAddr);
- vAddr.clear();
- }
- }
- }
- pto->vAddrToSend.clear();
- if (!vAddr.empty())
- pto->PushMessage("addr", vAddr);
- }
-
-
- //
- // Message: inventory
- //
- vector<CInv> vInv;
- vector<CInv> vInvWait;
- CRITICAL_BLOCK(pto->cs_inventory)
- {
- vInv.reserve(pto->vInventoryToSend.size());
- vInvWait.reserve(pto->vInventoryToSend.size());
- foreach(const CInv& inv, pto->vInventoryToSend)
- {
- if (pto->setInventoryKnown.count(inv))
- continue;
-
- // trickle out tx inv to protect privacy
- if (inv.type == MSG_TX && !fSendTrickle)
- {
- // 1/4 of tx invs blast to all immediately
- static uint256 hashSalt;
- if (hashSalt == 0)
- RAND_bytes((unsigned char*)&hashSalt, sizeof(hashSalt));
- uint256 hashRand = inv.hash ^ hashSalt;
- hashRand = Hash(BEGIN(hashRand), END(hashRand));
- bool fTrickleWait = ((hashRand & 3) != 0);
-
- // always trickle our own transactions
- if (!fTrickleWait)
- {
- TRY_CRITICAL_BLOCK(cs_mapWallet)
- {
- map<uint256, CWalletTx>::iterator mi = mapWallet.find(inv.hash);
- if (mi != mapWallet.end())
- {
- CWalletTx& wtx = (*mi).second;
- if (wtx.fFromMe)
- fTrickleWait = true;
- }
- }
- }
-
- if (fTrickleWait)
- {
- vInvWait.push_back(inv);
- continue;
- }
- }
-
- // returns true if wasn't already contained in the set
- if (pto->setInventoryKnown.insert(inv).second)
- {
- vInv.push_back(inv);
- if (vInv.size() >= 1000)
- {
- pto->PushMessage("inv", vInv);
- vInv.clear();
- }
- }
- }
- pto->vInventoryToSend = vInvWait;
- }
- if (!vInv.empty())
- pto->PushMessage("inv", vInv);
-
-
- //
- // Message: getdata
- //
- vector<CInv> vGetData;
- int64 nNow = GetTime() * 1000000;
- CTxDB txdb("r");
- while (!pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow)
- {
- const CInv& inv = (*pto->mapAskFor.begin()).second;
- if (!AlreadyHave(txdb, inv))
- {
- printf("sending getdata: %s\n", inv.ToString().c_str());
- vGetData.push_back(inv);
- if (vGetData.size() >= 1000)
- {
- pto->PushMessage("getdata", vGetData);
- vGetData.clear();
- }
- }
- pto->mapAskFor.erase(pto->mapAskFor.begin());
- }
- if (!vGetData.empty())
- pto->PushMessage("getdata", vGetData);
-
- }
- return true;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// BitcoinMiner
-//
-
-void GenerateBitcoins(bool fGenerate)
-{
- if (fGenerateBitcoins != fGenerate)
- {
- fGenerateBitcoins = fGenerate;
- CWalletDB().WriteSetting("fGenerateBitcoins", fGenerateBitcoins);
- MainFrameRepaint();
- }
- if (fGenerateBitcoins)
- {
- int nProcessors = wxThread::GetCPUCount();
- printf("%d processors\n", nProcessors);
- if (nProcessors < 1)
- nProcessors = 1;
- if (fLimitProcessors && nProcessors > nLimitProcessors)
- nProcessors = nLimitProcessors;
- int nAddThreads = nProcessors - vnThreadsRunning[3];
- printf("Starting %d BitcoinMiner threads\n", nAddThreads);
- for (int i = 0; i < nAddThreads; i++)
- {
- if (!CreateThread(ThreadBitcoinMiner, NULL))
- printf("Error: CreateThread(ThreadBitcoinMiner) failed\n");
- Sleep(10);
- }
- }
-}
-
-void ThreadBitcoinMiner(void* parg)
-{
- try
- {
- vnThreadsRunning[3]++;
- BitcoinMiner();
- vnThreadsRunning[3]--;
- }
- catch (std::exception& e) {
- vnThreadsRunning[3]--;
- PrintException(&e, "ThreadBitcoinMiner()");
- } catch (...) {
- vnThreadsRunning[3]--;
- PrintException(NULL, "ThreadBitcoinMiner()");
- }
- UIThreadCall(bind(CalledSetStatusBar, "", 0));
- printf("ThreadBitcoinMiner exiting, %d threads remaining\n", vnThreadsRunning[3]);
-}
-
-int FormatHashBlocks(void* pbuffer, unsigned int len)
-{
- unsigned char* pdata = (unsigned char*)pbuffer;
- unsigned int blocks = 1 + ((len + 8) / 64);
- unsigned char* pend = pdata + 64 * blocks;
- memset(pdata + len, 0, 64 * blocks - len);
- pdata[len] = 0x80;
- unsigned int bits = len * 8;
- pend[-1] = (bits >> 0) & 0xff;
- pend[-2] = (bits >> 8) & 0xff;
- pend[-3] = (bits >> 16) & 0xff;
- pend[-4] = (bits >> 24) & 0xff;
- return blocks;
-}
-
-using CryptoPP::ByteReverse;
-static int detectlittleendian = 1;
-
-void BlockSHA256(const void* pin, unsigned int nBlocks, void* pout)
-{
- unsigned int* pinput = (unsigned int*)pin;
- unsigned int* pstate = (unsigned int*)pout;
-
- CryptoPP::SHA256::InitState(pstate);
-
- if (*(char*)&detectlittleendian != 0)
- {
- for (int n = 0; n < nBlocks; n++)
- {
- unsigned int pbuf[16];
- for (int i = 0; i < 16; i++)
- pbuf[i] = ByteReverse(pinput[n * 16 + i]);
- CryptoPP::SHA256::Transform(pstate, pbuf);
- }
- for (int i = 0; i < 8; i++)
- pstate[i] = ByteReverse(pstate[i]);
- }
- else
- {
- for (int n = 0; n < nBlocks; n++)
- CryptoPP::SHA256::Transform(pstate, pinput + n * 16);
- }
-}
-
-
-void BitcoinMiner()
-{
- printf("BitcoinMiner started\n");
-
- CKey key;
- key.MakeNewKey();
- CBigNum bnExtraNonce = 0;
- while (fGenerateBitcoins)
- {
- SetThreadPriority(THREAD_PRIORITY_LOWEST);
- Sleep(50);
- if (fShutdown)
- return;
- while (vNodes.empty())
- {
- Sleep(1000);
- if (fShutdown)
- return;
- if (!fGenerateBitcoins)
- return;
- }
-
- unsigned int nTransactionsUpdatedLast = nTransactionsUpdated;
- CBlockIndex* pindexPrev = pindexBest;
- unsigned int nBits = GetNextWorkRequired(pindexPrev);
-
-
- //
- // Create coinbase tx
- //
- CTransaction txNew;
- txNew.vin.resize(1);
- txNew.vin[0].prevout.SetNull();
- txNew.vin[0].scriptSig << nBits << ++bnExtraNonce;
- txNew.vout.resize(1);
- txNew.vout[0].scriptPubKey << key.GetPubKey() << OP_CHECKSIG;
-
-
- //
- // Create new block
- //
- auto_ptr<CBlock> pblock(new CBlock());
- if (!pblock.get())
- return;
-
- // Add our coinbase tx as first transaction
- pblock->vtx.push_back(txNew);
-
- // Collect the latest transactions into the block
- int64 nFees = 0;
- CRITICAL_BLOCK(cs_main)
- CRITICAL_BLOCK(cs_mapTransactions)
- {
- CTxDB txdb("r");
- map<uint256, CTxIndex> mapTestPool;
- vector<char> vfAlreadyAdded(mapTransactions.size());
- bool fFoundSomething = true;
- unsigned int nBlockSize = 0;
- while (fFoundSomething && nBlockSize < MAX_SIZE/2)
- {
- fFoundSomething = false;
- unsigned int n = 0;
- for (map<uint256, CTransaction>::iterator mi = mapTransactions.begin(); mi != mapTransactions.end(); ++mi, ++n)
- {
- if (vfAlreadyAdded[n])
- continue;
- CTransaction& tx = (*mi).second;
- if (tx.IsCoinBase() || !tx.IsFinal())
- continue;
-
- // Transaction fee based on block size
- int64 nMinFee = tx.GetMinFee(nBlockSize);
-
- map<uint256, CTxIndex> mapTestPoolTmp(mapTestPool);
- if (!tx.ConnectInputs(txdb, mapTestPoolTmp, CDiskTxPos(1,1,1), 0, nFees, false, true, nMinFee))
- continue;
- swap(mapTestPool, mapTestPoolTmp);
-
- pblock->vtx.push_back(tx);
- nBlockSize += ::GetSerializeSize(tx, SER_NETWORK);
- vfAlreadyAdded[n] = true;
- fFoundSomething = true;
- }
- }
- }
- pblock->nBits = nBits;
- pblock->vtx[0].vout[0].nValue = pblock->GetBlockValue(nFees);
- printf("Running BitcoinMiner with %d transactions in block\n", pblock->vtx.size());
-
-
- //
- // Prebuild hash buffer
- //
- struct unnamed1
- {
- struct unnamed2
- {
- int nVersion;
- uint256 hashPrevBlock;
- uint256 hashMerkleRoot;
- unsigned int nTime;
- unsigned int nBits;
- unsigned int nNonce;
- }
- block;
- unsigned char pchPadding0[64];
- uint256 hash1;
- unsigned char pchPadding1[64];
- }
- tmp;
-
- tmp.block.nVersion = pblock->nVersion;
- tmp.block.hashPrevBlock = pblock->hashPrevBlock = (pindexPrev ? pindexPrev->GetBlockHash() : 0);
- tmp.block.hashMerkleRoot = pblock->hashMerkleRoot = pblock->BuildMerkleTree();
- tmp.block.nTime = pblock->nTime = max((pindexPrev ? pindexPrev->GetMedianTimePast()+1 : 0), GetAdjustedTime());
- tmp.block.nBits = pblock->nBits = nBits;
- tmp.block.nNonce = pblock->nNonce = 1;
-
- unsigned int nBlocks0 = FormatHashBlocks(&tmp.block, sizeof(tmp.block));
- unsigned int nBlocks1 = FormatHashBlocks(&tmp.hash1, sizeof(tmp.hash1));
-
-
- //
- // Search
- //
- int64 nStart = GetTime();
- uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
- uint256 hash;
- loop
- {
- BlockSHA256(&tmp.block, nBlocks0, &tmp.hash1);
- BlockSHA256(&tmp.hash1, nBlocks1, &hash);
-
- if (hash <= hashTarget)
- {
- pblock->nNonce = tmp.block.nNonce;
- assert(hash == pblock->GetHash());
-
- //// debug print
- printf("BitcoinMiner:\n");
- printf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str());
- pblock->print();
- printf("%s ", DateTimeStrFormat("%x %H:%M", GetTime()).c_str());
- printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str());
-
- SetThreadPriority(THREAD_PRIORITY_NORMAL);
- CRITICAL_BLOCK(cs_main)
- {
- if (pindexPrev == pindexBest)
- {
- // Save key
- if (!AddKey(key))
- return;
- key.MakeNewKey();
-
- // Track how many getdata requests this block gets
- CRITICAL_BLOCK(cs_mapRequestCount)
- mapRequestCount[pblock->GetHash()] = 0;
-
- // Process this block the same as if we had received it from another node
- if (!ProcessBlock(NULL, pblock.release()))
- printf("ERROR in BitcoinMiner, ProcessBlock, block not accepted\n");
- }
- }
- SetThreadPriority(THREAD_PRIORITY_LOWEST);
-
- Sleep(500);
- break;
- }
-
- // Update nTime every few seconds
- const unsigned int nMask = 0xffff;
- if ((++tmp.block.nNonce & nMask) == 0)
- {
- // Meter hashes/sec
- static int64 nTimerStart;
- static int nHashCounter;
- if (nTimerStart == 0)
- nTimerStart = GetTimeMillis();
- else
- nHashCounter++;
- if (GetTimeMillis() - nTimerStart > 4000)
- {
- static CCriticalSection cs;
- CRITICAL_BLOCK(cs)
- {
- if (GetTimeMillis() - nTimerStart > 4000)
- {
- double dHashesPerSec = 1000.0 * (nMask+1) * nHashCounter / (GetTimeMillis() - nTimerStart);
- nTimerStart = GetTimeMillis();
- nHashCounter = 0;
- string strStatus = strprintf(" %.0f khash/s", dHashesPerSec/1000.0);
- UIThreadCall(bind(CalledSetStatusBar, strStatus, 0));
- static int64 nLogTime;
- if (GetTime() - nLogTime > 30 * 60)
- {
- nLogTime = GetTime();
- printf("%s ", DateTimeStrFormat("%x %H:%M", GetTime()).c_str());
- printf("hashmeter %3d CPUs %6.0f khash/s\n", vnThreadsRunning[3], dHashesPerSec/1000.0);
- }
- }
- }
- }
-
- // Check for stop or if block needs to be rebuilt
- if (fShutdown)
- return;
- if (!fGenerateBitcoins)
- return;
- if (fLimitProcessors && vnThreadsRunning[3] > nLimitProcessors)
- return;
- if (vNodes.empty())
- break;
- if (tmp.block.nNonce == 0)
- break;
- if (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60)
- break;
- if (pindexPrev != pindexBest)
- {
- // Pause generating during initial download
- if (GetTime() - nStart < 20)
- {
- CBlockIndex* pindexTmp;
- do
- {
- pindexTmp = pindexBest;
- for (int i = 0; i < 10; i++)
- {
- Sleep(1000);
- if (fShutdown)
- return;
- }
- }
- while (pindexTmp != pindexBest);
- }
- break;
- }
-
- tmp.block.nTime = pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
- }
- }
- }
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// Actions
-//
-
-
-int64 GetBalance()
-{
- int64 nStart = GetTimeMillis();
-
- int64 nTotal = 0;
- CRITICAL_BLOCK(cs_mapWallet)
- {
- for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
- {
- CWalletTx* pcoin = &(*it).second;
- if (!pcoin->IsFinal() || pcoin->fSpent)
- continue;
- nTotal += pcoin->GetCredit(true);
- }
- }
-
- //printf("GetBalance() %"PRI64d"ms\n", GetTimeMillis() - nStart);
- return nTotal;
-}
-
-
-
-bool SelectCoins(int64 nTargetValue, set<CWalletTx*>& setCoinsRet)
-{
- setCoinsRet.clear();
-
- // List of values less than target
- int64 nLowestLarger = INT64_MAX;
- CWalletTx* pcoinLowestLarger = NULL;
- vector<pair<int64, CWalletTx*> > vValue;
- int64 nTotalLower = 0;
-
- CRITICAL_BLOCK(cs_mapWallet)
- {
- for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
- {
- CWalletTx* pcoin = &(*it).second;
- if (!pcoin->IsFinal() || pcoin->fSpent)
- continue;
- int64 n = pcoin->GetCredit();
- if (n <= 0)
- continue;
- if (n < nTargetValue)
- {
- vValue.push_back(make_pair(n, pcoin));
- nTotalLower += n;
- }
- else if (n == nTargetValue)
- {
- setCoinsRet.insert(pcoin);
- return true;
- }
- else if (n < nLowestLarger)
- {
- nLowestLarger = n;
- pcoinLowestLarger = pcoin;
- }
- }
- }
-
- if (nTotalLower < nTargetValue)
- {
- if (pcoinLowestLarger == NULL)
- return false;
- setCoinsRet.insert(pcoinLowestLarger);
- return true;
- }
-
- // Solve subset sum by stochastic approximation
- sort(vValue.rbegin(), vValue.rend());
- vector<char> vfIncluded;
- vector<char> vfBest(vValue.size(), true);
- int64 nBest = nTotalLower;
-
- for (int nRep = 0; nRep < 1000 && nBest != nTargetValue; nRep++)
- {
- vfIncluded.assign(vValue.size(), false);
- int64 nTotal = 0;
- bool fReachedTarget = false;
- for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++)
- {
- for (int i = 0; i < vValue.size(); i++)
- {
- if (nPass == 0 ? rand() % 2 : !vfIncluded[i])
- {
- nTotal += vValue[i].first;
- vfIncluded[i] = true;
- if (nTotal >= nTargetValue)
- {
- fReachedTarget = true;
- if (nTotal < nBest)
- {
- nBest = nTotal;
- vfBest = vfIncluded;
- }
- nTotal -= vValue[i].first;
- vfIncluded[i] = false;
- }
- }
- }
- }
- }
-
- // If the next larger is still closer, return it
- if (pcoinLowestLarger && nLowestLarger - nTargetValue <= nBest - nTargetValue)
- setCoinsRet.insert(pcoinLowestLarger);
- else
- {
- for (int i = 0; i < vValue.size(); i++)
- if (vfBest[i])
- setCoinsRet.insert(vValue[i].second);
-
- //// debug print
- printf("SelectCoins() best subset: ");
- for (int i = 0; i < vValue.size(); i++)
- if (vfBest[i])
- printf("%s ", FormatMoney(vValue[i].first).c_str());
- printf("total %s\n", FormatMoney(nBest).c_str());
- }
-
- return true;
-}
-
-
-
-
-bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CKey& keyRet, int64& nFeeRequiredRet)
-{
- nFeeRequiredRet = 0;
- CRITICAL_BLOCK(cs_main)
- {
- // txdb must be opened before the mapWallet lock
- CTxDB txdb("r");
- CRITICAL_BLOCK(cs_mapWallet)
- {
- int64 nFee = nTransactionFee;
- loop
- {
- wtxNew.vin.clear();
- wtxNew.vout.clear();
- wtxNew.fFromMe = true;
- if (nValue < 0)
- return false;
- int64 nValueOut = nValue;
- int64 nTotalValue = nValue + nFee;
-
- // Choose coins to use
- set<CWalletTx*> setCoins;
- if (!SelectCoins(nTotalValue, setCoins))
- return false;
- int64 nValueIn = 0;
- foreach(CWalletTx* pcoin, setCoins)
- nValueIn += pcoin->GetCredit();
-
- // Fill a vout to the payee
- bool fChangeFirst = GetRand(2);
- if (!fChangeFirst)
- wtxNew.vout.push_back(CTxOut(nValueOut, scriptPubKey));
-
- // Fill a vout back to self with any change
- if (nValueIn > nTotalValue)
- {
- // Note: We use a new key here to keep it from being obvious which side is the change.
- // The drawback is that by not reusing a previous key, the change may be lost if a
- // backup is restored, if the backup doesn't have the new private key for the change.
- // If we reused the old key, it would be possible to add code to look for and
- // rediscover unknown transactions that were written with keys of ours to recover
- // post-backup change.
-
- // New private key
- if (keyRet.IsNull())
- keyRet.MakeNewKey();
-
- // Fill a vout to ourself, using same address type as the payment
- CScript scriptChange;
- if (scriptPubKey.GetBitcoinAddressHash160() != 0)
- scriptChange.SetBitcoinAddress(keyRet.GetPubKey());
- else
- scriptChange << keyRet.GetPubKey() << OP_CHECKSIG;
- wtxNew.vout.push_back(CTxOut(nValueIn - nTotalValue, scriptChange));
- }
-
- // Fill a vout to the payee
- if (fChangeFirst)
- wtxNew.vout.push_back(CTxOut(nValueOut, scriptPubKey));
-
- // Fill vin
- foreach(CWalletTx* pcoin, setCoins)
- for (int nOut = 0; nOut < pcoin->vout.size(); nOut++)
- if (pcoin->vout[nOut].IsMine())
- wtxNew.vin.push_back(CTxIn(pcoin->GetHash(), nOut));
-
- // Sign
- int nIn = 0;
- foreach(CWalletTx* pcoin, setCoins)
- for (int nOut = 0; nOut < pcoin->vout.size(); nOut++)
- if (pcoin->vout[nOut].IsMine())
- SignSignature(*pcoin, wtxNew, nIn++);
-
- // Check that enough fee is included
- if (nFee < wtxNew.GetMinFee())
- {
- nFee = nFeeRequiredRet = wtxNew.GetMinFee();
- continue;
- }
-
- // Fill vtxPrev by copying from previous transactions vtxPrev
- wtxNew.AddSupportingTransactions(txdb);
- wtxNew.fTimeReceivedIsTxTime = true;
-
- break;
- }
- }
- }
- return true;
-}
-
-// Call after CreateTransaction unless you want to abort
-bool CommitTransaction(CWalletTx& wtxNew, const CKey& key)
-{
- CRITICAL_BLOCK(cs_main)
- {
- printf("CommitTransaction:\n%s", wtxNew.ToString().c_str());
- CRITICAL_BLOCK(cs_mapWallet)
- {
- // This is only to keep the database open to defeat the auto-flush for the
- // duration of this scope. This is the only place where this optimization
- // maybe makes sense; please don't do it anywhere else.
- CWalletDB walletdb("r");
-
- // Add the change's private key to wallet
- if (!key.IsNull() && !AddKey(key))
- throw runtime_error("CommitTransaction() : AddKey failed\n");
-
- // Add tx to wallet, because if it has change it's also ours,
- // otherwise just for transaction history.
- AddToWallet(wtxNew);
-
- // Mark old coins as spent
- set<CWalletTx*> setCoins;
- foreach(const CTxIn& txin, wtxNew.vin)
- setCoins.insert(&mapWallet[txin.prevout.hash]);
- foreach(CWalletTx* pcoin, setCoins)
- {
- pcoin->fSpent = true;
- pcoin->WriteToDisk();
- vWalletUpdated.push_back(pcoin->GetHash());
- }
- }
-
- // Track how many getdata requests our transaction gets
- CRITICAL_BLOCK(cs_mapRequestCount)
- mapRequestCount[wtxNew.GetHash()] = 0;
-
- // Broadcast
- if (!wtxNew.AcceptTransaction())
- {
- // This must not fail. The transaction has already been signed and recorded.
- printf("CommitTransaction() : Error: Transaction not valid");
- return false;
- }
- wtxNew.RelayWalletTransaction();
- }
- MainFrameRepaint();
- return true;
-}
-
-
-
-
-string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee)
-{
- CRITICAL_BLOCK(cs_main)
- {
- CKey key;
- int64 nFeeRequired;
- if (!CreateTransaction(scriptPubKey, nValue, wtxNew, key, nFeeRequired))
- {
- string strError;
- if (nValue + nFeeRequired > GetBalance())
- strError = strprintf(_("Error: This is an oversized transaction that requires a transaction fee of %s "), FormatMoney(nFeeRequired).c_str());
- else
- strError = _("Error: Transaction creation failed ");
- printf("SendMoney() : %s", strError.c_str());
- return strError;
- }
-
- if (fAskFee && !ThreadSafeAskFee(nFeeRequired, _("Sending..."), NULL))
- return "ABORTED";
-
- if (!CommitTransaction(wtxNew, key))
- return _("Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.");
- }
- MainFrameRepaint();
- return "";
-}
-
-
-
-string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew, bool fAskFee)
-{
- // Check amount
- if (nValue <= 0)
- return _("Invalid amount");
- if (nValue + nTransactionFee > GetBalance())
- return _("Insufficient funds");
-
- // Parse bitcoin address
- CScript scriptPubKey;
- if (!scriptPubKey.SetBitcoinAddress(strAddress))
- return _("Invalid bitcoin address");
-
- return SendMoney(scriptPubKey, nValue, wtxNew, fAskFee);
-}
+// Copyright (c) 2009-2010 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +#include "headers.h" +#include "sha.h" + + + + + +// +// Global state +// + +CCriticalSection cs_main; + +map<uint256, CTransaction> mapTransactions; +CCriticalSection cs_mapTransactions; +unsigned int nTransactionsUpdated = 0; +map<COutPoint, CInPoint> mapNextTx; + +map<uint256, CBlockIndex*> mapBlockIndex; +const uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"); +CBlockIndex* pindexGenesisBlock = NULL; +int nBestHeight = -1; +uint256 hashBestChain = 0; +CBlockIndex* pindexBest = NULL; +int64 nTimeBestReceived = 0; + +map<uint256, CBlock*> mapOrphanBlocks; +multimap<uint256, CBlock*> mapOrphanBlocksByPrev; + +map<uint256, CDataStream*> mapOrphanTransactions; +multimap<uint256, CDataStream*> mapOrphanTransactionsByPrev; + +map<uint256, CWalletTx> mapWallet; +vector<uint256> vWalletUpdated; +CCriticalSection cs_mapWallet; + +map<vector<unsigned char>, CPrivKey> mapKeys; +map<uint160, vector<unsigned char> > mapPubKeys; +CCriticalSection cs_mapKeys; +CKey keyUser; + +map<uint256, int> mapRequestCount; +CCriticalSection cs_mapRequestCount; + +map<string, string> mapAddressBook; +CCriticalSection cs_mapAddressBook; + +vector<unsigned char> vchDefaultKey; + +// Settings +int fGenerateBitcoins = false; +int64 nTransactionFee = 0; +CAddress addrIncoming; +int fLimitProcessors = false; +int nLimitProcessors = 1; +int fMinimizeToTray = true; +int fMinimizeOnClose = true; + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// mapKeys +// + +bool AddKey(const CKey& key) +{ + CRITICAL_BLOCK(cs_mapKeys) + { + mapKeys[key.GetPubKey()] = key.GetPrivKey(); + mapPubKeys[Hash160(key.GetPubKey())] = key.GetPubKey(); + } + return CWalletDB().WriteKey(key.GetPubKey(), key.GetPrivKey()); +} + +vector<unsigned char> GenerateNewKey() +{ + CKey key; + key.MakeNewKey(); + if (!AddKey(key)) + throw runtime_error("GenerateNewKey() : AddKey failed\n"); + return key.GetPubKey(); +} + + + + +////////////////////////////////////////////////////////////////////////////// +// +// mapWallet +// + +bool AddToWallet(const CWalletTx& wtxIn) +{ + uint256 hash = wtxIn.GetHash(); + CRITICAL_BLOCK(cs_mapWallet) + { + // Inserts only if not already there, returns tx inserted or tx found + pair<map<uint256, CWalletTx>::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn)); + CWalletTx& wtx = (*ret.first).second; + bool fInsertedNew = ret.second; + if (fInsertedNew) + wtx.nTimeReceived = GetAdjustedTime(); + + bool fUpdated = false; + if (!fInsertedNew) + { + // Merge + if (wtxIn.hashBlock != 0 && wtxIn.hashBlock != wtx.hashBlock) + { + wtx.hashBlock = wtxIn.hashBlock; + fUpdated = true; + } + if (wtxIn.nIndex != -1 && (wtxIn.vMerkleBranch != wtx.vMerkleBranch || wtxIn.nIndex != wtx.nIndex)) + { + wtx.vMerkleBranch = wtxIn.vMerkleBranch; + wtx.nIndex = wtxIn.nIndex; + fUpdated = true; + } + if (wtxIn.fFromMe && wtxIn.fFromMe != wtx.fFromMe) + { + wtx.fFromMe = wtxIn.fFromMe; + fUpdated = true; + } + if (wtxIn.fSpent && wtxIn.fSpent != wtx.fSpent) + { + wtx.fSpent = wtxIn.fSpent; + fUpdated = true; + } + } + + //// debug print + printf("AddToWallet %s %s%s\n", wtxIn.GetHash().ToString().substr(0,6).c_str(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : "")); + + // Write to disk + if (fInsertedNew || fUpdated) + if (!wtx.WriteToDisk()) + return false; + + // If default receiving address gets used, replace it with a new one + CScript scriptDefaultKey; + scriptDefaultKey.SetBitcoinAddress(vchDefaultKey); + foreach(const CTxOut& txout, wtx.vout) + { + if (txout.scriptPubKey == scriptDefaultKey) + { + CWalletDB walletdb; + walletdb.WriteDefaultKey(GenerateNewKey()); + walletdb.WriteName(PubKeyToAddress(vchDefaultKey), ""); + } + } + + // Notify UI + vWalletUpdated.push_back(hash); + } + + // Refresh UI + MainFrameRepaint(); + return true; +} + +bool AddToWalletIfMine(const CTransaction& tx, const CBlock* pblock) +{ + if (tx.IsMine() || mapWallet.count(tx.GetHash())) + { + CWalletTx wtx(tx); + // Get merkle branch if transaction was found in a block + if (pblock) + wtx.SetMerkleBranch(pblock); + return AddToWallet(wtx); + } + return true; +} + +bool EraseFromWallet(uint256 hash) +{ + CRITICAL_BLOCK(cs_mapWallet) + { + if (mapWallet.erase(hash)) + CWalletDB().EraseTx(hash); + } + return true; +} + +void WalletUpdateSpent(const COutPoint& prevout) +{ + // Anytime a signature is successfully verified, it's proof the outpoint is spent. + // Update the wallet spent flag if it doesn't know due to wallet.dat being + // restored from backup or the user making copies of wallet.dat. + CRITICAL_BLOCK(cs_mapWallet) + { + map<uint256, CWalletTx>::iterator mi = mapWallet.find(prevout.hash); + if (mi != mapWallet.end()) + { + CWalletTx& wtx = (*mi).second; + if (!wtx.fSpent && wtx.vout[prevout.n].IsMine()) + { + printf("WalletUpdateSpent found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str()); + wtx.fSpent = true; + wtx.WriteToDisk(); + vWalletUpdated.push_back(prevout.hash); + } + } + } +} + + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// mapOrphanTransactions +// + +void AddOrphanTx(const CDataStream& vMsg) +{ + CTransaction tx; + CDataStream(vMsg) >> tx; + uint256 hash = tx.GetHash(); + if (mapOrphanTransactions.count(hash)) + return; + CDataStream* pvMsg = mapOrphanTransactions[hash] = new CDataStream(vMsg); + foreach(const CTxIn& txin, tx.vin) + mapOrphanTransactionsByPrev.insert(make_pair(txin.prevout.hash, pvMsg)); +} + +void EraseOrphanTx(uint256 hash) +{ + if (!mapOrphanTransactions.count(hash)) + return; + const CDataStream* pvMsg = mapOrphanTransactions[hash]; + CTransaction tx; + CDataStream(*pvMsg) >> tx; + foreach(const CTxIn& txin, tx.vin) + { + for (multimap<uint256, CDataStream*>::iterator mi = mapOrphanTransactionsByPrev.lower_bound(txin.prevout.hash); + mi != mapOrphanTransactionsByPrev.upper_bound(txin.prevout.hash);) + { + if ((*mi).second == pvMsg) + mapOrphanTransactionsByPrev.erase(mi++); + else + mi++; + } + } + delete pvMsg; + mapOrphanTransactions.erase(hash); +} + + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CTransaction +// + +bool CTxIn::IsMine() const +{ + CRITICAL_BLOCK(cs_mapWallet) + { + map<uint256, CWalletTx>::iterator mi = mapWallet.find(prevout.hash); + if (mi != mapWallet.end()) + { + const CWalletTx& prev = (*mi).second; + if (prevout.n < prev.vout.size()) + if (prev.vout[prevout.n].IsMine()) + return true; + } + } + return false; +} + +int64 CTxIn::GetDebit() const +{ + CRITICAL_BLOCK(cs_mapWallet) + { + map<uint256, CWalletTx>::iterator mi = mapWallet.find(prevout.hash); + if (mi != mapWallet.end()) + { + const CWalletTx& prev = (*mi).second; + if (prevout.n < prev.vout.size()) + if (prev.vout[prevout.n].IsMine()) + return prev.vout[prevout.n].nValue; + } + } + return 0; +} + +int64 CWalletTx::GetTxTime() const +{ + if (!fTimeReceivedIsTxTime && hashBlock != 0) + { + // If we did not receive the transaction directly, we rely on the block's + // time to figure out when it happened. We use the median over a range + // of blocks to try to filter out inaccurate block times. + map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock); + if (mi != mapBlockIndex.end()) + { + CBlockIndex* pindex = (*mi).second; + if (pindex) + return pindex->GetMedianTime(); + } + } + return nTimeReceived; +} + +int CWalletTx::GetRequestCount() const +{ + // Returns -1 if it wasn't being tracked + int nRequests = -1; + CRITICAL_BLOCK(cs_mapRequestCount) + { + if (IsCoinBase()) + { + // Generated block + if (hashBlock != 0) + { + map<uint256, int>::iterator mi = mapRequestCount.find(hashBlock); + if (mi != mapRequestCount.end()) + nRequests = (*mi).second; + } + } + else + { + // Did anyone request this transaction? + map<uint256, int>::iterator mi = mapRequestCount.find(GetHash()); + if (mi != mapRequestCount.end()) + { + nRequests = (*mi).second; + + // How about the block it's in? + if (nRequests == 0 && hashBlock != 0) + { + map<uint256, int>::iterator mi = mapRequestCount.find(hashBlock); + if (mi != mapRequestCount.end()) + nRequests = (*mi).second; + else + nRequests = 1; // If it's in someone else's block it must have got out + } + } + } + } + return nRequests; +} + + + + +int CMerkleTx::SetMerkleBranch(const CBlock* pblock) +{ + if (fClient) + { + if (hashBlock == 0) + return 0; + } + else + { + CBlock blockTmp; + if (pblock == NULL) + { + // Load the block this tx is in + CTxIndex txindex; + if (!CTxDB("r").ReadTxIndex(GetHash(), txindex)) + return 0; + if (!blockTmp.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos)) + return 0; + pblock = &blockTmp; + } + + // Update the tx's hashBlock + hashBlock = pblock->GetHash(); + + // Locate the transaction + for (nIndex = 0; nIndex < pblock->vtx.size(); nIndex++) + if (pblock->vtx[nIndex] == *(CTransaction*)this) + break; + if (nIndex == pblock->vtx.size()) + { + vMerkleBranch.clear(); + nIndex = -1; + printf("ERROR: SetMerkleBranch() : couldn't find tx in block\n"); + return 0; + } + + // Fill in merkle branch + vMerkleBranch = pblock->GetMerkleBranch(nIndex); + } + + // Is the tx in a block that's in the main chain + map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock); + if (mi == mapBlockIndex.end()) + return 0; + CBlockIndex* pindex = (*mi).second; + if (!pindex || !pindex->IsInMainChain()) + return 0; + + return pindexBest->nHeight - pindex->nHeight + 1; +} + + + +void CWalletTx::AddSupportingTransactions(CTxDB& txdb) +{ + vtxPrev.clear(); + + const int COPY_DEPTH = 3; + if (SetMerkleBranch() < COPY_DEPTH) + { + vector<uint256> vWorkQueue; + foreach(const CTxIn& txin, vin) + vWorkQueue.push_back(txin.prevout.hash); + + // This critsect is OK because txdb is already open + CRITICAL_BLOCK(cs_mapWallet) + { + map<uint256, const CMerkleTx*> mapWalletPrev; + set<uint256> setAlreadyDone; + for (int i = 0; i < vWorkQueue.size(); i++) + { + uint256 hash = vWorkQueue[i]; + if (setAlreadyDone.count(hash)) + continue; + setAlreadyDone.insert(hash); + + CMerkleTx tx; + if (mapWallet.count(hash)) + { + tx = mapWallet[hash]; + foreach(const CMerkleTx& txWalletPrev, mapWallet[hash].vtxPrev) + mapWalletPrev[txWalletPrev.GetHash()] = &txWalletPrev; + } + else if (mapWalletPrev.count(hash)) + { + tx = *mapWalletPrev[hash]; + } + else if (!fClient && txdb.ReadDiskTx(hash, tx)) + { + ; + } + else + { + printf("ERROR: AddSupportingTransactions() : unsupported transaction\n"); + continue; + } + + int nDepth = tx.SetMerkleBranch(); + vtxPrev.push_back(tx); + + if (nDepth < COPY_DEPTH) + foreach(const CTxIn& txin, tx.vin) + vWorkQueue.push_back(txin.prevout.hash); + } + } + } + + reverse(vtxPrev.begin(), vtxPrev.end()); +} + + + + + + + + + + + +bool CTransaction::AcceptTransaction(CTxDB& txdb, bool fCheckInputs, bool* pfMissingInputs) +{ + if (pfMissingInputs) + *pfMissingInputs = false; + + // Coinbase is only valid in a block, not as a loose transaction + if (IsCoinBase()) + return error("AcceptTransaction() : coinbase as individual tx"); + + if (!CheckTransaction()) + return error("AcceptTransaction() : CheckTransaction failed"); + + // To help v0.1.5 clients who would see it as a negative number + if (nLockTime > INT_MAX) + return error("AcceptTransaction() : not accepting nLockTime beyond 2038"); + + // Do we already have it? + uint256 hash = GetHash(); + CRITICAL_BLOCK(cs_mapTransactions) + if (mapTransactions.count(hash)) + return false; + if (fCheckInputs) + if (txdb.ContainsTx(hash)) + return false; + + // Check for conflicts with in-memory transactions + CTransaction* ptxOld = NULL; + for (int i = 0; i < vin.size(); i++) + { + COutPoint outpoint = vin[i].prevout; + if (mapNextTx.count(outpoint)) + { + // Allow replacing with a newer version of the same transaction + if (i != 0) + return false; + ptxOld = mapNextTx[outpoint].ptx; + if (!IsNewerThan(*ptxOld)) + return false; + for (int i = 0; i < vin.size(); i++) + { + COutPoint outpoint = vin[i].prevout; + if (!mapNextTx.count(outpoint) || mapNextTx[outpoint].ptx != ptxOld) + return false; + } + break; + } + } + + // Check against previous transactions + map<uint256, CTxIndex> mapUnused; + int64 nFees = 0; + if (fCheckInputs && !ConnectInputs(txdb, mapUnused, CDiskTxPos(1,1,1), 0, nFees, false, false)) + { + if (pfMissingInputs) + *pfMissingInputs = true; + return error("AcceptTransaction() : ConnectInputs failed %s", hash.ToString().substr(0,6).c_str()); + } + + // Store transaction in memory + CRITICAL_BLOCK(cs_mapTransactions) + { + if (ptxOld) + { + printf("mapTransaction.erase(%s) replacing with new version\n", ptxOld->GetHash().ToString().c_str()); + mapTransactions.erase(ptxOld->GetHash()); + } + AddToMemoryPool(); + } + + ///// are we sure this is ok when loading transactions or restoring block txes + // If updated, erase old tx from wallet + if (ptxOld) + EraseFromWallet(ptxOld->GetHash()); + + printf("AcceptTransaction(): accepted %s\n", hash.ToString().substr(0,6).c_str()); + return true; +} + + +bool CTransaction::AddToMemoryPool() +{ + // Add to memory pool without checking anything. Don't call this directly, + // call AcceptTransaction to properly check the transaction first. + CRITICAL_BLOCK(cs_mapTransactions) + { + uint256 hash = GetHash(); + mapTransactions[hash] = *this; + for (int i = 0; i < vin.size(); i++) + mapNextTx[vin[i].prevout] = CInPoint(&mapTransactions[hash], i); + nTransactionsUpdated++; + } + return true; +} + + +bool CTransaction::RemoveFromMemoryPool() +{ + // Remove transaction from memory pool + CRITICAL_BLOCK(cs_mapTransactions) + { + foreach(const CTxIn& txin, vin) + mapNextTx.erase(txin.prevout); + mapTransactions.erase(GetHash()); + nTransactionsUpdated++; + } + return true; +} + + + + + + +int CMerkleTx::GetDepthInMainChain(int& nHeightRet) const +{ + if (hashBlock == 0 || nIndex == -1) + return 0; + + // Find the block it claims to be in + map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock); + if (mi == mapBlockIndex.end()) + return 0; + CBlockIndex* pindex = (*mi).second; + if (!pindex || !pindex->IsInMainChain()) + return 0; + + // Make sure the merkle branch connects to this block + if (!fMerkleVerified) + { + if (CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex) != pindex->hashMerkleRoot) + return 0; + fMerkleVerified = true; + } + + nHeightRet = pindex->nHeight; + return pindexBest->nHeight - pindex->nHeight + 1; +} + + +int CMerkleTx::GetBlocksToMaturity() const +{ + if (!IsCoinBase()) + return 0; + return max(0, (COINBASE_MATURITY+20) - GetDepthInMainChain()); +} + + +bool CMerkleTx::AcceptTransaction(CTxDB& txdb, bool fCheckInputs) +{ + if (fClient) + { + if (!IsInMainChain() && !ClientConnectInputs()) + return false; + return CTransaction::AcceptTransaction(txdb, false); + } + else + { + return CTransaction::AcceptTransaction(txdb, fCheckInputs); + } +} + + + +bool CWalletTx::AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs) +{ + CRITICAL_BLOCK(cs_mapTransactions) + { + foreach(CMerkleTx& tx, vtxPrev) + { + if (!tx.IsCoinBase()) + { + uint256 hash = tx.GetHash(); + if (!mapTransactions.count(hash) && !txdb.ContainsTx(hash)) + tx.AcceptTransaction(txdb, fCheckInputs); + } + } + if (!IsCoinBase()) + return AcceptTransaction(txdb, fCheckInputs); + } + return true; +} + +void ReacceptWalletTransactions() +{ + CTxDB txdb("r"); + CRITICAL_BLOCK(cs_mapWallet) + { + foreach(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet) + { + CWalletTx& wtx = item.second; + if (wtx.fSpent && wtx.IsCoinBase()) + continue; + + CTxIndex txindex; + if (txdb.ReadTxIndex(wtx.GetHash(), txindex)) + { + // Update fSpent if a tx got spent somewhere else by a copy of wallet.dat + if (!wtx.fSpent) + { + if (txindex.vSpent.size() != wtx.vout.size()) + { + printf("ERROR: ReacceptWalletTransactions() : txindex.vSpent.size() %d != wtx.vout.size() %d\n", txindex.vSpent.size(), wtx.vout.size()); + continue; + } + for (int i = 0; i < txindex.vSpent.size(); i++) + { + if (!txindex.vSpent[i].IsNull() && wtx.vout[i].IsMine()) + { + printf("ReacceptWalletTransactions found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str()); + wtx.fSpent = true; + wtx.WriteToDisk(); + break; + } + } + } + } + else + { + // Reaccept any txes of ours that aren't already in a block + if (!wtx.IsCoinBase()) + wtx.AcceptWalletTransaction(txdb, false); + } + } + } +} + + +void CWalletTx::RelayWalletTransaction(CTxDB& txdb) +{ + foreach(const CMerkleTx& tx, vtxPrev) + { + if (!tx.IsCoinBase()) + { + uint256 hash = tx.GetHash(); + if (!txdb.ContainsTx(hash)) + RelayMessage(CInv(MSG_TX, hash), (CTransaction)tx); + } + } + if (!IsCoinBase()) + { + uint256 hash = GetHash(); + if (!txdb.ContainsTx(hash)) + { + printf("Relaying wtx %s\n", hash.ToString().substr(0,6).c_str()); + RelayMessage(CInv(MSG_TX, hash), (CTransaction)*this); + } + } +} + +void ResendWalletTransactions() +{ + // Do this infrequently and randomly to avoid giving away + // that these are our transactions. + static int64 nNextTime; + if (GetTime() < nNextTime) + return; + bool fFirst = (nNextTime == 0); + nNextTime = GetTime() + GetRand(120 * 60); + if (fFirst) + return; + + // Rebroadcast any of our txes that aren't in a block yet + printf("ResendWalletTransactions()\n"); + CTxDB txdb("r"); + CRITICAL_BLOCK(cs_mapWallet) + { + // Sort them in chronological order + multimap<unsigned int, CWalletTx*> mapSorted; + foreach(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet) + { + CWalletTx& wtx = item.second; + // Don't rebroadcast until it's had plenty of time that + // it should have gotten in already by now. + if (nTimeBestReceived - wtx.nTimeReceived > 60 * 60) + mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx)); + } + foreach(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted) + { + CWalletTx& wtx = *item.second; + wtx.RelayWalletTransaction(txdb); + } + } +} + + + + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CBlock and CBlockIndex +// + +bool CBlock::ReadFromDisk(const CBlockIndex* pblockindex, bool fReadTransactions) +{ + return ReadFromDisk(pblockindex->nFile, pblockindex->nBlockPos, fReadTransactions); +} + +uint256 GetOrphanRoot(const CBlock* pblock) +{ + // Work back to the first block in the orphan chain + while (mapOrphanBlocks.count(pblock->hashPrevBlock)) + pblock = mapOrphanBlocks[pblock->hashPrevBlock]; + return pblock->GetHash(); +} + +int64 CBlock::GetBlockValue(int64 nFees) const +{ + int64 nSubsidy = 50 * COIN; + + // Subsidy is cut in half every 4 years + nSubsidy >>= (nBestHeight / 210000); + + return nSubsidy + nFees; +} + +unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast) +{ + const unsigned int nTargetTimespan = 14 * 24 * 60 * 60; // two weeks + const unsigned int nTargetSpacing = 10 * 60; + const unsigned int nInterval = nTargetTimespan / nTargetSpacing; + + // Genesis block + if (pindexLast == NULL) + return bnProofOfWorkLimit.GetCompact(); + + // Only change once per interval + if ((pindexLast->nHeight+1) % nInterval != 0) + return pindexLast->nBits; + + // Go back by what we want to be 14 days worth of blocks + const CBlockIndex* pindexFirst = pindexLast; + for (int i = 0; pindexFirst && i < nInterval-1; i++) + pindexFirst = pindexFirst->pprev; + assert(pindexFirst); + + // Limit adjustment step + unsigned int nActualTimespan = pindexLast->nTime - pindexFirst->nTime; + printf(" nActualTimespan = %d before bounds\n", nActualTimespan); + if (nActualTimespan < nTargetTimespan/4) + nActualTimespan = nTargetTimespan/4; + if (nActualTimespan > nTargetTimespan*4) + nActualTimespan = nTargetTimespan*4; + + // Retarget + CBigNum bnNew; + bnNew.SetCompact(pindexLast->nBits); + bnNew *= nActualTimespan; + bnNew /= nTargetTimespan; + + if (bnNew > bnProofOfWorkLimit) + bnNew = bnProofOfWorkLimit; + + /// debug print + printf("GetNextWorkRequired RETARGET\n"); + printf("nTargetTimespan = %d nActualTimespan = %d\n", nTargetTimespan, nActualTimespan); + printf("Before: %08x %s\n", pindexLast->nBits, CBigNum().SetCompact(pindexLast->nBits).getuint256().ToString().c_str()); + printf("After: %08x %s\n", bnNew.GetCompact(), bnNew.getuint256().ToString().c_str()); + + return bnNew.GetCompact(); +} + + + + + + + + + +bool CTransaction::DisconnectInputs(CTxDB& txdb) +{ + // Relinquish previous transactions' spent pointers + if (!IsCoinBase()) + { + foreach(const CTxIn& txin, vin) + { + COutPoint prevout = txin.prevout; + + // Get prev txindex from disk + CTxIndex txindex; + if (!txdb.ReadTxIndex(prevout.hash, txindex)) + return error("DisconnectInputs() : ReadTxIndex failed"); + + if (prevout.n >= txindex.vSpent.size()) + return error("DisconnectInputs() : prevout.n out of range"); + + // Mark outpoint as not spent + txindex.vSpent[prevout.n].SetNull(); + + // Write back + txdb.UpdateTxIndex(prevout.hash, txindex); + } + } + + // Remove transaction from index + if (!txdb.EraseTxIndex(*this)) + return error("DisconnectInputs() : EraseTxPos failed"); + + return true; +} + + +bool CTransaction::ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPool, CDiskTxPos posThisTx, int nHeight, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee) +{ + // Take over previous transactions' spent pointers + if (!IsCoinBase()) + { + int64 nValueIn = 0; + for (int i = 0; i < vin.size(); i++) + { + COutPoint prevout = vin[i].prevout; + + // Read txindex + CTxIndex txindex; + bool fFound = true; + if (fMiner && mapTestPool.count(prevout.hash)) + { + // Get txindex from current proposed changes + txindex = mapTestPool[prevout.hash]; + } + else + { + // Read txindex from txdb + fFound = txdb.ReadTxIndex(prevout.hash, txindex); + } + if (!fFound && (fBlock || fMiner)) + return fMiner ? false : error("ConnectInputs() : %s prev tx %s index entry not found", GetHash().ToString().substr(0,6).c_str(), prevout.hash.ToString().substr(0,6).c_str()); + + // Read txPrev + CTransaction txPrev; + if (!fFound || txindex.pos == CDiskTxPos(1,1,1)) + { + // Get prev tx from single transactions in memory + CRITICAL_BLOCK(cs_mapTransactions) + { + if (!mapTransactions.count(prevout.hash)) + return error("ConnectInputs() : %s mapTransactions prev not found %s", GetHash().ToString().substr(0,6).c_str(), prevout.hash.ToString().substr(0,6).c_str()); + txPrev = mapTransactions[prevout.hash]; + } + if (!fFound) + txindex.vSpent.resize(txPrev.vout.size()); + } + else + { + // Get prev tx from disk + if (!txPrev.ReadFromDisk(txindex.pos)) + return error("ConnectInputs() : %s ReadFromDisk prev tx %s failed", GetHash().ToString().substr(0,6).c_str(), prevout.hash.ToString().substr(0,6).c_str()); + } + + if (prevout.n >= txPrev.vout.size() || prevout.n >= txindex.vSpent.size()) + return error("ConnectInputs() : %s prevout.n out of range %d %d %d prev tx %s\n%s", GetHash().ToString().substr(0,6).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size(), prevout.hash.ToString().substr(0,6).c_str(), txPrev.ToString().c_str()); + + // If prev is coinbase, check that it's matured + if (txPrev.IsCoinBase()) + for (CBlockIndex* pindex = pindexBest; pindex && nBestHeight - pindex->nHeight < COINBASE_MATURITY-1; pindex = pindex->pprev) + if (pindex->nBlockPos == txindex.pos.nBlockPos && pindex->nFile == txindex.pos.nFile) + return error("ConnectInputs() : tried to spend coinbase at depth %d", nBestHeight - pindex->nHeight); + + // Verify signature + if (!VerifySignature(txPrev, *this, i)) + return error("ConnectInputs() : %s VerifySignature failed", GetHash().ToString().substr(0,6).c_str()); + + // Check for conflicts + if (!txindex.vSpent[prevout.n].IsNull()) + return fMiner ? false : error("ConnectInputs() : %s prev tx already used at %s", GetHash().ToString().substr(0,6).c_str(), txindex.vSpent[prevout.n].ToString().c_str()); + + // Mark outpoints as spent + txindex.vSpent[prevout.n] = posThisTx; + + // Write back + if (fBlock) + txdb.UpdateTxIndex(prevout.hash, txindex); + else if (fMiner) + mapTestPool[prevout.hash] = txindex; + + nValueIn += txPrev.vout[prevout.n].nValue; + } + + // Tally transaction fees + int64 nTxFee = nValueIn - GetValueOut(); + if (nTxFee < 0) + return error("ConnectInputs() : %s nTxFee < 0", GetHash().ToString().substr(0,6).c_str()); + if (nTxFee < nMinFee) + return false; + nFees += nTxFee; + } + + if (fBlock) + { + // Add transaction to disk index + if (!txdb.AddTxIndex(*this, posThisTx, nHeight)) + return error("ConnectInputs() : AddTxPos failed"); + } + else if (fMiner) + { + // Add transaction to test pool + mapTestPool[GetHash()] = CTxIndex(CDiskTxPos(1,1,1), vout.size()); + } + + return true; +} + + +bool CTransaction::ClientConnectInputs() +{ + if (IsCoinBase()) + return false; + + // Take over previous transactions' spent pointers + CRITICAL_BLOCK(cs_mapTransactions) + { + int64 nValueIn = 0; + for (int i = 0; i < vin.size(); i++) + { + // Get prev tx from single transactions in memory + COutPoint prevout = vin[i].prevout; + if (!mapTransactions.count(prevout.hash)) + return false; + CTransaction& txPrev = mapTransactions[prevout.hash]; + + if (prevout.n >= txPrev.vout.size()) + return false; + + // Verify signature + if (!VerifySignature(txPrev, *this, i)) + return error("ConnectInputs() : VerifySignature failed"); + + ///// this is redundant with the mapNextTx stuff, not sure which I want to get rid of + ///// this has to go away now that posNext is gone + // // Check for conflicts + // if (!txPrev.vout[prevout.n].posNext.IsNull()) + // return error("ConnectInputs() : prev tx already used"); + // + // // Flag outpoints as used + // txPrev.vout[prevout.n].posNext = posThisTx; + + nValueIn += txPrev.vout[prevout.n].nValue; + } + if (GetValueOut() > nValueIn) + return false; + } + + return true; +} + + + + +bool CBlock::DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex) +{ + // Disconnect in reverse order + for (int i = vtx.size()-1; i >= 0; i--) + if (!vtx[i].DisconnectInputs(txdb)) + return false; + + // Update block index on disk without changing it in memory. + // The memory index structure will be changed after the db commits. + if (pindex->pprev) + { + CDiskBlockIndex blockindexPrev(pindex->pprev); + blockindexPrev.hashNext = 0; + txdb.WriteBlockIndex(blockindexPrev); + } + + return true; +} + +bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex) +{ + //// issue here: it doesn't know the version + unsigned int nTxPos = pindex->nBlockPos + ::GetSerializeSize(CBlock(), SER_DISK) - 1 + GetSizeOfCompactSize(vtx.size()); + + map<uint256, CTxIndex> mapUnused; + int64 nFees = 0; + foreach(CTransaction& tx, vtx) + { + CDiskTxPos posThisTx(pindex->nFile, pindex->nBlockPos, nTxPos); + nTxPos += ::GetSerializeSize(tx, SER_DISK); + + if (!tx.ConnectInputs(txdb, mapUnused, posThisTx, pindex->nHeight, nFees, true, false)) + return false; + } + + if (vtx[0].GetValueOut() > GetBlockValue(nFees)) + return false; + + // Update block index on disk without changing it in memory. + // The memory index structure will be changed after the db commits. + if (pindex->pprev) + { + CDiskBlockIndex blockindexPrev(pindex->pprev); + blockindexPrev.hashNext = pindex->GetBlockHash(); + txdb.WriteBlockIndex(blockindexPrev); + } + + // Watch for transactions paying to me + foreach(CTransaction& tx, vtx) + AddToWalletIfMine(tx, this); + + return true; +} + + + +bool Reorganize(CTxDB& txdb, CBlockIndex* pindexNew) +{ + printf("REORGANIZE\n"); + + // Find the fork + CBlockIndex* pfork = pindexBest; + CBlockIndex* plonger = pindexNew; + while (pfork != plonger) + { + if (!(pfork = pfork->pprev)) + return error("Reorganize() : pfork->pprev is null"); + while (plonger->nHeight > pfork->nHeight) + if (!(plonger = plonger->pprev)) + return error("Reorganize() : plonger->pprev is null"); + } + + // List of what to disconnect + vector<CBlockIndex*> vDisconnect; + for (CBlockIndex* pindex = pindexBest; pindex != pfork; pindex = pindex->pprev) + vDisconnect.push_back(pindex); + + // List of what to connect + vector<CBlockIndex*> vConnect; + for (CBlockIndex* pindex = pindexNew; pindex != pfork; pindex = pindex->pprev) + vConnect.push_back(pindex); + reverse(vConnect.begin(), vConnect.end()); + + // Disconnect shorter branch + vector<CTransaction> vResurrect; + foreach(CBlockIndex* pindex, vDisconnect) + { + CBlock block; + if (!block.ReadFromDisk(pindex->nFile, pindex->nBlockPos)) + return error("Reorganize() : ReadFromDisk for disconnect failed"); + if (!block.DisconnectBlock(txdb, pindex)) + return error("Reorganize() : DisconnectBlock failed"); + + // Queue memory transactions to resurrect + foreach(const CTransaction& tx, block.vtx) + if (!tx.IsCoinBase()) + vResurrect.push_back(tx); + } + + // Connect longer branch + vector<CTransaction> vDelete; + for (int i = 0; i < vConnect.size(); i++) + { + CBlockIndex* pindex = vConnect[i]; + CBlock block; + if (!block.ReadFromDisk(pindex->nFile, pindex->nBlockPos)) + return error("Reorganize() : ReadFromDisk for connect failed"); + if (!block.ConnectBlock(txdb, pindex)) + { + // Invalid block, delete the rest of this branch + txdb.TxnAbort(); + for (int j = i; j < vConnect.size(); j++) + { + CBlockIndex* pindex = vConnect[j]; + pindex->EraseBlockFromDisk(); + txdb.EraseBlockIndex(pindex->GetBlockHash()); + mapBlockIndex.erase(pindex->GetBlockHash()); + delete pindex; + } + return error("Reorganize() : ConnectBlock failed"); + } + + // Queue memory transactions to delete + foreach(const CTransaction& tx, block.vtx) + vDelete.push_back(tx); + } + if (!txdb.WriteHashBestChain(pindexNew->GetBlockHash())) + return error("Reorganize() : WriteHashBestChain failed"); + + // Commit now because resurrecting could take some time + txdb.TxnCommit(); + + // Disconnect shorter branch + foreach(CBlockIndex* pindex, vDisconnect) + if (pindex->pprev) + pindex->pprev->pnext = NULL; + + // Connect longer branch + foreach(CBlockIndex* pindex, vConnect) + if (pindex->pprev) + pindex->pprev->pnext = pindex; + + // Resurrect memory transactions that were in the disconnected branch + foreach(CTransaction& tx, vResurrect) + tx.AcceptTransaction(txdb, false); + + // Delete redundant memory transactions that are in the connected branch + foreach(CTransaction& tx, vDelete) + tx.RemoveFromMemoryPool(); + + return true; +} + + +bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) +{ + // Check for duplicate + uint256 hash = GetHash(); + if (mapBlockIndex.count(hash)) + return error("AddToBlockIndex() : %s already exists", hash.ToString().substr(0,16).c_str()); + + // Construct new block index object + CBlockIndex* pindexNew = new CBlockIndex(nFile, nBlockPos, *this); + if (!pindexNew) + return error("AddToBlockIndex() : new CBlockIndex failed"); + map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first; + pindexNew->phashBlock = &((*mi).first); + map<uint256, CBlockIndex*>::iterator miPrev = mapBlockIndex.find(hashPrevBlock); + if (miPrev != mapBlockIndex.end()) + { + pindexNew->pprev = (*miPrev).second; + pindexNew->nHeight = pindexNew->pprev->nHeight + 1; + } + + CTxDB txdb; + txdb.TxnBegin(); + txdb.WriteBlockIndex(CDiskBlockIndex(pindexNew)); + + // New best + if (pindexNew->nHeight > nBestHeight) + { + if (pindexGenesisBlock == NULL && hash == hashGenesisBlock) + { + pindexGenesisBlock = pindexNew; + txdb.WriteHashBestChain(hash); + } + else if (hashPrevBlock == hashBestChain) + { + // Adding to current best branch + if (!ConnectBlock(txdb, pindexNew) || !txdb.WriteHashBestChain(hash)) + { + txdb.TxnAbort(); + pindexNew->EraseBlockFromDisk(); + mapBlockIndex.erase(pindexNew->GetBlockHash()); + delete pindexNew; + return error("AddToBlockIndex() : ConnectBlock failed"); + } + txdb.TxnCommit(); + pindexNew->pprev->pnext = pindexNew; + + // Delete redundant memory transactions + foreach(CTransaction& tx, vtx) + tx.RemoveFromMemoryPool(); + } + else + { + // New best branch + if (!Reorganize(txdb, pindexNew)) + { + txdb.TxnAbort(); + return error("AddToBlockIndex() : Reorganize failed"); + } + } + + // New best block + hashBestChain = hash; + pindexBest = pindexNew; + nBestHeight = pindexBest->nHeight; + nTimeBestReceived = GetTime(); + nTransactionsUpdated++; + printf("AddToBlockIndex: new best=%s height=%d\n", hashBestChain.ToString().substr(0,16).c_str(), nBestHeight); + } + + txdb.TxnCommit(); + txdb.Close(); + + if (pindexNew == pindexBest) + { + // Notify UI to display prev block's coinbase if it was ours + static uint256 hashPrevBestCoinBase; + CRITICAL_BLOCK(cs_mapWallet) + vWalletUpdated.push_back(hashPrevBestCoinBase); + hashPrevBestCoinBase = vtx[0].GetHash(); + } + + MainFrameRepaint(); + return true; +} + + + + +bool CBlock::CheckBlock() const +{ + // These are checks that are independent of context + // that can be verified before saving an orphan block. + + // Size limits + if (vtx.empty() || vtx.size() > MAX_SIZE || ::GetSerializeSize(*this, SER_DISK) > MAX_SIZE) + return error("CheckBlock() : size limits failed"); + + // Check timestamp + if (nTime > GetAdjustedTime() + 2 * 60 * 60) + return error("CheckBlock() : block timestamp too far in the future"); + + // First transaction must be coinbase, the rest must not be + if (vtx.empty() || !vtx[0].IsCoinBase()) + return error("CheckBlock() : first tx is not coinbase"); + for (int i = 1; i < vtx.size(); i++) + if (vtx[i].IsCoinBase()) + return error("CheckBlock() : more than one coinbase"); + + // Check transactions + foreach(const CTransaction& tx, vtx) + if (!tx.CheckTransaction()) + return error("CheckBlock() : CheckTransaction failed"); + + // Check proof of work matches claimed amount + if (CBigNum().SetCompact(nBits) > bnProofOfWorkLimit) + return error("CheckBlock() : nBits below minimum work"); + if (GetHash() > CBigNum().SetCompact(nBits).getuint256()) + return error("CheckBlock() : hash doesn't match nBits"); + + // Check merkleroot + if (hashMerkleRoot != BuildMerkleTree()) + return error("CheckBlock() : hashMerkleRoot mismatch"); + + return true; +} + +bool CBlock::AcceptBlock() +{ + // Check for duplicate + uint256 hash = GetHash(); + if (mapBlockIndex.count(hash)) + return error("AcceptBlock() : block already in mapBlockIndex"); + + // Get prev block index + map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashPrevBlock); + if (mi == mapBlockIndex.end()) + return error("AcceptBlock() : prev block not found"); + CBlockIndex* pindexPrev = (*mi).second; + + // Check timestamp against prev + if (nTime <= pindexPrev->GetMedianTimePast()) + return error("AcceptBlock() : block's timestamp is too early"); + + // Check that all transactions are finalized + foreach(const CTransaction& tx, vtx) + if (!tx.IsFinal(nTime)) + return error("AcceptBlock() : contains a non-final transaction"); + + // Check proof of work + if (nBits != GetNextWorkRequired(pindexPrev)) + return error("AcceptBlock() : incorrect proof of work"); + + // Write block to history file + if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK))) + return error("AcceptBlock() : out of disk space"); + unsigned int nFile; + unsigned int nBlockPos; + if (!WriteToDisk(!fClient, nFile, nBlockPos)) + return error("AcceptBlock() : WriteToDisk failed"); + if (!AddToBlockIndex(nFile, nBlockPos)) + return error("AcceptBlock() : AddToBlockIndex failed"); + + // Relay inventory, but don't relay old inventory during initial block download + if (hashBestChain == hash) + CRITICAL_BLOCK(cs_vNodes) + foreach(CNode* pnode, vNodes) + if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : 55000)) + pnode->PushInventory(CInv(MSG_BLOCK, hash)); + + return true; +} + +bool ProcessBlock(CNode* pfrom, CBlock* pblock) +{ + // Check for duplicate + uint256 hash = pblock->GetHash(); + if (mapBlockIndex.count(hash)) + return error("ProcessBlock() : already have block %d %s", mapBlockIndex[hash]->nHeight, hash.ToString().substr(0,16).c_str()); + if (mapOrphanBlocks.count(hash)) + return error("ProcessBlock() : already have block (orphan) %s", hash.ToString().substr(0,16).c_str()); + + // Preliminary checks + if (!pblock->CheckBlock()) + { + delete pblock; + return error("ProcessBlock() : CheckBlock FAILED"); + } + + // If don't already have its previous block, shunt it off to holding area until we get it + if (!mapBlockIndex.count(pblock->hashPrevBlock)) + { + printf("ProcessBlock: ORPHAN BLOCK, prev=%s\n", pblock->hashPrevBlock.ToString().substr(0,16).c_str()); + mapOrphanBlocks.insert(make_pair(hash, pblock)); + mapOrphanBlocksByPrev.insert(make_pair(pblock->hashPrevBlock, pblock)); + + // Ask this guy to fill in what we're missing + if (pfrom) + pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(pblock)); + return true; + } + + // Store to disk + if (!pblock->AcceptBlock()) + { + delete pblock; + return error("ProcessBlock() : AcceptBlock FAILED"); + } + delete pblock; + + // Recursively process any orphan blocks that depended on this one + vector<uint256> vWorkQueue; + vWorkQueue.push_back(hash); + for (int i = 0; i < vWorkQueue.size(); i++) + { + uint256 hashPrev = vWorkQueue[i]; + for (multimap<uint256, CBlock*>::iterator mi = mapOrphanBlocksByPrev.lower_bound(hashPrev); + mi != mapOrphanBlocksByPrev.upper_bound(hashPrev); + ++mi) + { + CBlock* pblockOrphan = (*mi).second; + if (pblockOrphan->AcceptBlock()) + vWorkQueue.push_back(pblockOrphan->GetHash()); + mapOrphanBlocks.erase(pblockOrphan->GetHash()); + delete pblockOrphan; + } + mapOrphanBlocksByPrev.erase(hashPrev); + } + + printf("ProcessBlock: ACCEPTED\n"); + return true; +} + + + + + + + + +template<typename Stream> +bool ScanMessageStart(Stream& s) +{ + // Scan ahead to the next pchMessageStart, which should normally be immediately + // at the file pointer. Leaves file pointer at end of pchMessageStart. + s.clear(0); + short prevmask = s.exceptions(0); + const char* p = BEGIN(pchMessageStart); + try + { + loop + { + char c; + s.read(&c, 1); + if (s.fail()) + { + s.clear(0); + s.exceptions(prevmask); + return false; + } + if (*p != c) + p = BEGIN(pchMessageStart); + if (*p == c) + { + if (++p == END(pchMessageStart)) + { + s.clear(0); + s.exceptions(prevmask); + return true; + } + } + } + } + catch (...) + { + s.clear(0); + s.exceptions(prevmask); + return false; + } +} + +bool CheckDiskSpace(int64 nAdditionalBytes) +{ + uint64 nFreeBytesAvailable = filesystem::space(GetDataDir()).available; + + // Check for 15MB because database could create another 10MB log file at any time + if (nFreeBytesAvailable < (int64)15000000 + nAdditionalBytes) + { + fShutdown = true; + printf("*** %s***\n", _("Warning: Disk space is low ")); +#if wxUSE_GUI + ThreadSafeMessageBox(_("Warning: Disk space is low "), "Bitcoin", wxOK | wxICON_EXCLAMATION); +#endif + CreateThread(Shutdown, NULL); + return false; + } + return true; +} + +FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode) +{ + if (nFile == -1) + return NULL; + FILE* file = fopen(strprintf("%s/blk%04d.dat", GetDataDir().c_str(), nFile).c_str(), pszMode); + if (!file) + return NULL; + if (nBlockPos != 0 && !strchr(pszMode, 'a') && !strchr(pszMode, 'w')) + { + if (fseek(file, nBlockPos, SEEK_SET) != 0) + { + fclose(file); + return NULL; + } + } + return file; +} + +static unsigned int nCurrentBlockFile = 1; + +FILE* AppendBlockFile(unsigned int& nFileRet) +{ + nFileRet = 0; + loop + { + FILE* file = OpenBlockFile(nCurrentBlockFile, 0, "ab"); + if (!file) + return NULL; + if (fseek(file, 0, SEEK_END) != 0) + return NULL; + // FAT32 filesize max 4GB, fseek and ftell max 2GB, so we must stay under 2GB + if (ftell(file) < 0x7F000000 - MAX_SIZE) + { + nFileRet = nCurrentBlockFile; + return file; + } + fclose(file); + nCurrentBlockFile++; + } +} + +bool LoadBlockIndex(bool fAllowNew) +{ + // + // Load block index + // + CTxDB txdb("cr"); + if (!txdb.LoadBlockIndex()) + return false; + txdb.Close(); + + // + // Init with genesis block + // + if (mapBlockIndex.empty()) + { + if (!fAllowNew) + return false; + + + // Genesis Block: + // GetHash() = 0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f + // hashMerkleRoot = 0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b + // txNew.vin[0].scriptSig = 486604799 4 0x736B6E616220726F662074756F6C69616220646E6F63657320666F206B6E697262206E6F20726F6C6C65636E61684320393030322F6E614A2F33302073656D695420656854 + // txNew.vout[0].nValue = 5000000000 + // txNew.vout[0].scriptPubKey = 0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704 OP_CHECKSIG + // block.nVersion = 1 + // block.nTime = 1231006505 + // block.nBits = 0x1d00ffff + // block.nNonce = 2083236893 + // CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=2083236893, vtx=1) + // CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0) + // CTxIn(COutPoint(000000, -1), coinbase 04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73) + // CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B) + // vMerkleTree: 4a5e1e + + // Genesis block + const char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks"; + CTransaction txNew; + txNew.vin.resize(1); + txNew.vout.resize(1); + txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); + txNew.vout[0].nValue = 50 * COIN; + CBigNum bnPubKey; + bnPubKey.SetHex("0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704"); + txNew.vout[0].scriptPubKey = CScript() << bnPubKey << OP_CHECKSIG; + CBlock block; + block.vtx.push_back(txNew); + block.hashPrevBlock = 0; + block.hashMerkleRoot = block.BuildMerkleTree(); + block.nVersion = 1; + block.nTime = 1231006505; + block.nBits = 0x1d00ffff; + block.nNonce = 2083236893; + + //// debug print + printf("%s\n", block.GetHash().ToString().c_str()); + printf("%s\n", block.hashMerkleRoot.ToString().c_str()); + printf("%s\n", hashGenesisBlock.ToString().c_str()); + txNew.vout[0].scriptPubKey.print(); + block.print(); + assert(block.hashMerkleRoot == uint256("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b")); + + assert(block.GetHash() == hashGenesisBlock); + + // Start new block file + unsigned int nFile; + unsigned int nBlockPos; + if (!block.WriteToDisk(!fClient, nFile, nBlockPos)) + return error("LoadBlockIndex() : writing genesis block to disk failed"); + if (!block.AddToBlockIndex(nFile, nBlockPos)) + return error("LoadBlockIndex() : genesis block not accepted"); + } + + return true; +} + + + +void PrintBlockTree() +{ + // precompute tree structure + map<CBlockIndex*, vector<CBlockIndex*> > mapNext; + for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi) + { + CBlockIndex* pindex = (*mi).second; + mapNext[pindex->pprev].push_back(pindex); + // test + //while (rand() % 3 == 0) + // mapNext[pindex->pprev].push_back(pindex); + } + + vector<pair<int, CBlockIndex*> > vStack; + vStack.push_back(make_pair(0, pindexGenesisBlock)); + + int nPrevCol = 0; + while (!vStack.empty()) + { + int nCol = vStack.back().first; + CBlockIndex* pindex = vStack.back().second; + vStack.pop_back(); + + // print split or gap + if (nCol > nPrevCol) + { + for (int i = 0; i < nCol-1; i++) + printf("| "); + printf("|\\\n"); + } + else if (nCol < nPrevCol) + { + for (int i = 0; i < nCol; i++) + printf("| "); + printf("|\n"); + } + nPrevCol = nCol; + + // print columns + for (int i = 0; i < nCol; i++) + printf("| "); + + // print item + CBlock block; + block.ReadFromDisk(pindex); + printf("%d (%u,%u) %s %s tx %d", + pindex->nHeight, + pindex->nFile, + pindex->nBlockPos, + block.GetHash().ToString().substr(0,16).c_str(), + DateTimeStrFormat("%x %H:%M:%S", block.nTime).c_str(), + block.vtx.size()); + + CRITICAL_BLOCK(cs_mapWallet) + { + if (mapWallet.count(block.vtx[0].GetHash())) + { + CWalletTx& wtx = mapWallet[block.vtx[0].GetHash()]; + printf(" mine: %d %d %d", wtx.GetDepthInMainChain(), wtx.GetBlocksToMaturity(), wtx.GetCredit()); + } + } + printf("\n"); + + + // put the main timechain first + vector<CBlockIndex*>& vNext = mapNext[pindex]; + for (int i = 0; i < vNext.size(); i++) + { + if (vNext[i]->pnext) + { + swap(vNext[0], vNext[i]); + break; + } + } + + // iterate children + for (int i = 0; i < vNext.size(); i++) + vStack.push_back(make_pair(nCol+i, vNext[i])); + } +} + + + + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// Messages +// + + +bool AlreadyHave(CTxDB& txdb, const CInv& inv) +{ + switch (inv.type) + { + case MSG_TX: return mapTransactions.count(inv.hash) || txdb.ContainsTx(inv.hash); + case MSG_BLOCK: return mapBlockIndex.count(inv.hash) || mapOrphanBlocks.count(inv.hash); + } + // Don't know what it is, just say we already got one + return true; +} + + + + + + + +bool ProcessMessages(CNode* pfrom) +{ + CDataStream& vRecv = pfrom->vRecv; + if (vRecv.empty()) + return true; + //if (fDebug) + // printf("ProcessMessages(%d bytes)\n", vRecv.size()); + + // + // Message format + // (4) message start + // (12) command + // (4) size + // (4) checksum + // (x) data + // + + loop + { + // Scan for message start + CDataStream::iterator pstart = search(vRecv.begin(), vRecv.end(), BEGIN(pchMessageStart), END(pchMessageStart)); + int nHeaderSize = vRecv.GetSerializeSize(CMessageHeader()); + if (vRecv.end() - pstart < nHeaderSize) + { + if (vRecv.size() > nHeaderSize) + { + printf("\n\nPROCESSMESSAGE MESSAGESTART NOT FOUND\n\n"); + vRecv.erase(vRecv.begin(), vRecv.end() - nHeaderSize); + } + break; + } + if (pstart - vRecv.begin() > 0) + printf("\n\nPROCESSMESSAGE SKIPPED %d BYTES\n\n", pstart - vRecv.begin()); + vRecv.erase(vRecv.begin(), pstart); + + // Read header + vector<char> vHeaderSave(vRecv.begin(), vRecv.begin() + nHeaderSize); + CMessageHeader hdr; + vRecv >> hdr; + if (!hdr.IsValid()) + { + printf("\n\nPROCESSMESSAGE: ERRORS IN HEADER %s\n\n\n", hdr.GetCommand().c_str()); + continue; + } + string strCommand = hdr.GetCommand(); + + // Message size + unsigned int nMessageSize = hdr.nMessageSize; + if (nMessageSize > vRecv.size()) + { + // Rewind and wait for rest of message + ///// need a mechanism to give up waiting for overlong message size error + vRecv.insert(vRecv.begin(), vHeaderSave.begin(), vHeaderSave.end()); + break; + } + + // Copy message to its own buffer + CDataStream vMsg(vRecv.begin(), vRecv.begin() + nMessageSize, vRecv.nType, vRecv.nVersion); + vRecv.ignore(nMessageSize); + + // Checksum + if (vRecv.GetVersion() >= 209) + { + uint256 hash = Hash(vMsg.begin(), vMsg.end()); + unsigned int nChecksum = 0; + memcpy(&nChecksum, &hash, sizeof(nChecksum)); + if (nChecksum != hdr.nChecksum) + { + printf("ProcessMessage(%s, %d bytes) : CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n", + strCommand.c_str(), nMessageSize, nChecksum, hdr.nChecksum); + continue; + } + } + + // Process message + bool fRet = false; + try + { + CRITICAL_BLOCK(cs_main) + fRet = ProcessMessage(pfrom, strCommand, vMsg); + if (fShutdown) + return true; + } + catch (std::ios_base::failure& e) + { + if (strstr(e.what(), "CDataStream::read() : end of data")) + { + // Allow exceptions from underlength message on vRecv + printf("ProcessMessage(%s, %d bytes) : Exception '%s' caught, normally caused by a message being shorter than its stated length\n", strCommand.c_str(), nMessageSize, e.what()); + } + else if (strstr(e.what(), ": size too large")) + { + // Allow exceptions from overlong size + printf("ProcessMessage(%s, %d bytes) : Exception '%s' caught\n", strCommand.c_str(), nMessageSize, e.what()); + } + else + { + PrintException(&e, "ProcessMessage()"); + } + } + catch (std::exception& e) { + PrintException(&e, "ProcessMessage()"); + } catch (...) { + PrintException(NULL, "ProcessMessage()"); + } + + if (!fRet) + printf("ProcessMessage(%s, %d bytes) FAILED\n", strCommand.c_str(), nMessageSize); + } + + vRecv.Compact(); + return true; +} + + + + +bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) +{ + static map<unsigned int, vector<unsigned char> > mapReuseKey; + RandAddSeedPerfmon(); + if (fDebug) + printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); + printf("received: %s (%d bytes)\n", strCommand.c_str(), vRecv.size()); + if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0) + { + printf("dropmessagestest DROPPING RECV MESSAGE\n"); + return true; + } + + + + + + if (strCommand == "version") + { + // Each connection can only send one version message + if (pfrom->nVersion != 0) + return false; + + int64 nTime; + CAddress addrMe; + CAddress addrFrom; + uint64 nNonce = 1; + string strSubVer; + vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe; + if (pfrom->nVersion == 10300) + pfrom->nVersion = 300; + if (pfrom->nVersion >= 106 && !vRecv.empty()) + vRecv >> addrFrom >> nNonce; + if (pfrom->nVersion >= 106 && !vRecv.empty()) + vRecv >> strSubVer; + if (pfrom->nVersion >= 209 && !vRecv.empty()) + vRecv >> pfrom->nStartingHeight; + + if (pfrom->nVersion == 0) + return false; + + // Disconnect if we connected to ourself + if (nNonce == nLocalHostNonce && nNonce > 1) + { + pfrom->fDisconnect = true; + return true; + } + + pfrom->fClient = !(pfrom->nServices & NODE_NETWORK); + if (pfrom->fClient) + { + pfrom->vSend.nType |= SER_BLOCKHEADERONLY; + pfrom->vRecv.nType |= SER_BLOCKHEADERONLY; + } + + AddTimeData(pfrom->addr.ip, nTime); + + // Change version + if (pfrom->nVersion >= 209) + pfrom->PushMessage("verack"); + pfrom->vSend.SetVersion(min(pfrom->nVersion, VERSION)); + if (pfrom->nVersion < 209) + pfrom->vRecv.SetVersion(min(pfrom->nVersion, VERSION)); + + // Ask the first connected node for block updates + static int nAskedForBlocks; + if (!pfrom->fClient && (nAskedForBlocks < 1 || vNodes.size() <= 1)) + { + nAskedForBlocks++; + pfrom->PushGetBlocks(pindexBest, uint256(0)); + } + + pfrom->fSuccessfullyConnected = true; + + printf("version message: version %d, blocks=%d\n", pfrom->nVersion, pfrom->nStartingHeight); + } + + + else if (pfrom->nVersion == 0) + { + // Must have a version message before anything else + return false; + } + + + else if (strCommand == "verack") + { + pfrom->vRecv.SetVersion(min(pfrom->nVersion, VERSION)); + } + + + else if (strCommand == "addr") + { + vector<CAddress> vAddr; + vRecv >> vAddr; + if (pfrom->nVersion < 200) // don't want addresses from 0.1.5 + return true; + if (vAddr.size() > 1000) + return error("message addr size() = %d", vAddr.size()); + + // Store the new addresses + foreach(CAddress& addr, vAddr) + { + if (fShutdown) + return true; + addr.nTime = GetAdjustedTime() - 2 * 60 * 60; + if (pfrom->fGetAddr || vAddr.size() > 10) + addr.nTime -= 5 * 24 * 60 * 60; + AddAddress(addr); + pfrom->AddAddressKnown(addr); + if (!pfrom->fGetAddr && addr.IsRoutable()) + { + // Relay to a limited number of other nodes + CRITICAL_BLOCK(cs_vNodes) + { + // Use deterministic randomness to send to + // the same places for an hour at a time + static uint256 hashSalt; + if (hashSalt == 0) + RAND_bytes((unsigned char*)&hashSalt, sizeof(hashSalt)); + uint256 hashRand = addr.ip ^ (GetTime()/3600) ^ hashSalt; + multimap<uint256, CNode*> mapMix; + foreach(CNode* pnode, vNodes) + mapMix.insert(make_pair(hashRand = Hash(BEGIN(hashRand), END(hashRand)), pnode)); + int nRelayNodes = 10; // reduce this to 5 when the network is large + for (multimap<uint256, CNode*>::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi) + ((*mi).second)->PushAddress(addr); + } + } + } + if (vAddr.size() < 1000) + pfrom->fGetAddr = false; + } + + + else if (strCommand == "inv") + { + vector<CInv> vInv; + vRecv >> vInv; + if (vInv.size() > 50000) + return error("message inv size() = %d", vInv.size()); + + CTxDB txdb("r"); + foreach(const CInv& inv, vInv) + { + if (fShutdown) + return true; + pfrom->AddInventoryKnown(inv); + + bool fAlreadyHave = AlreadyHave(txdb, inv); + printf(" got inventory: %s %s\n", inv.ToString().c_str(), fAlreadyHave ? "have" : "new"); + + if (!fAlreadyHave) + pfrom->AskFor(inv); + else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash)) + pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(mapOrphanBlocks[inv.hash])); + + // Track requests for our stuff + CRITICAL_BLOCK(cs_mapRequestCount) + { + map<uint256, int>::iterator mi = mapRequestCount.find(inv.hash); + if (mi != mapRequestCount.end()) + (*mi).second++; + } + } + } + + + else if (strCommand == "getdata") + { + vector<CInv> vInv; + vRecv >> vInv; + if (vInv.size() > 50000) + return error("message getdata size() = %d", vInv.size()); + + foreach(const CInv& inv, vInv) + { + if (fShutdown) + return true; + printf("received getdata for: %s\n", inv.ToString().c_str()); + + if (inv.type == MSG_BLOCK) + { + // Send block from disk + map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(inv.hash); + if (mi != mapBlockIndex.end()) + { + //// could optimize this to send header straight from blockindex for client + CBlock block; + block.ReadFromDisk((*mi).second, !pfrom->fClient); + pfrom->PushMessage("block", block); + + // Trigger them to send a getblocks request for the next batch of inventory + if (inv.hash == pfrom->hashContinue) + { + // Bypass PushInventory, this must send even if redundant, + // and we want it right after the last block so they don't + // wait for other stuff first. + vector<CInv> vInv; + vInv.push_back(CInv(MSG_BLOCK, hashBestChain)); + pfrom->PushMessage("inv", vInv); + pfrom->hashContinue = 0; + } + } + } + else if (inv.IsKnownType()) + { + // Send stream from relay memory + CRITICAL_BLOCK(cs_mapRelay) + { + map<CInv, CDataStream>::iterator mi = mapRelay.find(inv); + if (mi != mapRelay.end()) + pfrom->PushMessage(inv.GetCommand(), (*mi).second); + } + } + + // Track requests for our stuff + CRITICAL_BLOCK(cs_mapRequestCount) + { + map<uint256, int>::iterator mi = mapRequestCount.find(inv.hash); + if (mi != mapRequestCount.end()) + (*mi).second++; + } + } + } + + + else if (strCommand == "getblocks") + { + CBlockLocator locator; + uint256 hashStop; + vRecv >> locator >> hashStop; + + // Find the first block the caller has in the main chain + CBlockIndex* pindex = locator.GetBlockIndex(); + + // Send the rest of the chain + if (pindex) + pindex = pindex->pnext; + int nLimit = 500 + locator.GetDistanceBack(); + printf("getblocks %d to %s limit %d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,16).c_str(), nLimit); + for (; pindex; pindex = pindex->pnext) + { + if (pindex->GetBlockHash() == hashStop) + { + printf(" getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,16).c_str()); + break; + } + pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash())); + if (--nLimit <= 0) + { + // When this block is requested, we'll send an inv that'll make them + // getblocks the next batch of inventory. + printf(" getblocks stopping at limit %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,16).c_str()); + pfrom->hashContinue = pindex->GetBlockHash(); + break; + } + } + } + + + else if (strCommand == "tx") + { + vector<uint256> vWorkQueue; + CDataStream vMsg(vRecv); + CTransaction tx; + vRecv >> tx; + + CInv inv(MSG_TX, tx.GetHash()); + pfrom->AddInventoryKnown(inv); + + bool fMissingInputs = false; + if (tx.AcceptTransaction(true, &fMissingInputs)) + { + AddToWalletIfMine(tx, NULL); + RelayMessage(inv, vMsg); + mapAlreadyAskedFor.erase(inv); + vWorkQueue.push_back(inv.hash); + + // Recursively process any orphan transactions that depended on this one + for (int i = 0; i < vWorkQueue.size(); i++) + { + uint256 hashPrev = vWorkQueue[i]; + for (multimap<uint256, CDataStream*>::iterator mi = mapOrphanTransactionsByPrev.lower_bound(hashPrev); + mi != mapOrphanTransactionsByPrev.upper_bound(hashPrev); + ++mi) + { + const CDataStream& vMsg = *((*mi).second); + CTransaction tx; + CDataStream(vMsg) >> tx; + CInv inv(MSG_TX, tx.GetHash()); + + if (tx.AcceptTransaction(true)) + { + printf(" accepted orphan tx %s\n", inv.hash.ToString().substr(0,6).c_str()); + AddToWalletIfMine(tx, NULL); + RelayMessage(inv, vMsg); + mapAlreadyAskedFor.erase(inv); + vWorkQueue.push_back(inv.hash); + } + } + } + + foreach(uint256 hash, vWorkQueue) + EraseOrphanTx(hash); + } + else if (fMissingInputs) + { + printf("storing orphan tx %s\n", inv.hash.ToString().substr(0,6).c_str()); + AddOrphanTx(vMsg); + } + } + + + else if (strCommand == "block") + { + auto_ptr<CBlock> pblock(new CBlock); + vRecv >> *pblock; + + //// debug print + printf("received block %s\n", pblock->GetHash().ToString().substr(0,16).c_str()); + // pblock->print(); + + CInv inv(MSG_BLOCK, pblock->GetHash()); + pfrom->AddInventoryKnown(inv); + + if (ProcessBlock(pfrom, pblock.release())) + mapAlreadyAskedFor.erase(inv); + } + + + else if (strCommand == "getaddr") + { + // This includes all nodes that are currently online, + // since they rebroadcast an addr every 24 hours + pfrom->vAddrToSend.clear(); + int64 nSince = GetAdjustedTime() - 24 * 60 * 60; // in the last 24 hours + CRITICAL_BLOCK(cs_mapAddresses) + { + unsigned int nSize = mapAddresses.size(); + foreach(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses) + { + if (fShutdown) + return true; + const CAddress& addr = item.second; + if (addr.nTime > nSince) + pfrom->PushAddress(addr); + } + } + } + + + else if (strCommand == "checkorder") + { + uint256 hashReply; + CWalletTx order; + vRecv >> hashReply >> order; + + /// we have a chance to check the order here + + // Keep giving the same key to the same ip until they use it + if (!mapReuseKey.count(pfrom->addr.ip)) + mapReuseKey[pfrom->addr.ip] = GenerateNewKey(); + + // Send back approval of order and pubkey to use + CScript scriptPubKey; + scriptPubKey << mapReuseKey[pfrom->addr.ip] << OP_CHECKSIG; + pfrom->PushMessage("reply", hashReply, (int)0, scriptPubKey); + } + + + else if (strCommand == "submitorder") + { + uint256 hashReply; + CWalletTx wtxNew; + vRecv >> hashReply >> wtxNew; + wtxNew.fFromMe = false; + + // Broadcast + if (!wtxNew.AcceptWalletTransaction()) + { + pfrom->PushMessage("reply", hashReply, (int)1); + return error("submitorder AcceptWalletTransaction() failed, returning error 1"); + } + wtxNew.fTimeReceivedIsTxTime = true; + AddToWallet(wtxNew); + wtxNew.RelayWalletTransaction(); + mapReuseKey.erase(pfrom->addr.ip); + + // Send back confirmation + pfrom->PushMessage("reply", hashReply, (int)0); + } + + + else if (strCommand == "reply") + { + uint256 hashReply; + vRecv >> hashReply; + + CRequestTracker tracker; + CRITICAL_BLOCK(pfrom->cs_mapRequests) + { + map<uint256, CRequestTracker>::iterator mi = pfrom->mapRequests.find(hashReply); + if (mi != pfrom->mapRequests.end()) + { + tracker = (*mi).second; + pfrom->mapRequests.erase(mi); + } + } + if (!tracker.IsNull()) + tracker.fn(tracker.param1, vRecv); + } + + + else if (strCommand == "ping") + { + } + + + else + { + // Ignore unknown commands for extensibility + } + + + // Update the last seen time for this node's address + if (pfrom->fNetworkNode) + if (strCommand == "version" || strCommand == "addr" || strCommand == "inv" || strCommand == "getdata" || strCommand == "ping") + AddressCurrentlyConnected(pfrom->addr); + + + return true; +} + + + + + + + + + +bool SendMessages(CNode* pto, bool fSendTrickle) +{ + CRITICAL_BLOCK(cs_main) + { + // Don't send anything until we get their version message + if (pto->nVersion == 0) + return true; + + // Keep-alive ping + if (pto->nLastSend && GetTime() - pto->nLastSend > 30 * 60 && pto->vSend.empty()) + pto->PushMessage("ping"); + + // Address refresh broadcast + static int64 nLastRebroadcast; + if (GetTime() - nLastRebroadcast > 24 * 60 * 60) // every 24 hours + { + nLastRebroadcast = GetTime(); + CRITICAL_BLOCK(cs_vNodes) + { + foreach(CNode* pnode, vNodes) + { + // Periodically clear setAddrKnown to allow refresh broadcasts + pnode->setAddrKnown.clear(); + + // Rebroadcast our address + if (addrLocalHost.IsRoutable() && !fUseProxy) + pnode->PushAddress(addrLocalHost); + } + } + } + + // Resend wallet transactions that haven't gotten in a block yet + ResendWalletTransactions(); + + + // + // Message: addr + // + if (fSendTrickle) + { + vector<CAddress> vAddr; + vAddr.reserve(pto->vAddrToSend.size()); + foreach(const CAddress& addr, pto->vAddrToSend) + { + // returns true if wasn't already contained in the set + if (pto->setAddrKnown.insert(addr).second) + { + vAddr.push_back(addr); + // receiver rejects addr messages larger than 1000 + if (vAddr.size() >= 1000) + { + pto->PushMessage("addr", vAddr); + vAddr.clear(); + } + } + } + pto->vAddrToSend.clear(); + if (!vAddr.empty()) + pto->PushMessage("addr", vAddr); + } + + + // + // Message: inventory + // + vector<CInv> vInv; + vector<CInv> vInvWait; + CRITICAL_BLOCK(pto->cs_inventory) + { + vInv.reserve(pto->vInventoryToSend.size()); + vInvWait.reserve(pto->vInventoryToSend.size()); + foreach(const CInv& inv, pto->vInventoryToSend) + { + if (pto->setInventoryKnown.count(inv)) + continue; + + // trickle out tx inv to protect privacy + if (inv.type == MSG_TX && !fSendTrickle) + { + // 1/4 of tx invs blast to all immediately + static uint256 hashSalt; + if (hashSalt == 0) + RAND_bytes((unsigned char*)&hashSalt, sizeof(hashSalt)); + uint256 hashRand = inv.hash ^ hashSalt; + hashRand = Hash(BEGIN(hashRand), END(hashRand)); + bool fTrickleWait = ((hashRand & 3) != 0); + + // always trickle our own transactions + if (!fTrickleWait) + { + TRY_CRITICAL_BLOCK(cs_mapWallet) + { + map<uint256, CWalletTx>::iterator mi = mapWallet.find(inv.hash); + if (mi != mapWallet.end()) + { + CWalletTx& wtx = (*mi).second; + if (wtx.fFromMe) + fTrickleWait = true; + } + } + } + + if (fTrickleWait) + { + vInvWait.push_back(inv); + continue; + } + } + + // returns true if wasn't already contained in the set + if (pto->setInventoryKnown.insert(inv).second) + { + vInv.push_back(inv); + if (vInv.size() >= 1000) + { + pto->PushMessage("inv", vInv); + vInv.clear(); + } + } + } + pto->vInventoryToSend = vInvWait; + } + if (!vInv.empty()) + pto->PushMessage("inv", vInv); + + + // + // Message: getdata + // + vector<CInv> vGetData; + int64 nNow = GetTime() * 1000000; + CTxDB txdb("r"); + while (!pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow) + { + const CInv& inv = (*pto->mapAskFor.begin()).second; + if (!AlreadyHave(txdb, inv)) + { + printf("sending getdata: %s\n", inv.ToString().c_str()); + vGetData.push_back(inv); + if (vGetData.size() >= 1000) + { + pto->PushMessage("getdata", vGetData); + vGetData.clear(); + } + } + pto->mapAskFor.erase(pto->mapAskFor.begin()); + } + if (!vGetData.empty()) + pto->PushMessage("getdata", vGetData); + + } + return true; +} + + + + + + + + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// BitcoinMiner +// + +void GenerateBitcoins(bool fGenerate) +{ + if (fGenerateBitcoins != fGenerate) + { + fGenerateBitcoins = fGenerate; + CWalletDB().WriteSetting("fGenerateBitcoins", fGenerateBitcoins); + MainFrameRepaint(); + } + if (fGenerateBitcoins) + { + int nProcessors = wxThread::GetCPUCount(); + printf("%d processors\n", nProcessors); + if (nProcessors < 1) + nProcessors = 1; + if (fLimitProcessors && nProcessors > nLimitProcessors) + nProcessors = nLimitProcessors; + int nAddThreads = nProcessors - vnThreadsRunning[3]; + printf("Starting %d BitcoinMiner threads\n", nAddThreads); + for (int i = 0; i < nAddThreads; i++) + { + if (!CreateThread(ThreadBitcoinMiner, NULL)) + printf("Error: CreateThread(ThreadBitcoinMiner) failed\n"); + Sleep(10); + } + } +} + +void ThreadBitcoinMiner(void* parg) +{ + try + { + vnThreadsRunning[3]++; + BitcoinMiner(); + vnThreadsRunning[3]--; + } + catch (std::exception& e) { + vnThreadsRunning[3]--; + PrintException(&e, "ThreadBitcoinMiner()"); + } catch (...) { + vnThreadsRunning[3]--; + PrintException(NULL, "ThreadBitcoinMiner()"); + } + UIThreadCall(bind(CalledSetStatusBar, "", 0)); + printf("ThreadBitcoinMiner exiting, %d threads remaining\n", vnThreadsRunning[3]); +} + +int FormatHashBlocks(void* pbuffer, unsigned int len) +{ + unsigned char* pdata = (unsigned char*)pbuffer; + unsigned int blocks = 1 + ((len + 8) / 64); + unsigned char* pend = pdata + 64 * blocks; + memset(pdata + len, 0, 64 * blocks - len); + pdata[len] = 0x80; + unsigned int bits = len * 8; + pend[-1] = (bits >> 0) & 0xff; + pend[-2] = (bits >> 8) & 0xff; + pend[-3] = (bits >> 16) & 0xff; + pend[-4] = (bits >> 24) & 0xff; + return blocks; +} + +using CryptoPP::ByteReverse; +static int detectlittleendian = 1; + +void BlockSHA256(const void* pin, unsigned int nBlocks, void* pout) +{ + unsigned int* pinput = (unsigned int*)pin; + unsigned int* pstate = (unsigned int*)pout; + + CryptoPP::SHA256::InitState(pstate); + + if (*(char*)&detectlittleendian != 0) + { + for (int n = 0; n < nBlocks; n++) + { + unsigned int pbuf[16]; + for (int i = 0; i < 16; i++) + pbuf[i] = ByteReverse(pinput[n * 16 + i]); + CryptoPP::SHA256::Transform(pstate, pbuf); + } + for (int i = 0; i < 8; i++) + pstate[i] = ByteReverse(pstate[i]); + } + else + { + for (int n = 0; n < nBlocks; n++) + CryptoPP::SHA256::Transform(pstate, pinput + n * 16); + } +} + + +void BitcoinMiner() +{ + printf("BitcoinMiner started\n"); + + CKey key; + key.MakeNewKey(); + CBigNum bnExtraNonce = 0; + while (fGenerateBitcoins) + { + SetThreadPriority(THREAD_PRIORITY_LOWEST); + Sleep(50); + if (fShutdown) + return; + while (vNodes.empty()) + { + Sleep(1000); + if (fShutdown) + return; + if (!fGenerateBitcoins) + return; + } + + unsigned int nTransactionsUpdatedLast = nTransactionsUpdated; + CBlockIndex* pindexPrev = pindexBest; + unsigned int nBits = GetNextWorkRequired(pindexPrev); + + + // + // Create coinbase tx + // + CTransaction txNew; + txNew.vin.resize(1); + txNew.vin[0].prevout.SetNull(); + txNew.vin[0].scriptSig << nBits << ++bnExtraNonce; + txNew.vout.resize(1); + txNew.vout[0].scriptPubKey << key.GetPubKey() << OP_CHECKSIG; + + + // + // Create new block + // + auto_ptr<CBlock> pblock(new CBlock()); + if (!pblock.get()) + return; + + // Add our coinbase tx as first transaction + pblock->vtx.push_back(txNew); + + // Collect the latest transactions into the block + int64 nFees = 0; + CRITICAL_BLOCK(cs_main) + CRITICAL_BLOCK(cs_mapTransactions) + { + CTxDB txdb("r"); + map<uint256, CTxIndex> mapTestPool; + vector<char> vfAlreadyAdded(mapTransactions.size()); + bool fFoundSomething = true; + unsigned int nBlockSize = 0; + while (fFoundSomething && nBlockSize < MAX_SIZE/2) + { + fFoundSomething = false; + unsigned int n = 0; + for (map<uint256, CTransaction>::iterator mi = mapTransactions.begin(); mi != mapTransactions.end(); ++mi, ++n) + { + if (vfAlreadyAdded[n]) + continue; + CTransaction& tx = (*mi).second; + if (tx.IsCoinBase() || !tx.IsFinal()) + continue; + + // Transaction fee based on block size + int64 nMinFee = tx.GetMinFee(nBlockSize); + + map<uint256, CTxIndex> mapTestPoolTmp(mapTestPool); + if (!tx.ConnectInputs(txdb, mapTestPoolTmp, CDiskTxPos(1,1,1), 0, nFees, false, true, nMinFee)) + continue; + swap(mapTestPool, mapTestPoolTmp); + + pblock->vtx.push_back(tx); + nBlockSize += ::GetSerializeSize(tx, SER_NETWORK); + vfAlreadyAdded[n] = true; + fFoundSomething = true; + } + } + } + pblock->nBits = nBits; + pblock->vtx[0].vout[0].nValue = pblock->GetBlockValue(nFees); + printf("Running BitcoinMiner with %d transactions in block\n", pblock->vtx.size()); + + + // + // Prebuild hash buffer + // + struct unnamed1 + { + struct unnamed2 + { + int nVersion; + uint256 hashPrevBlock; + uint256 hashMerkleRoot; + unsigned int nTime; + unsigned int nBits; + unsigned int nNonce; + } + block; + unsigned char pchPadding0[64]; + uint256 hash1; + unsigned char pchPadding1[64]; + } + tmp; + + tmp.block.nVersion = pblock->nVersion; + tmp.block.hashPrevBlock = pblock->hashPrevBlock = (pindexPrev ? pindexPrev->GetBlockHash() : 0); + tmp.block.hashMerkleRoot = pblock->hashMerkleRoot = pblock->BuildMerkleTree(); + tmp.block.nTime = pblock->nTime = max((pindexPrev ? pindexPrev->GetMedianTimePast()+1 : 0), GetAdjustedTime()); + tmp.block.nBits = pblock->nBits = nBits; + tmp.block.nNonce = pblock->nNonce = 1; + + unsigned int nBlocks0 = FormatHashBlocks(&tmp.block, sizeof(tmp.block)); + unsigned int nBlocks1 = FormatHashBlocks(&tmp.hash1, sizeof(tmp.hash1)); + + + // + // Search + // + int64 nStart = GetTime(); + uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); + uint256 hash; + loop + { + BlockSHA256(&tmp.block, nBlocks0, &tmp.hash1); + BlockSHA256(&tmp.hash1, nBlocks1, &hash); + + if (hash <= hashTarget) + { + pblock->nNonce = tmp.block.nNonce; + assert(hash == pblock->GetHash()); + + //// debug print + printf("BitcoinMiner:\n"); + printf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str()); + pblock->print(); + printf("%s ", DateTimeStrFormat("%x %H:%M", GetTime()).c_str()); + printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str()); + + SetThreadPriority(THREAD_PRIORITY_NORMAL); + CRITICAL_BLOCK(cs_main) + { + if (pindexPrev == pindexBest) + { + // Save key + if (!AddKey(key)) + return; + key.MakeNewKey(); + + // Track how many getdata requests this block gets + CRITICAL_BLOCK(cs_mapRequestCount) + mapRequestCount[pblock->GetHash()] = 0; + + // Process this block the same as if we had received it from another node + if (!ProcessBlock(NULL, pblock.release())) + printf("ERROR in BitcoinMiner, ProcessBlock, block not accepted\n"); + } + } + SetThreadPriority(THREAD_PRIORITY_LOWEST); + + Sleep(500); + break; + } + + // Update nTime every few seconds + const unsigned int nMask = 0xffff; + if ((++tmp.block.nNonce & nMask) == 0) + { + // Meter hashes/sec + static int64 nTimerStart; + static int nHashCounter; + if (nTimerStart == 0) + nTimerStart = GetTimeMillis(); + else + nHashCounter++; + if (GetTimeMillis() - nTimerStart > 4000) + { + static CCriticalSection cs; + CRITICAL_BLOCK(cs) + { + if (GetTimeMillis() - nTimerStart > 4000) + { + double dHashesPerSec = 1000.0 * (nMask+1) * nHashCounter / (GetTimeMillis() - nTimerStart); + nTimerStart = GetTimeMillis(); + nHashCounter = 0; + string strStatus = strprintf(" %.0f khash/s", dHashesPerSec/1000.0); + UIThreadCall(bind(CalledSetStatusBar, strStatus, 0)); + static int64 nLogTime; + if (GetTime() - nLogTime > 30 * 60) + { + nLogTime = GetTime(); + printf("%s ", DateTimeStrFormat("%x %H:%M", GetTime()).c_str()); + printf("hashmeter %3d CPUs %6.0f khash/s\n", vnThreadsRunning[3], dHashesPerSec/1000.0); + } + } + } + } + + // Check for stop or if block needs to be rebuilt + if (fShutdown) + return; + if (!fGenerateBitcoins) + return; + if (fLimitProcessors && vnThreadsRunning[3] > nLimitProcessors) + return; + if (vNodes.empty()) + break; + if (tmp.block.nNonce == 0) + break; + if (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60) + break; + if (pindexPrev != pindexBest) + { + // Pause generating during initial download + if (GetTime() - nStart < 20) + { + CBlockIndex* pindexTmp; + do + { + pindexTmp = pindexBest; + for (int i = 0; i < 10; i++) + { + Sleep(1000); + if (fShutdown) + return; + } + } + while (pindexTmp != pindexBest); + } + break; + } + + tmp.block.nTime = pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); + } + } + } +} + + + + + + + + + + + + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// Actions +// + + +int64 GetBalance() +{ + int64 nStart = GetTimeMillis(); + + int64 nTotal = 0; + CRITICAL_BLOCK(cs_mapWallet) + { + for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + CWalletTx* pcoin = &(*it).second; + if (!pcoin->IsFinal() || pcoin->fSpent) + continue; + nTotal += pcoin->GetCredit(true); + } + } + + //printf("GetBalance() %"PRI64d"ms\n", GetTimeMillis() - nStart); + return nTotal; +} + + + +bool SelectCoins(int64 nTargetValue, set<CWalletTx*>& setCoinsRet) +{ + setCoinsRet.clear(); + + // List of values less than target + int64 nLowestLarger = INT64_MAX; + CWalletTx* pcoinLowestLarger = NULL; + vector<pair<int64, CWalletTx*> > vValue; + int64 nTotalLower = 0; + + CRITICAL_BLOCK(cs_mapWallet) + { + for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + CWalletTx* pcoin = &(*it).second; + if (!pcoin->IsFinal() || pcoin->fSpent) + continue; + int64 n = pcoin->GetCredit(); + if (n <= 0) + continue; + if (n < nTargetValue) + { + vValue.push_back(make_pair(n, pcoin)); + nTotalLower += n; + } + else if (n == nTargetValue) + { + setCoinsRet.insert(pcoin); + return true; + } + else if (n < nLowestLarger) + { + nLowestLarger = n; + pcoinLowestLarger = pcoin; + } + } + } + + if (nTotalLower < nTargetValue) + { + if (pcoinLowestLarger == NULL) + return false; + setCoinsRet.insert(pcoinLowestLarger); + return true; + } + + // Solve subset sum by stochastic approximation + sort(vValue.rbegin(), vValue.rend()); + vector<char> vfIncluded; + vector<char> vfBest(vValue.size(), true); + int64 nBest = nTotalLower; + + for (int nRep = 0; nRep < 1000 && nBest != nTargetValue; nRep++) + { + vfIncluded.assign(vValue.size(), false); + int64 nTotal = 0; + bool fReachedTarget = false; + for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++) + { + for (int i = 0; i < vValue.size(); i++) + { + if (nPass == 0 ? rand() % 2 : !vfIncluded[i]) + { + nTotal += vValue[i].first; + vfIncluded[i] = true; + if (nTotal >= nTargetValue) + { + fReachedTarget = true; + if (nTotal < nBest) + { + nBest = nTotal; + vfBest = vfIncluded; + } + nTotal -= vValue[i].first; + vfIncluded[i] = false; + } + } + } + } + } + + // If the next larger is still closer, return it + if (pcoinLowestLarger && nLowestLarger - nTargetValue <= nBest - nTargetValue) + setCoinsRet.insert(pcoinLowestLarger); + else + { + for (int i = 0; i < vValue.size(); i++) + if (vfBest[i]) + setCoinsRet.insert(vValue[i].second); + + //// debug print + printf("SelectCoins() best subset: "); + for (int i = 0; i < vValue.size(); i++) + if (vfBest[i]) + printf("%s ", FormatMoney(vValue[i].first).c_str()); + printf("total %s\n", FormatMoney(nBest).c_str()); + } + + return true; +} + + + + +bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CKey& keyRet, int64& nFeeRequiredRet) +{ + nFeeRequiredRet = 0; + CRITICAL_BLOCK(cs_main) + { + // txdb must be opened before the mapWallet lock + CTxDB txdb("r"); + CRITICAL_BLOCK(cs_mapWallet) + { + int64 nFee = nTransactionFee; + loop + { + wtxNew.vin.clear(); + wtxNew.vout.clear(); + wtxNew.fFromMe = true; + if (nValue < 0) + return false; + int64 nValueOut = nValue; + int64 nTotalValue = nValue + nFee; + + // Choose coins to use + set<CWalletTx*> setCoins; + if (!SelectCoins(nTotalValue, setCoins)) + return false; + int64 nValueIn = 0; + foreach(CWalletTx* pcoin, setCoins) + nValueIn += pcoin->GetCredit(); + + // Fill a vout to the payee + bool fChangeFirst = GetRand(2); + if (!fChangeFirst) + wtxNew.vout.push_back(CTxOut(nValueOut, scriptPubKey)); + + // Fill a vout back to self with any change + if (nValueIn > nTotalValue) + { + // Note: We use a new key here to keep it from being obvious which side is the change. + // The drawback is that by not reusing a previous key, the change may be lost if a + // backup is restored, if the backup doesn't have the new private key for the change. + // If we reused the old key, it would be possible to add code to look for and + // rediscover unknown transactions that were written with keys of ours to recover + // post-backup change. + + // New private key + if (keyRet.IsNull()) + keyRet.MakeNewKey(); + + // Fill a vout to ourself, using same address type as the payment + CScript scriptChange; + if (scriptPubKey.GetBitcoinAddressHash160() != 0) + scriptChange.SetBitcoinAddress(keyRet.GetPubKey()); + else + scriptChange << keyRet.GetPubKey() << OP_CHECKSIG; + wtxNew.vout.push_back(CTxOut(nValueIn - nTotalValue, scriptChange)); + } + + // Fill a vout to the payee + if (fChangeFirst) + wtxNew.vout.push_back(CTxOut(nValueOut, scriptPubKey)); + + // Fill vin + foreach(CWalletTx* pcoin, setCoins) + for (int nOut = 0; nOut < pcoin->vout.size(); nOut++) + if (pcoin->vout[nOut].IsMine()) + wtxNew.vin.push_back(CTxIn(pcoin->GetHash(), nOut)); + + // Sign + int nIn = 0; + foreach(CWalletTx* pcoin, setCoins) + for (int nOut = 0; nOut < pcoin->vout.size(); nOut++) + if (pcoin->vout[nOut].IsMine()) + SignSignature(*pcoin, wtxNew, nIn++); + + // Check that enough fee is included + if (nFee < wtxNew.GetMinFee()) + { + nFee = nFeeRequiredRet = wtxNew.GetMinFee(); + continue; + } + + // Fill vtxPrev by copying from previous transactions vtxPrev + wtxNew.AddSupportingTransactions(txdb); + wtxNew.fTimeReceivedIsTxTime = true; + + break; + } + } + } + return true; +} + +// Call after CreateTransaction unless you want to abort +bool CommitTransaction(CWalletTx& wtxNew, const CKey& key) +{ + CRITICAL_BLOCK(cs_main) + { + printf("CommitTransaction:\n%s", wtxNew.ToString().c_str()); + CRITICAL_BLOCK(cs_mapWallet) + { + // This is only to keep the database open to defeat the auto-flush for the + // duration of this scope. This is the only place where this optimization + // maybe makes sense; please don't do it anywhere else. + CWalletDB walletdb("r"); + + // Add the change's private key to wallet + if (!key.IsNull() && !AddKey(key)) + throw runtime_error("CommitTransaction() : AddKey failed\n"); + + // Add tx to wallet, because if it has change it's also ours, + // otherwise just for transaction history. + AddToWallet(wtxNew); + + // Mark old coins as spent + set<CWalletTx*> setCoins; + foreach(const CTxIn& txin, wtxNew.vin) + setCoins.insert(&mapWallet[txin.prevout.hash]); + foreach(CWalletTx* pcoin, setCoins) + { + pcoin->fSpent = true; + pcoin->WriteToDisk(); + vWalletUpdated.push_back(pcoin->GetHash()); + } + } + + // Track how many getdata requests our transaction gets + CRITICAL_BLOCK(cs_mapRequestCount) + mapRequestCount[wtxNew.GetHash()] = 0; + + // Broadcast + if (!wtxNew.AcceptTransaction()) + { + // This must not fail. The transaction has already been signed and recorded. + printf("CommitTransaction() : Error: Transaction not valid"); + return false; + } + wtxNew.RelayWalletTransaction(); + } + MainFrameRepaint(); + return true; +} + + + + +string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee) +{ + CRITICAL_BLOCK(cs_main) + { + CKey key; + int64 nFeeRequired; + if (!CreateTransaction(scriptPubKey, nValue, wtxNew, key, nFeeRequired)) + { + string strError; + if (nValue + nFeeRequired > GetBalance()) + strError = strprintf(_("Error: This is an oversized transaction that requires a transaction fee of %s "), FormatMoney(nFeeRequired).c_str()); + else + strError = _("Error: Transaction creation failed "); + printf("SendMoney() : %s", strError.c_str()); + return strError; + } + + if (fAskFee && !ThreadSafeAskFee(nFeeRequired, _("Sending..."), NULL)) + return "ABORTED"; + + if (!CommitTransaction(wtxNew, key)) + return _("Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."); + } + MainFrameRepaint(); + return ""; +} + + + +string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew, bool fAskFee) +{ + // Check amount + if (nValue <= 0) + return _("Invalid amount"); + if (nValue + nTransactionFee > GetBalance()) + return _("Insufficient funds"); + + // Parse bitcoin address + CScript scriptPubKey; + if (!scriptPubKey.SetBitcoinAddress(strAddress)) + return _("Invalid bitcoin address"); + + return SendMoney(scriptPubKey, nValue, wtxNew, fAskFee); +} @@ -1,1423 +1,1423 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
-
-class COutPoint;
-class CInPoint;
-class CDiskTxPos;
-class CCoinBase;
-class CTxIn;
-class CTxOut;
-class CTransaction;
-class CBlock;
-class CBlockIndex;
-class CWalletTx;
-class CKeyItem;
-
-static const unsigned int MAX_SIZE = 0x02000000;
-static const int64 COIN = 100000000;
-static const int64 CENT = 1000000;
-static const int COINBASE_MATURITY = 100;
-
-static const CBigNum bnProofOfWorkLimit(~uint256(0) >> 32);
-
-
-
-
-
-
-extern CCriticalSection cs_main;
-extern map<uint256, CBlockIndex*> mapBlockIndex;
-extern const uint256 hashGenesisBlock;
-extern CBlockIndex* pindexGenesisBlock;
-extern int nBestHeight;
-extern uint256 hashBestChain;
-extern CBlockIndex* pindexBest;
-extern unsigned int nTransactionsUpdated;
-extern map<uint256, int> mapRequestCount;
-extern CCriticalSection cs_mapRequestCount;
-extern map<string, string> mapAddressBook;
-extern CCriticalSection cs_mapAddressBook;
-extern vector<unsigned char> vchDefaultKey;
-
-// Settings
-extern int fGenerateBitcoins;
-extern int64 nTransactionFee;
-extern CAddress addrIncoming;
-extern int fLimitProcessors;
-extern int nLimitProcessors;
-extern int fMinimizeToTray;
-extern int fMinimizeOnClose;
-
-
-
-
-
-
-
-bool CheckDiskSpace(int64 nAdditionalBytes=0);
-FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb");
-FILE* AppendBlockFile(unsigned int& nFileRet);
-bool AddKey(const CKey& key);
-vector<unsigned char> GenerateNewKey();
-bool AddToWallet(const CWalletTx& wtxIn);
-void WalletUpdateSpent(const COutPoint& prevout);
-void ReacceptWalletTransactions();
-bool LoadBlockIndex(bool fAllowNew=true);
-void PrintBlockTree();
-bool ProcessMessages(CNode* pfrom);
-bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv);
-bool SendMessages(CNode* pto, bool fSendTrickle);
-int64 GetBalance();
-bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CKey& keyRet, int64& nFeeRequiredRet);
-bool CommitTransaction(CWalletTx& wtxNew, const CKey& key);
-bool BroadcastTransaction(CWalletTx& wtxNew);
-string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
-string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
-void GenerateBitcoins(bool fGenerate);
-void ThreadBitcoinMiner(void* parg);
-void BitcoinMiner();
-
-
-
-
-
-
-
-
-
-
-
-
-class CDiskTxPos
-{
-public:
- unsigned int nFile;
- unsigned int nBlockPos;
- unsigned int nTxPos;
-
- CDiskTxPos()
- {
- SetNull();
- }
-
- CDiskTxPos(unsigned int nFileIn, unsigned int nBlockPosIn, unsigned int nTxPosIn)
- {
- nFile = nFileIn;
- nBlockPos = nBlockPosIn;
- nTxPos = nTxPosIn;
- }
-
- IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); )
- void SetNull() { nFile = -1; nBlockPos = 0; nTxPos = 0; }
- bool IsNull() const { return (nFile == -1); }
-
- friend bool operator==(const CDiskTxPos& a, const CDiskTxPos& b)
- {
- return (a.nFile == b.nFile &&
- a.nBlockPos == b.nBlockPos &&
- a.nTxPos == b.nTxPos);
- }
-
- friend bool operator!=(const CDiskTxPos& a, const CDiskTxPos& b)
- {
- return !(a == b);
- }
-
- string ToString() const
- {
- if (IsNull())
- return strprintf("null");
- else
- return strprintf("(nFile=%d, nBlockPos=%d, nTxPos=%d)", nFile, nBlockPos, nTxPos);
- }
-
- void print() const
- {
- printf("%s", ToString().c_str());
- }
-};
-
-
-
-
-class CInPoint
-{
-public:
- CTransaction* ptx;
- unsigned int n;
-
- CInPoint() { SetNull(); }
- CInPoint(CTransaction* ptxIn, unsigned int nIn) { ptx = ptxIn; n = nIn; }
- void SetNull() { ptx = NULL; n = -1; }
- bool IsNull() const { return (ptx == NULL && n == -1); }
-};
-
-
-
-
-class COutPoint
-{
-public:
- uint256 hash;
- unsigned int n;
-
- COutPoint() { SetNull(); }
- COutPoint(uint256 hashIn, unsigned int nIn) { hash = hashIn; n = nIn; }
- IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); )
- void SetNull() { hash = 0; n = -1; }
- bool IsNull() const { return (hash == 0 && n == -1); }
-
- friend bool operator<(const COutPoint& a, const COutPoint& b)
- {
- return (a.hash < b.hash || (a.hash == b.hash && a.n < b.n));
- }
-
- friend bool operator==(const COutPoint& a, const COutPoint& b)
- {
- return (a.hash == b.hash && a.n == b.n);
- }
-
- friend bool operator!=(const COutPoint& a, const COutPoint& b)
- {
- return !(a == b);
- }
-
- string ToString() const
- {
- return strprintf("COutPoint(%s, %d)", hash.ToString().substr(0,6).c_str(), n);
- }
-
- void print() const
- {
- printf("%s\n", ToString().c_str());
- }
-};
-
-
-
-
-//
-// An input of a transaction. It contains the location of the previous
-// transaction's output that it claims and a signature that matches the
-// output's public key.
-//
-class CTxIn
-{
-public:
- COutPoint prevout;
- CScript scriptSig;
- unsigned int nSequence;
-
- CTxIn()
- {
- nSequence = UINT_MAX;
- }
-
- explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX)
- {
- prevout = prevoutIn;
- scriptSig = scriptSigIn;
- nSequence = nSequenceIn;
- }
-
- CTxIn(uint256 hashPrevTx, unsigned int nOut, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX)
- {
- prevout = COutPoint(hashPrevTx, nOut);
- scriptSig = scriptSigIn;
- nSequence = nSequenceIn;
- }
-
- IMPLEMENT_SERIALIZE
- (
- READWRITE(prevout);
- READWRITE(scriptSig);
- READWRITE(nSequence);
- )
-
- bool IsFinal() const
- {
- return (nSequence == UINT_MAX);
- }
-
- friend bool operator==(const CTxIn& a, const CTxIn& b)
- {
- return (a.prevout == b.prevout &&
- a.scriptSig == b.scriptSig &&
- a.nSequence == b.nSequence);
- }
-
- friend bool operator!=(const CTxIn& a, const CTxIn& b)
- {
- return !(a == b);
- }
-
- string ToString() const
- {
- string str;
- str += strprintf("CTxIn(");
- str += prevout.ToString();
- if (prevout.IsNull())
- str += strprintf(", coinbase %s", HexStr(scriptSig.begin(), scriptSig.end(), false).c_str());
- else
- str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24).c_str());
- if (nSequence != UINT_MAX)
- str += strprintf(", nSequence=%u", nSequence);
- str += ")";
- return str;
- }
-
- void print() const
- {
- printf("%s\n", ToString().c_str());
- }
-
- bool IsMine() const;
- int64 GetDebit() const;
-};
-
-
-
-
-//
-// An output of a transaction. It contains the public key that the next input
-// must be able to sign with to claim it.
-//
-class CTxOut
-{
-public:
- int64 nValue;
- CScript scriptPubKey;
-
-public:
- CTxOut()
- {
- SetNull();
- }
-
- CTxOut(int64 nValueIn, CScript scriptPubKeyIn)
- {
- nValue = nValueIn;
- scriptPubKey = scriptPubKeyIn;
- }
-
- IMPLEMENT_SERIALIZE
- (
- READWRITE(nValue);
- READWRITE(scriptPubKey);
- )
-
- void SetNull()
- {
- nValue = -1;
- scriptPubKey.clear();
- }
-
- bool IsNull()
- {
- return (nValue == -1);
- }
-
- uint256 GetHash() const
- {
- return SerializeHash(*this);
- }
-
- bool IsMine() const
- {
- return ::IsMine(scriptPubKey);
- }
-
- int64 GetCredit() const
- {
- if (IsMine())
- return nValue;
- return 0;
- }
-
- friend bool operator==(const CTxOut& a, const CTxOut& b)
- {
- return (a.nValue == b.nValue &&
- a.scriptPubKey == b.scriptPubKey);
- }
-
- friend bool operator!=(const CTxOut& a, const CTxOut& b)
- {
- return !(a == b);
- }
-
- string ToString() const
- {
- if (scriptPubKey.size() < 6)
- return "CTxOut(error)";
- return strprintf("CTxOut(nValue=%"PRI64d".%08"PRI64d", scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,24).c_str());
- }
-
- void print() const
- {
- printf("%s\n", ToString().c_str());
- }
-};
-
-
-
-
-//
-// The basic transaction that is broadcasted on the network and contained in
-// blocks. A transaction can contain multiple inputs and outputs.
-//
-class CTransaction
-{
-public:
- int nVersion;
- vector<CTxIn> vin;
- vector<CTxOut> vout;
- unsigned int nLockTime;
-
-
- CTransaction()
- {
- SetNull();
- }
-
- IMPLEMENT_SERIALIZE
- (
- READWRITE(this->nVersion);
- nVersion = this->nVersion;
- READWRITE(vin);
- READWRITE(vout);
- READWRITE(nLockTime);
- )
-
- void SetNull()
- {
- nVersion = 1;
- vin.clear();
- vout.clear();
- nLockTime = 0;
- }
-
- bool IsNull() const
- {
- return (vin.empty() && vout.empty());
- }
-
- uint256 GetHash() const
- {
- return SerializeHash(*this);
- }
-
- bool IsFinal(int64 nBlockTime=0) const
- {
- // Time based nLockTime implemented in 0.1.6,
- // do not use time based until most 0.1.5 nodes have upgraded.
- if (nLockTime == 0)
- return true;
- if (nBlockTime == 0)
- nBlockTime = GetAdjustedTime();
- if (nLockTime < (nLockTime < 500000000 ? nBestHeight : nBlockTime))
- return true;
- foreach(const CTxIn& txin, vin)
- if (!txin.IsFinal())
- return false;
- return true;
- }
-
- bool IsNewerThan(const CTransaction& old) const
- {
- if (vin.size() != old.vin.size())
- return false;
- for (int i = 0; i < vin.size(); i++)
- if (vin[i].prevout != old.vin[i].prevout)
- return false;
-
- bool fNewer = false;
- unsigned int nLowest = UINT_MAX;
- for (int i = 0; i < vin.size(); i++)
- {
- if (vin[i].nSequence != old.vin[i].nSequence)
- {
- if (vin[i].nSequence <= nLowest)
- {
- fNewer = false;
- nLowest = vin[i].nSequence;
- }
- if (old.vin[i].nSequence < nLowest)
- {
- fNewer = true;
- nLowest = old.vin[i].nSequence;
- }
- }
- }
- return fNewer;
- }
-
- bool IsCoinBase() const
- {
- return (vin.size() == 1 && vin[0].prevout.IsNull());
- }
-
- bool CheckTransaction() const
- {
- // Basic checks that don't depend on any context
- if (vin.empty() || vout.empty())
- return error("CTransaction::CheckTransaction() : vin or vout empty");
-
- // Check for negative values
- foreach(const CTxOut& txout, vout)
- if (txout.nValue < 0)
- return error("CTransaction::CheckTransaction() : txout.nValue negative");
-
- if (IsCoinBase())
- {
- if (vin[0].scriptSig.size() < 2 || vin[0].scriptSig.size() > 100)
- return error("CTransaction::CheckTransaction() : coinbase script size");
- }
- else
- {
- foreach(const CTxIn& txin, vin)
- if (txin.prevout.IsNull())
- return error("CTransaction::CheckTransaction() : prevout is null");
- }
-
- return true;
- }
-
- bool IsMine() const
- {
- foreach(const CTxOut& txout, vout)
- if (txout.IsMine())
- return true;
- return false;
- }
-
- int64 GetDebit() const
- {
- int64 nDebit = 0;
- foreach(const CTxIn& txin, vin)
- nDebit += txin.GetDebit();
- return nDebit;
- }
-
- int64 GetCredit() const
- {
- int64 nCredit = 0;
- foreach(const CTxOut& txout, vout)
- nCredit += txout.GetCredit();
- return nCredit;
- }
-
- int64 GetValueOut() const
- {
- int64 nValueOut = 0;
- foreach(const CTxOut& txout, vout)
- {
- if (txout.nValue < 0)
- throw runtime_error("CTransaction::GetValueOut() : negative value");
- nValueOut += txout.nValue;
- }
- return nValueOut;
- }
-
- int64 GetMinFee(unsigned int nBlockSize=1) const
- {
- // Base fee is 1 cent per kilobyte
- unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK);
- int64 nMinFee = (1 + (int64)nBytes / 1000) * CENT;
-
- // Transactions under 60K are free as long as block size is under 80K
- // (about 27,000bc if made of 50bc inputs)
- if (nBytes < 60000 && nBlockSize < 80000)
- nMinFee = 0;
-
- // Transactions under 3K are free as long as block size is under 200K
- if (nBytes < 3000 && nBlockSize < 200000)
- nMinFee = 0;
-
- // To limit dust spam, require a 0.01 fee if any output is less than 0.01
- if (nMinFee < CENT)
- foreach(const CTxOut& txout, vout)
- if (txout.nValue < CENT)
- nMinFee = CENT;
-
- return nMinFee;
- }
-
-
-
- bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL)
- {
- CAutoFile filein = OpenBlockFile(pos.nFile, 0, pfileRet ? "rb+" : "rb");
- if (!filein)
- return error("CTransaction::ReadFromDisk() : OpenBlockFile failed");
-
- // Read transaction
- if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)
- return error("CTransaction::ReadFromDisk() : fseek failed");
- filein >> *this;
-
- // Return file pointer
- if (pfileRet)
- {
- if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)
- return error("CTransaction::ReadFromDisk() : second fseek failed");
- *pfileRet = filein.release();
- }
- return true;
- }
-
-
- friend bool operator==(const CTransaction& a, const CTransaction& b)
- {
- return (a.nVersion == b.nVersion &&
- a.vin == b.vin &&
- a.vout == b.vout &&
- a.nLockTime == b.nLockTime);
- }
-
- friend bool operator!=(const CTransaction& a, const CTransaction& b)
- {
- return !(a == b);
- }
-
-
- string ToString() const
- {
- string str;
- str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%d, vout.size=%d, nLockTime=%d)\n",
- GetHash().ToString().substr(0,6).c_str(),
- nVersion,
- vin.size(),
- vout.size(),
- nLockTime);
- for (int i = 0; i < vin.size(); i++)
- str += " " + vin[i].ToString() + "\n";
- for (int i = 0; i < vout.size(); i++)
- str += " " + vout[i].ToString() + "\n";
- return str;
- }
-
- void print() const
- {
- printf("%s", ToString().c_str());
- }
-
-
-
- bool DisconnectInputs(CTxDB& txdb);
- bool ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPool, CDiskTxPos posThisTx, int nHeight, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee=0);
- bool ClientConnectInputs();
-
- bool AcceptTransaction(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL);
-
- bool AcceptTransaction(bool fCheckInputs=true, bool* pfMissingInputs=NULL)
- {
- CTxDB txdb("r");
- return AcceptTransaction(txdb, fCheckInputs, pfMissingInputs);
- }
-
-protected:
- bool AddToMemoryPool();
-public:
- bool RemoveFromMemoryPool();
-};
-
-
-
-
-
-//
-// A transaction with a merkle branch linking it to the block chain
-//
-class CMerkleTx : public CTransaction
-{
-public:
- uint256 hashBlock;
- vector<uint256> vMerkleBranch;
- int nIndex;
-
- // memory only
- mutable bool fMerkleVerified;
- mutable bool fGetCreditCached;
- mutable int64 nGetCreditCached;
-
-
- CMerkleTx()
- {
- Init();
- }
-
- CMerkleTx(const CTransaction& txIn) : CTransaction(txIn)
- {
- Init();
- }
-
- void Init()
- {
- hashBlock = 0;
- nIndex = -1;
- fMerkleVerified = false;
- fGetCreditCached = false;
- nGetCreditCached = 0;
- }
-
- IMPLEMENT_SERIALIZE
- (
- nSerSize += SerReadWrite(s, *(CTransaction*)this, nType, nVersion, ser_action);
- nVersion = this->nVersion;
- READWRITE(hashBlock);
- READWRITE(vMerkleBranch);
- READWRITE(nIndex);
- )
-
- int64 GetCredit(bool fUseCache=false) const
- {
- // Must wait until coinbase is safely deep enough in the chain before valuing it
- if (IsCoinBase() && GetBlocksToMaturity() > 0)
- return 0;
-
- // GetBalance can assume transactions in mapWallet won't change
- if (fUseCache && fGetCreditCached)
- return nGetCreditCached;
- nGetCreditCached = CTransaction::GetCredit();
- fGetCreditCached = true;
- return nGetCreditCached;
- }
-
-
- int SetMerkleBranch(const CBlock* pblock=NULL);
- int GetDepthInMainChain(int& nHeightRet) const;
- int GetDepthInMainChain() const { int nHeight; return GetDepthInMainChain(nHeight); }
- bool IsInMainChain() const { return GetDepthInMainChain() > 0; }
- int GetBlocksToMaturity() const;
- bool AcceptTransaction(CTxDB& txdb, bool fCheckInputs=true);
- bool AcceptTransaction() { CTxDB txdb("r"); return AcceptTransaction(txdb); }
-};
-
-
-
-
-//
-// A transaction with a bunch of additional info that only the owner cares
-// about. It includes any unrecorded transactions needed to link it back
-// to the block chain.
-//
-class CWalletTx : public CMerkleTx
-{
-public:
- vector<CMerkleTx> vtxPrev;
- map<string, string> mapValue;
- vector<pair<string, string> > vOrderForm;
- unsigned int fTimeReceivedIsTxTime;
- unsigned int nTimeReceived; // time received by this node
- char fFromMe;
- char fSpent;
- //// probably need to sign the order info so know it came from payer
-
- // memory only UI hints
- mutable unsigned int nTimeDisplayed;
- mutable int nLinesDisplayed;
-
-
- CWalletTx()
- {
- Init();
- }
-
- CWalletTx(const CMerkleTx& txIn) : CMerkleTx(txIn)
- {
- Init();
- }
-
- CWalletTx(const CTransaction& txIn) : CMerkleTx(txIn)
- {
- Init();
- }
-
- void Init()
- {
- fTimeReceivedIsTxTime = false;
- nTimeReceived = 0;
- fFromMe = false;
- fSpent = false;
- nTimeDisplayed = 0;
- nLinesDisplayed = 0;
- }
-
- IMPLEMENT_SERIALIZE
- (
- nSerSize += SerReadWrite(s, *(CMerkleTx*)this, nType, nVersion, ser_action);
- nVersion = this->nVersion;
- READWRITE(vtxPrev);
- READWRITE(mapValue);
- READWRITE(vOrderForm);
- READWRITE(fTimeReceivedIsTxTime);
- READWRITE(nTimeReceived);
- READWRITE(fFromMe);
- READWRITE(fSpent);
- )
-
- bool WriteToDisk()
- {
- return CWalletDB().WriteTx(GetHash(), *this);
- }
-
-
- int64 GetTxTime() const;
- int GetRequestCount() const;
-
- void AddSupportingTransactions(CTxDB& txdb);
-
- bool AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs=true);
- bool AcceptWalletTransaction() { CTxDB txdb("r"); return AcceptWalletTransaction(txdb); }
-
- void RelayWalletTransaction(CTxDB& txdb);
- void RelayWalletTransaction() { CTxDB txdb("r"); RelayWalletTransaction(txdb); }
-};
-
-
-
-
-//
-// A txdb record that contains the disk location of a transaction and the
-// locations of transactions that spend its outputs. vSpent is really only
-// used as a flag, but having the location is very helpful for debugging.
-//
-class CTxIndex
-{
-public:
- CDiskTxPos pos;
- vector<CDiskTxPos> vSpent;
-
- CTxIndex()
- {
- SetNull();
- }
-
- CTxIndex(const CDiskTxPos& posIn, unsigned int nOutputs)
- {
- pos = posIn;
- vSpent.resize(nOutputs);
- }
-
- IMPLEMENT_SERIALIZE
- (
- if (!(nType & SER_GETHASH))
- READWRITE(nVersion);
- READWRITE(pos);
- READWRITE(vSpent);
- )
-
- void SetNull()
- {
- pos.SetNull();
- vSpent.clear();
- }
-
- bool IsNull()
- {
- return pos.IsNull();
- }
-
- friend bool operator==(const CTxIndex& a, const CTxIndex& b)
- {
- if (a.pos != b.pos || a.vSpent.size() != b.vSpent.size())
- return false;
- for (int i = 0; i < a.vSpent.size(); i++)
- if (a.vSpent[i] != b.vSpent[i])
- return false;
- return true;
- }
-
- friend bool operator!=(const CTxIndex& a, const CTxIndex& b)
- {
- return !(a == b);
- }
-};
-
-
-
-
-
-//
-// Nodes collect new transactions into a block, hash them into a hash tree,
-// and scan through nonce values to make the block's hash satisfy proof-of-work
-// requirements. When they solve the proof-of-work, they broadcast the block
-// to everyone and the block is added to the block chain. The first transaction
-// in the block is a special one that creates a new coin owned by the creator
-// of the block.
-//
-// Blocks are appended to blk0001.dat files on disk. Their location on disk
-// is indexed by CBlockIndex objects in memory.
-//
-class CBlock
-{
-public:
- // header
- int nVersion;
- uint256 hashPrevBlock;
- uint256 hashMerkleRoot;
- unsigned int nTime;
- unsigned int nBits;
- unsigned int nNonce;
-
- // network and disk
- vector<CTransaction> vtx;
-
- // memory only
- mutable vector<uint256> vMerkleTree;
-
-
- CBlock()
- {
- SetNull();
- }
-
- IMPLEMENT_SERIALIZE
- (
- READWRITE(this->nVersion);
- nVersion = this->nVersion;
- READWRITE(hashPrevBlock);
- READWRITE(hashMerkleRoot);
- READWRITE(nTime);
- READWRITE(nBits);
- READWRITE(nNonce);
-
- // ConnectBlock depends on vtx being last so it can calculate offset
- if (!(nType & (SER_GETHASH|SER_BLOCKHEADERONLY)))
- READWRITE(vtx);
- else if (fRead)
- const_cast<CBlock*>(this)->vtx.clear();
- )
-
- void SetNull()
- {
- nVersion = 1;
- hashPrevBlock = 0;
- hashMerkleRoot = 0;
- nTime = 0;
- nBits = 0;
- nNonce = 0;
- vtx.clear();
- vMerkleTree.clear();
- }
-
- bool IsNull() const
- {
- return (nBits == 0);
- }
-
- uint256 GetHash() const
- {
- return Hash(BEGIN(nVersion), END(nNonce));
- }
-
-
- uint256 BuildMerkleTree() const
- {
- vMerkleTree.clear();
- foreach(const CTransaction& tx, vtx)
- vMerkleTree.push_back(tx.GetHash());
- int j = 0;
- for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
- {
- for (int i = 0; i < nSize; i += 2)
- {
- int i2 = min(i+1, nSize-1);
- vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]), END(vMerkleTree[j+i]),
- BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2])));
- }
- j += nSize;
- }
- return (vMerkleTree.empty() ? 0 : vMerkleTree.back());
- }
-
- vector<uint256> GetMerkleBranch(int nIndex) const
- {
- if (vMerkleTree.empty())
- BuildMerkleTree();
- vector<uint256> vMerkleBranch;
- int j = 0;
- for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
- {
- int i = min(nIndex^1, nSize-1);
- vMerkleBranch.push_back(vMerkleTree[j+i]);
- nIndex >>= 1;
- j += nSize;
- }
- return vMerkleBranch;
- }
-
- static uint256 CheckMerkleBranch(uint256 hash, const vector<uint256>& vMerkleBranch, int nIndex)
- {
- if (nIndex == -1)
- return 0;
- foreach(const uint256& otherside, vMerkleBranch)
- {
- if (nIndex & 1)
- hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash));
- else
- hash = Hash(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside));
- nIndex >>= 1;
- }
- return hash;
- }
-
-
- bool WriteToDisk(bool fWriteTransactions, unsigned int& nFileRet, unsigned int& nBlockPosRet)
- {
- // Open history file to append
- CAutoFile fileout = AppendBlockFile(nFileRet);
- if (!fileout)
- return error("CBlock::WriteToDisk() : AppendBlockFile failed");
- if (!fWriteTransactions)
- fileout.nType |= SER_BLOCKHEADERONLY;
-
- // Write index header
- unsigned int nSize = fileout.GetSerializeSize(*this);
- fileout << FLATDATA(pchMessageStart) << nSize;
-
- // Write block
- nBlockPosRet = ftell(fileout);
- if (nBlockPosRet == -1)
- return error("CBlock::WriteToDisk() : ftell failed");
- fileout << *this;
-
- // Flush stdio buffers and commit to disk before returning
- fflush(fileout);
-#ifdef __WXMSW__
- _commit(_fileno(fileout));
-#else
- fsync(fileno(fileout));
-#endif
-
- return true;
- }
-
- bool ReadFromDisk(unsigned int nFile, unsigned int nBlockPos, bool fReadTransactions=true)
- {
- SetNull();
-
- // Open history file to read
- CAutoFile filein = OpenBlockFile(nFile, nBlockPos, "rb");
- if (!filein)
- return error("CBlock::ReadFromDisk() : OpenBlockFile failed");
- if (!fReadTransactions)
- filein.nType |= SER_BLOCKHEADERONLY;
-
- // Read block
- filein >> *this;
-
- // Check the header
- if (CBigNum().SetCompact(nBits) > bnProofOfWorkLimit)
- return error("CBlock::ReadFromDisk() : nBits errors in block header");
- if (GetHash() > CBigNum().SetCompact(nBits).getuint256())
- return error("CBlock::ReadFromDisk() : GetHash() errors in block header");
-
- return true;
- }
-
-
-
- void print() const
- {
- printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%d)\n",
- GetHash().ToString().substr(0,16).c_str(),
- nVersion,
- hashPrevBlock.ToString().substr(0,16).c_str(),
- hashMerkleRoot.ToString().substr(0,6).c_str(),
- nTime, nBits, nNonce,
- vtx.size());
- for (int i = 0; i < vtx.size(); i++)
- {
- printf(" ");
- vtx[i].print();
- }
- printf(" vMerkleTree: ");
- for (int i = 0; i < vMerkleTree.size(); i++)
- printf("%s ", vMerkleTree[i].ToString().substr(0,6).c_str());
- printf("\n");
- }
-
-
- int64 GetBlockValue(int64 nFees) const;
- bool DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex);
- bool ConnectBlock(CTxDB& txdb, CBlockIndex* pindex);
- bool ReadFromDisk(const CBlockIndex* blockindex, bool fReadTransactions=true);
- bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos);
- bool CheckBlock() const;
- bool AcceptBlock();
-};
-
-
-
-
-
-
-//
-// The block chain is a tree shaped structure starting with the
-// genesis block at the root, with each block potentially having multiple
-// candidates to be the next block. pprev and pnext link a path through the
-// main/longest chain. A blockindex may have multiple pprev pointing back
-// to it, but pnext will only point forward to the longest branch, or will
-// be null if the block is not part of the longest chain.
-//
-class CBlockIndex
-{
-public:
- const uint256* phashBlock;
- CBlockIndex* pprev;
- CBlockIndex* pnext;
- unsigned int nFile;
- unsigned int nBlockPos;
- int nHeight;
-
- // block header
- int nVersion;
- uint256 hashMerkleRoot;
- unsigned int nTime;
- unsigned int nBits;
- unsigned int nNonce;
-
-
- CBlockIndex()
- {
- phashBlock = NULL;
- pprev = NULL;
- pnext = NULL;
- nFile = 0;
- nBlockPos = 0;
- nHeight = 0;
-
- nVersion = 0;
- hashMerkleRoot = 0;
- nTime = 0;
- nBits = 0;
- nNonce = 0;
- }
-
- CBlockIndex(unsigned int nFileIn, unsigned int nBlockPosIn, CBlock& block)
- {
- phashBlock = NULL;
- pprev = NULL;
- pnext = NULL;
- nFile = nFileIn;
- nBlockPos = nBlockPosIn;
- nHeight = 0;
-
- nVersion = block.nVersion;
- hashMerkleRoot = block.hashMerkleRoot;
- nTime = block.nTime;
- nBits = block.nBits;
- nNonce = block.nNonce;
- }
-
- uint256 GetBlockHash() const
- {
- return *phashBlock;
- }
-
- bool IsInMainChain() const
- {
- return (pnext || this == pindexBest);
- }
-
- bool EraseBlockFromDisk()
- {
- // Open history file
- CAutoFile fileout = OpenBlockFile(nFile, nBlockPos, "rb+");
- if (!fileout)
- return false;
-
- // Overwrite with empty null block
- CBlock block;
- block.SetNull();
- fileout << block;
-
- return true;
- }
-
- enum { nMedianTimeSpan=11 };
-
- int64 GetMedianTimePast() const
- {
- unsigned int pmedian[nMedianTimeSpan];
- unsigned int* pbegin = &pmedian[nMedianTimeSpan];
- unsigned int* pend = &pmedian[nMedianTimeSpan];
-
- const CBlockIndex* pindex = this;
- for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev)
- *(--pbegin) = pindex->nTime;
-
- sort(pbegin, pend);
- return pbegin[(pend - pbegin)/2];
- }
-
- int64 GetMedianTime() const
- {
- const CBlockIndex* pindex = this;
- for (int i = 0; i < nMedianTimeSpan/2; i++)
- {
- if (!pindex->pnext)
- return nTime;
- pindex = pindex->pnext;
- }
- return pindex->GetMedianTimePast();
- }
-
-
-
- string ToString() const
- {
- return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)",
- pprev, pnext, nFile, nBlockPos, nHeight,
- hashMerkleRoot.ToString().substr(0,6).c_str(),
- GetBlockHash().ToString().substr(0,16).c_str());
- }
-
- void print() const
- {
- printf("%s\n", ToString().c_str());
- }
-};
-
-
-
-//
-// Used to marshal pointers into hashes for db storage.
-//
-class CDiskBlockIndex : public CBlockIndex
-{
-public:
- uint256 hashPrev;
- uint256 hashNext;
-
- CDiskBlockIndex()
- {
- hashPrev = 0;
- hashNext = 0;
- }
-
- explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex)
- {
- hashPrev = (pprev ? pprev->GetBlockHash() : 0);
- hashNext = (pnext ? pnext->GetBlockHash() : 0);
- }
-
- IMPLEMENT_SERIALIZE
- (
- if (!(nType & SER_GETHASH))
- READWRITE(nVersion);
-
- READWRITE(hashNext);
- READWRITE(nFile);
- READWRITE(nBlockPos);
- READWRITE(nHeight);
-
- // block header
- READWRITE(this->nVersion);
- READWRITE(hashPrev);
- READWRITE(hashMerkleRoot);
- READWRITE(nTime);
- READWRITE(nBits);
- READWRITE(nNonce);
- )
-
- uint256 GetBlockHash() const
- {
- CBlock block;
- block.nVersion = nVersion;
- block.hashPrevBlock = hashPrev;
- block.hashMerkleRoot = hashMerkleRoot;
- block.nTime = nTime;
- block.nBits = nBits;
- block.nNonce = nNonce;
- return block.GetHash();
- }
-
-
- string ToString() const
- {
- string str = "CDiskBlockIndex(";
- str += CBlockIndex::ToString();
- str += strprintf("\n hashBlock=%s, hashPrev=%s, hashNext=%s)",
- GetBlockHash().ToString().c_str(),
- hashPrev.ToString().substr(0,16).c_str(),
- hashNext.ToString().substr(0,16).c_str());
- return str;
- }
-
- void print() const
- {
- printf("%s\n", ToString().c_str());
- }
-};
-
-
-
-
-
-
-
-
-//
-// Describes a place in the block chain to another node such that if the
-// other node doesn't have the same branch, it can find a recent common trunk.
-// The further back it is, the further before the fork it may be.
-//
-class CBlockLocator
-{
-protected:
- vector<uint256> vHave;
-public:
-
- CBlockLocator()
- {
- }
-
- explicit CBlockLocator(const CBlockIndex* pindex)
- {
- Set(pindex);
- }
-
- explicit CBlockLocator(uint256 hashBlock)
- {
- map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
- if (mi != mapBlockIndex.end())
- Set((*mi).second);
- }
-
- IMPLEMENT_SERIALIZE
- (
- if (!(nType & SER_GETHASH))
- READWRITE(nVersion);
- READWRITE(vHave);
- )
-
- void Set(const CBlockIndex* pindex)
- {
- vHave.clear();
- int nStep = 1;
- while (pindex)
- {
- vHave.push_back(pindex->GetBlockHash());
-
- // Exponentially larger steps back
- for (int i = 0; pindex && i < nStep; i++)
- pindex = pindex->pprev;
- if (vHave.size() > 10)
- nStep *= 2;
- }
- vHave.push_back(hashGenesisBlock);
- }
-
- int GetDistanceBack()
- {
- // Retrace how far back it was in the sender's branch
- int nDistance = 0;
- int nStep = 1;
- foreach(const uint256& hash, vHave)
- {
- map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
- if (mi != mapBlockIndex.end())
- {
- CBlockIndex* pindex = (*mi).second;
- if (pindex->IsInMainChain())
- return nDistance;
- }
- nDistance += nStep;
- if (nDistance > 10)
- nStep *= 2;
- }
- return nDistance;
- }
-
- CBlockIndex* GetBlockIndex()
- {
- // Find the first block the caller has in the main chain
- foreach(const uint256& hash, vHave)
- {
- map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
- if (mi != mapBlockIndex.end())
- {
- CBlockIndex* pindex = (*mi).second;
- if (pindex->IsInMainChain())
- return pindex;
- }
- }
- return pindexGenesisBlock;
- }
-
- uint256 GetBlockHash()
- {
- // Find the first block the caller has in the main chain
- foreach(const uint256& hash, vHave)
- {
- map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
- if (mi != mapBlockIndex.end())
- {
- CBlockIndex* pindex = (*mi).second;
- if (pindex->IsInMainChain())
- return hash;
- }
- }
- return hashGenesisBlock;
- }
-
- int GetHeight()
- {
- CBlockIndex* pindex = GetBlockIndex();
- if (!pindex)
- return 0;
- return pindex->nHeight;
- }
-};
-
-
-
-
-
-
-//
-// Private key that includes an expiration date in case it never gets used.
-//
-class CWalletKey
-{
-public:
- CPrivKey vchPrivKey;
- int64 nTimeCreated;
- int64 nTimeExpires;
- string strComment;
- //// todo: add something to note what created it (user, getnewaddress, change)
- //// maybe should have a map<string, string> property map
-
- CWalletKey(int64 nTimeExpiresIn=0)
- {
- nTimeCreated = (nTimeExpiresIn ? GetTime() : 0);
- nTimeExpires = nTimeExpiresIn;
- }
-
- IMPLEMENT_SERIALIZE
- (
- if (!(nType & SER_GETHASH))
- READWRITE(nVersion);
- READWRITE(vchPrivKey);
- READWRITE(nTimeCreated);
- READWRITE(nTimeExpires);
- READWRITE(strComment);
- )
-};
-
-
-
-
-
-
-extern map<uint256, CTransaction> mapTransactions;
-extern map<uint256, CWalletTx> mapWallet;
-extern vector<uint256> vWalletUpdated;
-extern CCriticalSection cs_mapWallet;
-extern map<vector<unsigned char>, CPrivKey> mapKeys;
-extern map<uint160, vector<unsigned char> > mapPubKeys;
-extern CCriticalSection cs_mapKeys;
-extern CKey keyUser;
+// Copyright (c) 2009-2010 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +class COutPoint; +class CInPoint; +class CDiskTxPos; +class CCoinBase; +class CTxIn; +class CTxOut; +class CTransaction; +class CBlock; +class CBlockIndex; +class CWalletTx; +class CKeyItem; + +static const unsigned int MAX_SIZE = 0x02000000; +static const int64 COIN = 100000000; +static const int64 CENT = 1000000; +static const int COINBASE_MATURITY = 100; + +static const CBigNum bnProofOfWorkLimit(~uint256(0) >> 32); + + + + + + +extern CCriticalSection cs_main; +extern map<uint256, CBlockIndex*> mapBlockIndex; +extern const uint256 hashGenesisBlock; +extern CBlockIndex* pindexGenesisBlock; +extern int nBestHeight; +extern uint256 hashBestChain; +extern CBlockIndex* pindexBest; +extern unsigned int nTransactionsUpdated; +extern map<uint256, int> mapRequestCount; +extern CCriticalSection cs_mapRequestCount; +extern map<string, string> mapAddressBook; +extern CCriticalSection cs_mapAddressBook; +extern vector<unsigned char> vchDefaultKey; + +// Settings +extern int fGenerateBitcoins; +extern int64 nTransactionFee; +extern CAddress addrIncoming; +extern int fLimitProcessors; +extern int nLimitProcessors; +extern int fMinimizeToTray; +extern int fMinimizeOnClose; + + + + + + + +bool CheckDiskSpace(int64 nAdditionalBytes=0); +FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb"); +FILE* AppendBlockFile(unsigned int& nFileRet); +bool AddKey(const CKey& key); +vector<unsigned char> GenerateNewKey(); +bool AddToWallet(const CWalletTx& wtxIn); +void WalletUpdateSpent(const COutPoint& prevout); +void ReacceptWalletTransactions(); +bool LoadBlockIndex(bool fAllowNew=true); +void PrintBlockTree(); +bool ProcessMessages(CNode* pfrom); +bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv); +bool SendMessages(CNode* pto, bool fSendTrickle); +int64 GetBalance(); +bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CKey& keyRet, int64& nFeeRequiredRet); +bool CommitTransaction(CWalletTx& wtxNew, const CKey& key); +bool BroadcastTransaction(CWalletTx& wtxNew); +string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false); +string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false); +void GenerateBitcoins(bool fGenerate); +void ThreadBitcoinMiner(void* parg); +void BitcoinMiner(); + + + + + + + + + + + + +class CDiskTxPos +{ +public: + unsigned int nFile; + unsigned int nBlockPos; + unsigned int nTxPos; + + CDiskTxPos() + { + SetNull(); + } + + CDiskTxPos(unsigned int nFileIn, unsigned int nBlockPosIn, unsigned int nTxPosIn) + { + nFile = nFileIn; + nBlockPos = nBlockPosIn; + nTxPos = nTxPosIn; + } + + IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); ) + void SetNull() { nFile = -1; nBlockPos = 0; nTxPos = 0; } + bool IsNull() const { return (nFile == -1); } + + friend bool operator==(const CDiskTxPos& a, const CDiskTxPos& b) + { + return (a.nFile == b.nFile && + a.nBlockPos == b.nBlockPos && + a.nTxPos == b.nTxPos); + } + + friend bool operator!=(const CDiskTxPos& a, const CDiskTxPos& b) + { + return !(a == b); + } + + string ToString() const + { + if (IsNull()) + return strprintf("null"); + else + return strprintf("(nFile=%d, nBlockPos=%d, nTxPos=%d)", nFile, nBlockPos, nTxPos); + } + + void print() const + { + printf("%s", ToString().c_str()); + } +}; + + + + +class CInPoint +{ +public: + CTransaction* ptx; + unsigned int n; + + CInPoint() { SetNull(); } + CInPoint(CTransaction* ptxIn, unsigned int nIn) { ptx = ptxIn; n = nIn; } + void SetNull() { ptx = NULL; n = -1; } + bool IsNull() const { return (ptx == NULL && n == -1); } +}; + + + + +class COutPoint +{ +public: + uint256 hash; + unsigned int n; + + COutPoint() { SetNull(); } + COutPoint(uint256 hashIn, unsigned int nIn) { hash = hashIn; n = nIn; } + IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); ) + void SetNull() { hash = 0; n = -1; } + bool IsNull() const { return (hash == 0 && n == -1); } + + friend bool operator<(const COutPoint& a, const COutPoint& b) + { + return (a.hash < b.hash || (a.hash == b.hash && a.n < b.n)); + } + + friend bool operator==(const COutPoint& a, const COutPoint& b) + { + return (a.hash == b.hash && a.n == b.n); + } + + friend bool operator!=(const COutPoint& a, const COutPoint& b) + { + return !(a == b); + } + + string ToString() const + { + return strprintf("COutPoint(%s, %d)", hash.ToString().substr(0,6).c_str(), n); + } + + void print() const + { + printf("%s\n", ToString().c_str()); + } +}; + + + + +// +// An input of a transaction. It contains the location of the previous +// transaction's output that it claims and a signature that matches the +// output's public key. +// +class CTxIn +{ +public: + COutPoint prevout; + CScript scriptSig; + unsigned int nSequence; + + CTxIn() + { + nSequence = UINT_MAX; + } + + explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX) + { + prevout = prevoutIn; + scriptSig = scriptSigIn; + nSequence = nSequenceIn; + } + + CTxIn(uint256 hashPrevTx, unsigned int nOut, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX) + { + prevout = COutPoint(hashPrevTx, nOut); + scriptSig = scriptSigIn; + nSequence = nSequenceIn; + } + + IMPLEMENT_SERIALIZE + ( + READWRITE(prevout); + READWRITE(scriptSig); + READWRITE(nSequence); + ) + + bool IsFinal() const + { + return (nSequence == UINT_MAX); + } + + friend bool operator==(const CTxIn& a, const CTxIn& b) + { + return (a.prevout == b.prevout && + a.scriptSig == b.scriptSig && + a.nSequence == b.nSequence); + } + + friend bool operator!=(const CTxIn& a, const CTxIn& b) + { + return !(a == b); + } + + string ToString() const + { + string str; + str += strprintf("CTxIn("); + str += prevout.ToString(); + if (prevout.IsNull()) + str += strprintf(", coinbase %s", HexStr(scriptSig.begin(), scriptSig.end(), false).c_str()); + else + str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24).c_str()); + if (nSequence != UINT_MAX) + str += strprintf(", nSequence=%u", nSequence); + str += ")"; + return str; + } + + void print() const + { + printf("%s\n", ToString().c_str()); + } + + bool IsMine() const; + int64 GetDebit() const; +}; + + + + +// +// An output of a transaction. It contains the public key that the next input +// must be able to sign with to claim it. +// +class CTxOut +{ +public: + int64 nValue; + CScript scriptPubKey; + +public: + CTxOut() + { + SetNull(); + } + + CTxOut(int64 nValueIn, CScript scriptPubKeyIn) + { + nValue = nValueIn; + scriptPubKey = scriptPubKeyIn; + } + + IMPLEMENT_SERIALIZE + ( + READWRITE(nValue); + READWRITE(scriptPubKey); + ) + + void SetNull() + { + nValue = -1; + scriptPubKey.clear(); + } + + bool IsNull() + { + return (nValue == -1); + } + + uint256 GetHash() const + { + return SerializeHash(*this); + } + + bool IsMine() const + { + return ::IsMine(scriptPubKey); + } + + int64 GetCredit() const + { + if (IsMine()) + return nValue; + return 0; + } + + friend bool operator==(const CTxOut& a, const CTxOut& b) + { + return (a.nValue == b.nValue && + a.scriptPubKey == b.scriptPubKey); + } + + friend bool operator!=(const CTxOut& a, const CTxOut& b) + { + return !(a == b); + } + + string ToString() const + { + if (scriptPubKey.size() < 6) + return "CTxOut(error)"; + return strprintf("CTxOut(nValue=%"PRI64d".%08"PRI64d", scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,24).c_str()); + } + + void print() const + { + printf("%s\n", ToString().c_str()); + } +}; + + + + +// +// The basic transaction that is broadcasted on the network and contained in +// blocks. A transaction can contain multiple inputs and outputs. +// +class CTransaction +{ +public: + int nVersion; + vector<CTxIn> vin; + vector<CTxOut> vout; + unsigned int nLockTime; + + + CTransaction() + { + SetNull(); + } + + IMPLEMENT_SERIALIZE + ( + READWRITE(this->nVersion); + nVersion = this->nVersion; + READWRITE(vin); + READWRITE(vout); + READWRITE(nLockTime); + ) + + void SetNull() + { + nVersion = 1; + vin.clear(); + vout.clear(); + nLockTime = 0; + } + + bool IsNull() const + { + return (vin.empty() && vout.empty()); + } + + uint256 GetHash() const + { + return SerializeHash(*this); + } + + bool IsFinal(int64 nBlockTime=0) const + { + // Time based nLockTime implemented in 0.1.6, + // do not use time based until most 0.1.5 nodes have upgraded. + if (nLockTime == 0) + return true; + if (nBlockTime == 0) + nBlockTime = GetAdjustedTime(); + if (nLockTime < (nLockTime < 500000000 ? nBestHeight : nBlockTime)) + return true; + foreach(const CTxIn& txin, vin) + if (!txin.IsFinal()) + return false; + return true; + } + + bool IsNewerThan(const CTransaction& old) const + { + if (vin.size() != old.vin.size()) + return false; + for (int i = 0; i < vin.size(); i++) + if (vin[i].prevout != old.vin[i].prevout) + return false; + + bool fNewer = false; + unsigned int nLowest = UINT_MAX; + for (int i = 0; i < vin.size(); i++) + { + if (vin[i].nSequence != old.vin[i].nSequence) + { + if (vin[i].nSequence <= nLowest) + { + fNewer = false; + nLowest = vin[i].nSequence; + } + if (old.vin[i].nSequence < nLowest) + { + fNewer = true; + nLowest = old.vin[i].nSequence; + } + } + } + return fNewer; + } + + bool IsCoinBase() const + { + return (vin.size() == 1 && vin[0].prevout.IsNull()); + } + + bool CheckTransaction() const + { + // Basic checks that don't depend on any context + if (vin.empty() || vout.empty()) + return error("CTransaction::CheckTransaction() : vin or vout empty"); + + // Check for negative values + foreach(const CTxOut& txout, vout) + if (txout.nValue < 0) + return error("CTransaction::CheckTransaction() : txout.nValue negative"); + + if (IsCoinBase()) + { + if (vin[0].scriptSig.size() < 2 || vin[0].scriptSig.size() > 100) + return error("CTransaction::CheckTransaction() : coinbase script size"); + } + else + { + foreach(const CTxIn& txin, vin) + if (txin.prevout.IsNull()) + return error("CTransaction::CheckTransaction() : prevout is null"); + } + + return true; + } + + bool IsMine() const + { + foreach(const CTxOut& txout, vout) + if (txout.IsMine()) + return true; + return false; + } + + int64 GetDebit() const + { + int64 nDebit = 0; + foreach(const CTxIn& txin, vin) + nDebit += txin.GetDebit(); + return nDebit; + } + + int64 GetCredit() const + { + int64 nCredit = 0; + foreach(const CTxOut& txout, vout) + nCredit += txout.GetCredit(); + return nCredit; + } + + int64 GetValueOut() const + { + int64 nValueOut = 0; + foreach(const CTxOut& txout, vout) + { + if (txout.nValue < 0) + throw runtime_error("CTransaction::GetValueOut() : negative value"); + nValueOut += txout.nValue; + } + return nValueOut; + } + + int64 GetMinFee(unsigned int nBlockSize=1) const + { + // Base fee is 1 cent per kilobyte + unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK); + int64 nMinFee = (1 + (int64)nBytes / 1000) * CENT; + + // Transactions under 60K are free as long as block size is under 80K + // (about 27,000bc if made of 50bc inputs) + if (nBytes < 60000 && nBlockSize < 80000) + nMinFee = 0; + + // Transactions under 3K are free as long as block size is under 200K + if (nBytes < 3000 && nBlockSize < 200000) + nMinFee = 0; + + // To limit dust spam, require a 0.01 fee if any output is less than 0.01 + if (nMinFee < CENT) + foreach(const CTxOut& txout, vout) + if (txout.nValue < CENT) + nMinFee = CENT; + + return nMinFee; + } + + + + bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL) + { + CAutoFile filein = OpenBlockFile(pos.nFile, 0, pfileRet ? "rb+" : "rb"); + if (!filein) + return error("CTransaction::ReadFromDisk() : OpenBlockFile failed"); + + // Read transaction + if (fseek(filein, pos.nTxPos, SEEK_SET) != 0) + return error("CTransaction::ReadFromDisk() : fseek failed"); + filein >> *this; + + // Return file pointer + if (pfileRet) + { + if (fseek(filein, pos.nTxPos, SEEK_SET) != 0) + return error("CTransaction::ReadFromDisk() : second fseek failed"); + *pfileRet = filein.release(); + } + return true; + } + + + friend bool operator==(const CTransaction& a, const CTransaction& b) + { + return (a.nVersion == b.nVersion && + a.vin == b.vin && + a.vout == b.vout && + a.nLockTime == b.nLockTime); + } + + friend bool operator!=(const CTransaction& a, const CTransaction& b) + { + return !(a == b); + } + + + string ToString() const + { + string str; + str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%d, vout.size=%d, nLockTime=%d)\n", + GetHash().ToString().substr(0,6).c_str(), + nVersion, + vin.size(), + vout.size(), + nLockTime); + for (int i = 0; i < vin.size(); i++) + str += " " + vin[i].ToString() + "\n"; + for (int i = 0; i < vout.size(); i++) + str += " " + vout[i].ToString() + "\n"; + return str; + } + + void print() const + { + printf("%s", ToString().c_str()); + } + + + + bool DisconnectInputs(CTxDB& txdb); + bool ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPool, CDiskTxPos posThisTx, int nHeight, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee=0); + bool ClientConnectInputs(); + + bool AcceptTransaction(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL); + + bool AcceptTransaction(bool fCheckInputs=true, bool* pfMissingInputs=NULL) + { + CTxDB txdb("r"); + return AcceptTransaction(txdb, fCheckInputs, pfMissingInputs); + } + +protected: + bool AddToMemoryPool(); +public: + bool RemoveFromMemoryPool(); +}; + + + + + +// +// A transaction with a merkle branch linking it to the block chain +// +class CMerkleTx : public CTransaction +{ +public: + uint256 hashBlock; + vector<uint256> vMerkleBranch; + int nIndex; + + // memory only + mutable bool fMerkleVerified; + mutable bool fGetCreditCached; + mutable int64 nGetCreditCached; + + + CMerkleTx() + { + Init(); + } + + CMerkleTx(const CTransaction& txIn) : CTransaction(txIn) + { + Init(); + } + + void Init() + { + hashBlock = 0; + nIndex = -1; + fMerkleVerified = false; + fGetCreditCached = false; + nGetCreditCached = 0; + } + + IMPLEMENT_SERIALIZE + ( + nSerSize += SerReadWrite(s, *(CTransaction*)this, nType, nVersion, ser_action); + nVersion = this->nVersion; + READWRITE(hashBlock); + READWRITE(vMerkleBranch); + READWRITE(nIndex); + ) + + int64 GetCredit(bool fUseCache=false) const + { + // Must wait until coinbase is safely deep enough in the chain before valuing it + if (IsCoinBase() && GetBlocksToMaturity() > 0) + return 0; + + // GetBalance can assume transactions in mapWallet won't change + if (fUseCache && fGetCreditCached) + return nGetCreditCached; + nGetCreditCached = CTransaction::GetCredit(); + fGetCreditCached = true; + return nGetCreditCached; + } + + + int SetMerkleBranch(const CBlock* pblock=NULL); + int GetDepthInMainChain(int& nHeightRet) const; + int GetDepthInMainChain() const { int nHeight; return GetDepthInMainChain(nHeight); } + bool IsInMainChain() const { return GetDepthInMainChain() > 0; } + int GetBlocksToMaturity() const; + bool AcceptTransaction(CTxDB& txdb, bool fCheckInputs=true); + bool AcceptTransaction() { CTxDB txdb("r"); return AcceptTransaction(txdb); } +}; + + + + +// +// A transaction with a bunch of additional info that only the owner cares +// about. It includes any unrecorded transactions needed to link it back +// to the block chain. +// +class CWalletTx : public CMerkleTx +{ +public: + vector<CMerkleTx> vtxPrev; + map<string, string> mapValue; + vector<pair<string, string> > vOrderForm; + unsigned int fTimeReceivedIsTxTime; + unsigned int nTimeReceived; // time received by this node + char fFromMe; + char fSpent; + //// probably need to sign the order info so know it came from payer + + // memory only UI hints + mutable unsigned int nTimeDisplayed; + mutable int nLinesDisplayed; + + + CWalletTx() + { + Init(); + } + + CWalletTx(const CMerkleTx& txIn) : CMerkleTx(txIn) + { + Init(); + } + + CWalletTx(const CTransaction& txIn) : CMerkleTx(txIn) + { + Init(); + } + + void Init() + { + fTimeReceivedIsTxTime = false; + nTimeReceived = 0; + fFromMe = false; + fSpent = false; + nTimeDisplayed = 0; + nLinesDisplayed = 0; + } + + IMPLEMENT_SERIALIZE + ( + nSerSize += SerReadWrite(s, *(CMerkleTx*)this, nType, nVersion, ser_action); + nVersion = this->nVersion; + READWRITE(vtxPrev); + READWRITE(mapValue); + READWRITE(vOrderForm); + READWRITE(fTimeReceivedIsTxTime); + READWRITE(nTimeReceived); + READWRITE(fFromMe); + READWRITE(fSpent); + ) + + bool WriteToDisk() + { + return CWalletDB().WriteTx(GetHash(), *this); + } + + + int64 GetTxTime() const; + int GetRequestCount() const; + + void AddSupportingTransactions(CTxDB& txdb); + + bool AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs=true); + bool AcceptWalletTransaction() { CTxDB txdb("r"); return AcceptWalletTransaction(txdb); } + + void RelayWalletTransaction(CTxDB& txdb); + void RelayWalletTransaction() { CTxDB txdb("r"); RelayWalletTransaction(txdb); } +}; + + + + +// +// A txdb record that contains the disk location of a transaction and the +// locations of transactions that spend its outputs. vSpent is really only +// used as a flag, but having the location is very helpful for debugging. +// +class CTxIndex +{ +public: + CDiskTxPos pos; + vector<CDiskTxPos> vSpent; + + CTxIndex() + { + SetNull(); + } + + CTxIndex(const CDiskTxPos& posIn, unsigned int nOutputs) + { + pos = posIn; + vSpent.resize(nOutputs); + } + + IMPLEMENT_SERIALIZE + ( + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + READWRITE(pos); + READWRITE(vSpent); + ) + + void SetNull() + { + pos.SetNull(); + vSpent.clear(); + } + + bool IsNull() + { + return pos.IsNull(); + } + + friend bool operator==(const CTxIndex& a, const CTxIndex& b) + { + if (a.pos != b.pos || a.vSpent.size() != b.vSpent.size()) + return false; + for (int i = 0; i < a.vSpent.size(); i++) + if (a.vSpent[i] != b.vSpent[i]) + return false; + return true; + } + + friend bool operator!=(const CTxIndex& a, const CTxIndex& b) + { + return !(a == b); + } +}; + + + + + +// +// Nodes collect new transactions into a block, hash them into a hash tree, +// and scan through nonce values to make the block's hash satisfy proof-of-work +// requirements. When they solve the proof-of-work, they broadcast the block +// to everyone and the block is added to the block chain. The first transaction +// in the block is a special one that creates a new coin owned by the creator +// of the block. +// +// Blocks are appended to blk0001.dat files on disk. Their location on disk +// is indexed by CBlockIndex objects in memory. +// +class CBlock +{ +public: + // header + int nVersion; + uint256 hashPrevBlock; + uint256 hashMerkleRoot; + unsigned int nTime; + unsigned int nBits; + unsigned int nNonce; + + // network and disk + vector<CTransaction> vtx; + + // memory only + mutable vector<uint256> vMerkleTree; + + + CBlock() + { + SetNull(); + } + + IMPLEMENT_SERIALIZE + ( + READWRITE(this->nVersion); + nVersion = this->nVersion; + READWRITE(hashPrevBlock); + READWRITE(hashMerkleRoot); + READWRITE(nTime); + READWRITE(nBits); + READWRITE(nNonce); + + // ConnectBlock depends on vtx being last so it can calculate offset + if (!(nType & (SER_GETHASH|SER_BLOCKHEADERONLY))) + READWRITE(vtx); + else if (fRead) + const_cast<CBlock*>(this)->vtx.clear(); + ) + + void SetNull() + { + nVersion = 1; + hashPrevBlock = 0; + hashMerkleRoot = 0; + nTime = 0; + nBits = 0; + nNonce = 0; + vtx.clear(); + vMerkleTree.clear(); + } + + bool IsNull() const + { + return (nBits == 0); + } + + uint256 GetHash() const + { + return Hash(BEGIN(nVersion), END(nNonce)); + } + + + uint256 BuildMerkleTree() const + { + vMerkleTree.clear(); + foreach(const CTransaction& tx, vtx) + vMerkleTree.push_back(tx.GetHash()); + int j = 0; + for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2) + { + for (int i = 0; i < nSize; i += 2) + { + int i2 = min(i+1, nSize-1); + vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]), END(vMerkleTree[j+i]), + BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2]))); + } + j += nSize; + } + return (vMerkleTree.empty() ? 0 : vMerkleTree.back()); + } + + vector<uint256> GetMerkleBranch(int nIndex) const + { + if (vMerkleTree.empty()) + BuildMerkleTree(); + vector<uint256> vMerkleBranch; + int j = 0; + for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2) + { + int i = min(nIndex^1, nSize-1); + vMerkleBranch.push_back(vMerkleTree[j+i]); + nIndex >>= 1; + j += nSize; + } + return vMerkleBranch; + } + + static uint256 CheckMerkleBranch(uint256 hash, const vector<uint256>& vMerkleBranch, int nIndex) + { + if (nIndex == -1) + return 0; + foreach(const uint256& otherside, vMerkleBranch) + { + if (nIndex & 1) + hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash)); + else + hash = Hash(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside)); + nIndex >>= 1; + } + return hash; + } + + + bool WriteToDisk(bool fWriteTransactions, unsigned int& nFileRet, unsigned int& nBlockPosRet) + { + // Open history file to append + CAutoFile fileout = AppendBlockFile(nFileRet); + if (!fileout) + return error("CBlock::WriteToDisk() : AppendBlockFile failed"); + if (!fWriteTransactions) + fileout.nType |= SER_BLOCKHEADERONLY; + + // Write index header + unsigned int nSize = fileout.GetSerializeSize(*this); + fileout << FLATDATA(pchMessageStart) << nSize; + + // Write block + nBlockPosRet = ftell(fileout); + if (nBlockPosRet == -1) + return error("CBlock::WriteToDisk() : ftell failed"); + fileout << *this; + + // Flush stdio buffers and commit to disk before returning + fflush(fileout); +#ifdef __WXMSW__ + _commit(_fileno(fileout)); +#else + fsync(fileno(fileout)); +#endif + + return true; + } + + bool ReadFromDisk(unsigned int nFile, unsigned int nBlockPos, bool fReadTransactions=true) + { + SetNull(); + + // Open history file to read + CAutoFile filein = OpenBlockFile(nFile, nBlockPos, "rb"); + if (!filein) + return error("CBlock::ReadFromDisk() : OpenBlockFile failed"); + if (!fReadTransactions) + filein.nType |= SER_BLOCKHEADERONLY; + + // Read block + filein >> *this; + + // Check the header + if (CBigNum().SetCompact(nBits) > bnProofOfWorkLimit) + return error("CBlock::ReadFromDisk() : nBits errors in block header"); + if (GetHash() > CBigNum().SetCompact(nBits).getuint256()) + return error("CBlock::ReadFromDisk() : GetHash() errors in block header"); + + return true; + } + + + + void print() const + { + printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%d)\n", + GetHash().ToString().substr(0,16).c_str(), + nVersion, + hashPrevBlock.ToString().substr(0,16).c_str(), + hashMerkleRoot.ToString().substr(0,6).c_str(), + nTime, nBits, nNonce, + vtx.size()); + for (int i = 0; i < vtx.size(); i++) + { + printf(" "); + vtx[i].print(); + } + printf(" vMerkleTree: "); + for (int i = 0; i < vMerkleTree.size(); i++) + printf("%s ", vMerkleTree[i].ToString().substr(0,6).c_str()); + printf("\n"); + } + + + int64 GetBlockValue(int64 nFees) const; + bool DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex); + bool ConnectBlock(CTxDB& txdb, CBlockIndex* pindex); + bool ReadFromDisk(const CBlockIndex* blockindex, bool fReadTransactions=true); + bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos); + bool CheckBlock() const; + bool AcceptBlock(); +}; + + + + + + +// +// The block chain is a tree shaped structure starting with the +// genesis block at the root, with each block potentially having multiple +// candidates to be the next block. pprev and pnext link a path through the +// main/longest chain. A blockindex may have multiple pprev pointing back +// to it, but pnext will only point forward to the longest branch, or will +// be null if the block is not part of the longest chain. +// +class CBlockIndex +{ +public: + const uint256* phashBlock; + CBlockIndex* pprev; + CBlockIndex* pnext; + unsigned int nFile; + unsigned int nBlockPos; + int nHeight; + + // block header + int nVersion; + uint256 hashMerkleRoot; + unsigned int nTime; + unsigned int nBits; + unsigned int nNonce; + + + CBlockIndex() + { + phashBlock = NULL; + pprev = NULL; + pnext = NULL; + nFile = 0; + nBlockPos = 0; + nHeight = 0; + + nVersion = 0; + hashMerkleRoot = 0; + nTime = 0; + nBits = 0; + nNonce = 0; + } + + CBlockIndex(unsigned int nFileIn, unsigned int nBlockPosIn, CBlock& block) + { + phashBlock = NULL; + pprev = NULL; + pnext = NULL; + nFile = nFileIn; + nBlockPos = nBlockPosIn; + nHeight = 0; + + nVersion = block.nVersion; + hashMerkleRoot = block.hashMerkleRoot; + nTime = block.nTime; + nBits = block.nBits; + nNonce = block.nNonce; + } + + uint256 GetBlockHash() const + { + return *phashBlock; + } + + bool IsInMainChain() const + { + return (pnext || this == pindexBest); + } + + bool EraseBlockFromDisk() + { + // Open history file + CAutoFile fileout = OpenBlockFile(nFile, nBlockPos, "rb+"); + if (!fileout) + return false; + + // Overwrite with empty null block + CBlock block; + block.SetNull(); + fileout << block; + + return true; + } + + enum { nMedianTimeSpan=11 }; + + int64 GetMedianTimePast() const + { + unsigned int pmedian[nMedianTimeSpan]; + unsigned int* pbegin = &pmedian[nMedianTimeSpan]; + unsigned int* pend = &pmedian[nMedianTimeSpan]; + + const CBlockIndex* pindex = this; + for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev) + *(--pbegin) = pindex->nTime; + + sort(pbegin, pend); + return pbegin[(pend - pbegin)/2]; + } + + int64 GetMedianTime() const + { + const CBlockIndex* pindex = this; + for (int i = 0; i < nMedianTimeSpan/2; i++) + { + if (!pindex->pnext) + return nTime; + pindex = pindex->pnext; + } + return pindex->GetMedianTimePast(); + } + + + + string ToString() const + { + return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)", + pprev, pnext, nFile, nBlockPos, nHeight, + hashMerkleRoot.ToString().substr(0,6).c_str(), + GetBlockHash().ToString().substr(0,16).c_str()); + } + + void print() const + { + printf("%s\n", ToString().c_str()); + } +}; + + + +// +// Used to marshal pointers into hashes for db storage. +// +class CDiskBlockIndex : public CBlockIndex +{ +public: + uint256 hashPrev; + uint256 hashNext; + + CDiskBlockIndex() + { + hashPrev = 0; + hashNext = 0; + } + + explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex) + { + hashPrev = (pprev ? pprev->GetBlockHash() : 0); + hashNext = (pnext ? pnext->GetBlockHash() : 0); + } + + IMPLEMENT_SERIALIZE + ( + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + + READWRITE(hashNext); + READWRITE(nFile); + READWRITE(nBlockPos); + READWRITE(nHeight); + + // block header + READWRITE(this->nVersion); + READWRITE(hashPrev); + READWRITE(hashMerkleRoot); + READWRITE(nTime); + READWRITE(nBits); + READWRITE(nNonce); + ) + + uint256 GetBlockHash() const + { + CBlock block; + block.nVersion = nVersion; + block.hashPrevBlock = hashPrev; + block.hashMerkleRoot = hashMerkleRoot; + block.nTime = nTime; + block.nBits = nBits; + block.nNonce = nNonce; + return block.GetHash(); + } + + + string ToString() const + { + string str = "CDiskBlockIndex("; + str += CBlockIndex::ToString(); + str += strprintf("\n hashBlock=%s, hashPrev=%s, hashNext=%s)", + GetBlockHash().ToString().c_str(), + hashPrev.ToString().substr(0,16).c_str(), + hashNext.ToString().substr(0,16).c_str()); + return str; + } + + void print() const + { + printf("%s\n", ToString().c_str()); + } +}; + + + + + + + + +// +// Describes a place in the block chain to another node such that if the +// other node doesn't have the same branch, it can find a recent common trunk. +// The further back it is, the further before the fork it may be. +// +class CBlockLocator +{ +protected: + vector<uint256> vHave; +public: + + CBlockLocator() + { + } + + explicit CBlockLocator(const CBlockIndex* pindex) + { + Set(pindex); + } + + explicit CBlockLocator(uint256 hashBlock) + { + map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock); + if (mi != mapBlockIndex.end()) + Set((*mi).second); + } + + IMPLEMENT_SERIALIZE + ( + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + READWRITE(vHave); + ) + + void Set(const CBlockIndex* pindex) + { + vHave.clear(); + int nStep = 1; + while (pindex) + { + vHave.push_back(pindex->GetBlockHash()); + + // Exponentially larger steps back + for (int i = 0; pindex && i < nStep; i++) + pindex = pindex->pprev; + if (vHave.size() > 10) + nStep *= 2; + } + vHave.push_back(hashGenesisBlock); + } + + int GetDistanceBack() + { + // Retrace how far back it was in the sender's branch + int nDistance = 0; + int nStep = 1; + foreach(const uint256& hash, vHave) + { + map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash); + if (mi != mapBlockIndex.end()) + { + CBlockIndex* pindex = (*mi).second; + if (pindex->IsInMainChain()) + return nDistance; + } + nDistance += nStep; + if (nDistance > 10) + nStep *= 2; + } + return nDistance; + } + + CBlockIndex* GetBlockIndex() + { + // Find the first block the caller has in the main chain + foreach(const uint256& hash, vHave) + { + map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash); + if (mi != mapBlockIndex.end()) + { + CBlockIndex* pindex = (*mi).second; + if (pindex->IsInMainChain()) + return pindex; + } + } + return pindexGenesisBlock; + } + + uint256 GetBlockHash() + { + // Find the first block the caller has in the main chain + foreach(const uint256& hash, vHave) + { + map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash); + if (mi != mapBlockIndex.end()) + { + CBlockIndex* pindex = (*mi).second; + if (pindex->IsInMainChain()) + return hash; + } + } + return hashGenesisBlock; + } + + int GetHeight() + { + CBlockIndex* pindex = GetBlockIndex(); + if (!pindex) + return 0; + return pindex->nHeight; + } +}; + + + + + + +// +// Private key that includes an expiration date in case it never gets used. +// +class CWalletKey +{ +public: + CPrivKey vchPrivKey; + int64 nTimeCreated; + int64 nTimeExpires; + string strComment; + //// todo: add something to note what created it (user, getnewaddress, change) + //// maybe should have a map<string, string> property map + + CWalletKey(int64 nTimeExpiresIn=0) + { + nTimeCreated = (nTimeExpiresIn ? GetTime() : 0); + nTimeExpires = nTimeExpiresIn; + } + + IMPLEMENT_SERIALIZE + ( + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + READWRITE(vchPrivKey); + READWRITE(nTimeCreated); + READWRITE(nTimeExpires); + READWRITE(strComment); + ) +}; + + + + + + +extern map<uint256, CTransaction> mapTransactions; +extern map<uint256, CWalletTx> mapWallet; +extern vector<uint256> vWalletUpdated; +extern CCriticalSection cs_mapWallet; +extern map<vector<unsigned char>, CPrivKey> mapKeys; +extern map<uint160, vector<unsigned char> > mapPubKeys; +extern CCriticalSection cs_mapKeys; +extern CKey keyUser; diff --git a/makefile.mingw b/makefile.mingw index ee63d11ead..35a63a847a 100644 --- a/makefile.mingw +++ b/makefile.mingw @@ -1,76 +1,76 @@ -# Copyright (c) 2009-2010 Satoshi Nakamoto
-# Distributed under the MIT/X11 software license, see the accompanying
-# file license.txt or http://www.opensource.org/licenses/mit-license.php.
-
-
-# for wxWidgets-2.8.x, search and replace "mswud"->"mswd" and "29u"->"28"
-
-INCLUDEPATHS= \
- -I"/boost" \
- -I"/db/build_unix" \
- -I"/openssl/include" \
- -I"/wxwidgets/lib/gcc_lib/mswud" \
- -I"/wxwidgets/include"
-
-LIBPATHS= \
- -L"/boost/stage/lib" \
- -L"/db/build_unix" \
- -L"/openssl/out" \
- -L"/wxwidgets/lib/gcc_lib"
-
-WXLIBS= \
- -l wxmsw29ud_html -l wxmsw29ud_core -l wxmsw29ud_adv -l wxbase29ud -l wxtiffd -l wxjpegd -l wxpngd -l wxzlibd
-
-LIBS= \
- -l libboost_system-mgw34-mt-d -l libboost_filesystem-mgw34-mt-d \
- -l db_cxx \
- -l eay32 \
- -l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32 -l shlwapi
-
-WXDEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH
-DEBUGFLAGS=-g -D__WXDEBUG__
-CFLAGS=-mthreads -O2 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS)
-HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \
- script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h init.h sha.h
-
-
-all: bitcoin.exe
-
-
-headers.h.gch: headers.h $(HEADERS)
- g++ -c $(CFLAGS) -o $@ $<
-
-obj/%.o: %.cpp $(HEADERS) headers.h.gch
- g++ -c $(CFLAGS) -o $@ $<
-
-obj/sha.o: sha.cpp sha.h
- g++ -c $(CFLAGS) -O3 -o $@ $<
-
-obj/ui_res.o: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp
- windres $(WXDEFS) $(INCLUDEPATHS) -o $@ -i $<
-
-OBJS= \
- obj/util.o \
- obj/script.o \
- obj/db.o \
- obj/net.o \
- obj/irc.o \
- obj/main.o \
- obj/rpc.o \
- obj/init.o
-
-bitcoin.exe: $(OBJS) obj/ui.o obj/uibase.o obj/sha.o obj/ui_res.o
- g++ $(CFLAGS) -mwindows -Wl,--subsystem,windows -o $@ $(LIBPATHS) $^ $(WXLIBS) $(LIBS)
-
-
-obj/nogui/%.o: %.cpp $(HEADERS)
- g++ -c $(CFLAGS) -DwxUSE_GUI=0 -o $@ $<
-
-bitcoind.exe: $(OBJS:obj/%=obj/nogui/%) obj/sha.o obj/ui_res.o
- g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ -l wxbase29ud $(LIBS)
-
-
-clean:
- -del /Q obj\*
- -del /Q obj\nogui\*
- -del /Q headers.h.gch
+# Copyright (c) 2009-2010 Satoshi Nakamoto +# Distributed under the MIT/X11 software license, see the accompanying +# file license.txt or http://www.opensource.org/licenses/mit-license.php. + + +# for wxWidgets-2.8.x, search and replace "mswud"->"mswd" and "29u"->"28" + +INCLUDEPATHS= \ + -I"/boost" \ + -I"/db/build_unix" \ + -I"/openssl/include" \ + -I"/wxwidgets/lib/gcc_lib/mswud" \ + -I"/wxwidgets/include" + +LIBPATHS= \ + -L"/boost/stage/lib" \ + -L"/db/build_unix" \ + -L"/openssl/out" \ + -L"/wxwidgets/lib/gcc_lib" + +WXLIBS= \ + -l wxmsw29ud_html -l wxmsw29ud_core -l wxmsw29ud_adv -l wxbase29ud -l wxtiffd -l wxjpegd -l wxpngd -l wxzlibd + +LIBS= \ + -l libboost_system-mgw34-mt-d -l libboost_filesystem-mgw34-mt-d \ + -l db_cxx \ + -l eay32 \ + -l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32 -l shlwapi + +WXDEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH +DEBUGFLAGS=-g -D__WXDEBUG__ +CFLAGS=-mthreads -O2 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) +HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \ + script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h init.h sha.h + + +all: bitcoin.exe + + +headers.h.gch: headers.h $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/%.o: %.cpp $(HEADERS) headers.h.gch + g++ -c $(CFLAGS) -o $@ $< + +obj/sha.o: sha.cpp sha.h + g++ -c $(CFLAGS) -O3 -o $@ $< + +obj/ui_res.o: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp + windres $(WXDEFS) $(INCLUDEPATHS) -o $@ -i $< + +OBJS= \ + obj/util.o \ + obj/script.o \ + obj/db.o \ + obj/net.o \ + obj/irc.o \ + obj/main.o \ + obj/rpc.o \ + obj/init.o + +bitcoin.exe: $(OBJS) obj/ui.o obj/uibase.o obj/sha.o obj/ui_res.o + g++ $(CFLAGS) -mwindows -Wl,--subsystem,windows -o $@ $(LIBPATHS) $^ $(WXLIBS) $(LIBS) + + +obj/nogui/%.o: %.cpp $(HEADERS) + g++ -c $(CFLAGS) -DwxUSE_GUI=0 -o $@ $< + +bitcoind.exe: $(OBJS:obj/%=obj/nogui/%) obj/sha.o obj/ui_res.o + g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ -l wxbase29ud $(LIBS) + + +clean: + -del /Q obj\* + -del /Q obj\nogui\* + -del /Q headers.h.gch diff --git a/makefile.osx b/makefile.osx index 264f0b1629..f624d922ac 100644 --- a/makefile.osx +++ b/makefile.osx @@ -1,65 +1,65 @@ -# Copyright (c) 2009-2010 Satoshi Nakamoto
-# Distributed under the MIT/X11 software license, see the accompanying
-# file license.txt or http://www.opensource.org/licenses/mit-license.php.
-
-# Mac OS X makefile for bitcoin
-# Laszlo Hanyecz (solar@heliacal.net)
-
-DEPSDIR=/Users/macosuser/bitcoin/deps
-
-INCLUDEPATHS= \
- -I"$(DEPSDIR)/include"
-
-LIBPATHS= \
- -L"$(DEPSDIR)/lib"
-
-WXLIBS=$(shell $(DEPSDIR)/bin/wx-config --libs --static)
-
-LIBS= -dead_strip \
- $(DEPSDIR)/lib/libdb_cxx-4.8.a \
- $(DEPSDIR)/lib/libboost_system.a \
- $(DEPSDIR)/lib/libboost_filesystem.a \
- $(DEPSDIR)/lib/libcrypto.a
-
-WXDEFS=$(shell $(DEPSDIR)/bin/wx-config --cxxflags) -DNOPCH -DMSG_NOSIGNAL=0
-
-DEBUGFLAGS=-g -DwxDEBUG_LEVEL=0
-# ppc doesn't work because we don't support big-endian
-CFLAGS=-mmacosx-version-min=10.5 -arch i386 -arch x86_64 -O2 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS)
-HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \
- script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h init.h sha.h
-
-
-all: bitcoin
-
-
-obj/%.o: %.cpp $(HEADERS)
- g++ -c $(CFLAGS) -o $@ $<
-
-obj/sha.o: sha.cpp sha.h
- g++ -c $(CFLAGS) -O3 -o $@ $<
-
-OBJS= \
- obj/util.o \
- obj/script.o \
- obj/db.o \
- obj/net.o \
- obj/irc.o \
- obj/main.o \
- obj/rpc.o \
- obj/init.o
-
-bitcoin: $(OBJS) obj/ui.o obj/uibase.o obj/sha.o
- g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(WXLIBS) $(LIBS)
-
-
-obj/nogui/%.o: %.cpp $(HEADERS)
- g++ -c $(CFLAGS) -DwxUSE_GUI=0 -o $@ $<
-
-bitcoind: $(OBJS:obj/%=obj/nogui/%) obj/sha.o
- g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(WXLIBS) $(LIBS)
-
-
-clean:
- -rm -f obj/*.o
- -rm -f obj/nogui/*.o
+# Copyright (c) 2009-2010 Satoshi Nakamoto +# Distributed under the MIT/X11 software license, see the accompanying +# file license.txt or http://www.opensource.org/licenses/mit-license.php. + +# Mac OS X makefile for bitcoin +# Laszlo Hanyecz (solar@heliacal.net) + +DEPSDIR=/Users/macosuser/bitcoin/deps + +INCLUDEPATHS= \ + -I"$(DEPSDIR)/include" + +LIBPATHS= \ + -L"$(DEPSDIR)/lib" + +WXLIBS=$(shell $(DEPSDIR)/bin/wx-config --libs --static) + +LIBS= -dead_strip \ + $(DEPSDIR)/lib/libdb_cxx-4.8.a \ + $(DEPSDIR)/lib/libboost_system.a \ + $(DEPSDIR)/lib/libboost_filesystem.a \ + $(DEPSDIR)/lib/libcrypto.a + +WXDEFS=$(shell $(DEPSDIR)/bin/wx-config --cxxflags) -DNOPCH -DMSG_NOSIGNAL=0 + +DEBUGFLAGS=-g -DwxDEBUG_LEVEL=0 +# ppc doesn't work because we don't support big-endian +CFLAGS=-mmacosx-version-min=10.5 -arch i386 -arch x86_64 -O2 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) +HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \ + script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h init.h sha.h + + +all: bitcoin + + +obj/%.o: %.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/sha.o: sha.cpp sha.h + g++ -c $(CFLAGS) -O3 -o $@ $< + +OBJS= \ + obj/util.o \ + obj/script.o \ + obj/db.o \ + obj/net.o \ + obj/irc.o \ + obj/main.o \ + obj/rpc.o \ + obj/init.o + +bitcoin: $(OBJS) obj/ui.o obj/uibase.o obj/sha.o + g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(WXLIBS) $(LIBS) + + +obj/nogui/%.o: %.cpp $(HEADERS) + g++ -c $(CFLAGS) -DwxUSE_GUI=0 -o $@ $< + +bitcoind: $(OBJS:obj/%=obj/nogui/%) obj/sha.o + g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(WXLIBS) $(LIBS) + + +clean: + -rm -f obj/*.o + -rm -f obj/nogui/*.o diff --git a/makefile.unix b/makefile.unix index f6ca110b7f..3f99f0a143 100644 --- a/makefile.unix +++ b/makefile.unix @@ -1,73 +1,73 @@ -# Copyright (c) 2009-2010 Satoshi Nakamoto
-# Distributed under the MIT/X11 software license, see the accompanying
-# file license.txt or http://www.opensource.org/licenses/mit-license.php.
-
-
-
-INCLUDEPATHS= \
- -I"/usr/include" \
- -I"/usr/local/include/wx-2.9" \
- -I"/usr/local/lib/wx/include/gtk2-unicode-debug-static-2.9"
-
-LIBPATHS= \
- -L"/usr/lib" \
- -L"/usr/local/lib"
-
-WXLIBS= \
- -Wl,-Bstatic \
- -l wx_gtk2ud-2.9 \
- -Wl,-Bdynamic \
- -l gtk-x11-2.0 -l SM
-
-LIBS= \
- -Wl,-Bstatic \
- -l boost_system -l boost_filesystem \
- -l db_cxx \
- -Wl,-Bdynamic \
- -l crypto \
- -l gthread-2.0
-
-WXDEFS=-D__WXGTK__ -DNOPCH
-DEBUGFLAGS=-g -D__WXDEBUG__
-CFLAGS=-O2 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS)
-HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \
- script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h init.h sha.h
-
-
-all: bitcoin
-
-
-headers.h.gch: headers.h $(HEADERS)
- g++ -c $(CFLAGS) -o $@ $<
-
-obj/%.o: %.cpp $(HEADERS) headers.h.gch
- g++ -c $(CFLAGS) -o $@ $<
-
-obj/sha.o: sha.cpp sha.h
- g++ -c $(CFLAGS) -O3 -o $@ $<
-
-OBJS= \
- obj/util.o \
- obj/script.o \
- obj/db.o \
- obj/net.o \
- obj/irc.o \
- obj/main.o \
- obj/rpc.o \
- obj/init.o
-
-bitcoin: $(OBJS) obj/ui.o obj/uibase.o obj/sha.o
- g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(WXLIBS) $(LIBS)
-
-
-obj/nogui/%.o: %.cpp $(HEADERS)
- g++ -c $(CFLAGS) -DwxUSE_GUI=0 -o $@ $<
-
-bitcoind: $(OBJS:obj/%=obj/nogui/%) obj/sha.o
- g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ -l wx_baseud-2.9 $(LIBS)
-
-
-clean:
- -rm -f obj/*.o
- -rm -f obj/nogui/*.o
- -rm -f headers.h.gch
+# Copyright (c) 2009-2010 Satoshi Nakamoto +# Distributed under the MIT/X11 software license, see the accompanying +# file license.txt or http://www.opensource.org/licenses/mit-license.php. + + + +INCLUDEPATHS= \ + -I"/usr/include" \ + -I"/usr/local/include/wx-2.9" \ + -I"/usr/local/lib/wx/include/gtk2-unicode-debug-static-2.9" + +LIBPATHS= \ + -L"/usr/lib" \ + -L"/usr/local/lib" + +WXLIBS= \ + -Wl,-Bstatic \ + -l wx_gtk2ud-2.9 \ + -Wl,-Bdynamic \ + -l gtk-x11-2.0 -l SM + +LIBS= \ + -Wl,-Bstatic \ + -l boost_system -l boost_filesystem \ + -l db_cxx \ + -Wl,-Bdynamic \ + -l crypto \ + -l gthread-2.0 + +WXDEFS=-D__WXGTK__ -DNOPCH +DEBUGFLAGS=-g -D__WXDEBUG__ +CFLAGS=-O2 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) +HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \ + script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h init.h sha.h + + +all: bitcoin + + +headers.h.gch: headers.h $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/%.o: %.cpp $(HEADERS) headers.h.gch + g++ -c $(CFLAGS) -o $@ $< + +obj/sha.o: sha.cpp sha.h + g++ -c $(CFLAGS) -O3 -o $@ $< + +OBJS= \ + obj/util.o \ + obj/script.o \ + obj/db.o \ + obj/net.o \ + obj/irc.o \ + obj/main.o \ + obj/rpc.o \ + obj/init.o + +bitcoin: $(OBJS) obj/ui.o obj/uibase.o obj/sha.o + g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(WXLIBS) $(LIBS) + + +obj/nogui/%.o: %.cpp $(HEADERS) + g++ -c $(CFLAGS) -DwxUSE_GUI=0 -o $@ $< + +bitcoind: $(OBJS:obj/%=obj/nogui/%) obj/sha.o + g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ -l wx_baseud-2.9 $(LIBS) + + +clean: + -rm -f obj/*.o + -rm -f obj/nogui/*.o + -rm -f headers.h.gch diff --git a/makefile.vc b/makefile.vc index 9f821771e7..14e6e39051 100644 --- a/makefile.vc +++ b/makefile.vc @@ -1,107 +1,107 @@ -# Copyright (c) 2009-2010 Satoshi Nakamoto
-# Distributed under the MIT/X11 software license, see the accompanying
-# file license.txt or http://www.opensource.org/licenses/mit-license.php.
-
-
-# for wxWidgets-2.8.x, search and replace "mswud"->"mswd" and "29u"->"28"
-
-INCLUDEPATHS= \
- /I"/boost" \
- /I"/db/build_windows" \
- /I"/openssl/include" \
- /I"/wxwidgets/lib/vc_lib/mswud" \
- /I"/wxwidgets/include"
-
-LIBPATHS= \
- /LIBPATH:"/boost/stage/lib" \
- /LIBPATH:"/db/build_windows/debug" \
- /LIBPATH:"/openssl/out" \
- /LIBPATH:"/wxwidgets/lib/vc_lib"
-
-LIBS= \
- libboost_system-vc80-mt-gd.lib libboost_filesystem-vc80-mt-gd.lib \
- libdb47sd.lib \
- libeay32.lib \
- wxmsw29ud_html.lib wxmsw29ud_core.lib wxmsw29ud_adv.lib wxbase29ud.lib wxtiffd.lib wxjpegd.lib wxpngd.lib wxzlibd.lib \
- kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib ws2_32.lib shlwapi.lib
-
-WXDEFS=/DWIN32 /D__WXMSW__ /D_WINDOWS /DNOPCH
-DEBUGFLAGS=/Zi /Od /D__WXDEBUG__
-CFLAGS=/c /nologo /Ob0 /MDd /EHsc /GR /Zm300 $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS)
-HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \
- script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h init.h sha.h
-
-
-all: bitcoin.exe
-
-
-.cpp{obj}.obj:
- cl $(CFLAGS) /Fo$@ %s
-
-obj\util.obj: $(HEADERS)
-
-obj\script.obj: $(HEADERS)
-
-obj\db.obj: $(HEADERS)
-
-obj\net.obj: $(HEADERS)
-
-obj\irc.obj: $(HEADERS)
-
-obj\main.obj: $(HEADERS)
-
-obj\rpc.obj: $(HEADERS)
-
-obj\init.obj: $(HEADERS)
-
-obj\ui.obj: $(HEADERS)
-
-obj\uibase.obj: $(HEADERS)
-
-obj\sha.obj: sha.cpp sha.h
- cl $(CFLAGS) /O2 /Fo$@ %s
-
-obj\ui.res: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp
- rc $(INCLUDEPATHS) $(WXDEFS) /Fo$@ %s
-
-OBJS= \
- obj\util.obj \
- obj\script.obj \
- obj\db.obj \
- obj\net.obj \
- obj\irc.obj \
- obj\main.obj \
- obj\rpc.obj \
- obj\init.obj
-
-bitcoin.exe: $(OBJS) obj\ui.obj obj\uibase.obj obj\sha.obj obj\ui.res
- link /nologo /DEBUG /SUBSYSTEM:WINDOWS /OUT:$@ $(LIBPATHS) $** $(LIBS)
-
-
-.cpp{obj\nogui}.obj:
- cl $(CFLAGS) /DwxUSE_GUI=0 /Fo$@ %s
-
-obj\nogui\util.obj: $(HEADERS)
-
-obj\nogui\script.obj: $(HEADERS)
-
-obj\nogui\db.obj: $(HEADERS)
-
-obj\nogui\net.obj: $(HEADERS)
-
-obj\nogui\irc.obj: $(HEADERS)
-
-obj\nogui\main.obj: $(HEADERS)
-
-obj\nogui\rpc.obj: $(HEADERS)
-
-obj\nogui\init.obj: $(HEADERS)
-
-bitcoind.exe: $(OBJS:obj\=obj\nogui\) obj\sha.obj obj\ui.res
- link /nologo /DEBUG /OUT:$@ $(LIBPATHS) $** $(LIBS)
-
-
-clean:
- -del /Q obj\*
- -del *.ilk
- -del *.pdb
+# Copyright (c) 2009-2010 Satoshi Nakamoto +# Distributed under the MIT/X11 software license, see the accompanying +# file license.txt or http://www.opensource.org/licenses/mit-license.php. + + +# for wxWidgets-2.8.x, search and replace "mswud"->"mswd" and "29u"->"28" + +INCLUDEPATHS= \ + /I"/boost" \ + /I"/db/build_windows" \ + /I"/openssl/include" \ + /I"/wxwidgets/lib/vc_lib/mswud" \ + /I"/wxwidgets/include" + +LIBPATHS= \ + /LIBPATH:"/boost/stage/lib" \ + /LIBPATH:"/db/build_windows/debug" \ + /LIBPATH:"/openssl/out" \ + /LIBPATH:"/wxwidgets/lib/vc_lib" + +LIBS= \ + libboost_system-vc80-mt-gd.lib libboost_filesystem-vc80-mt-gd.lib \ + libdb47sd.lib \ + libeay32.lib \ + wxmsw29ud_html.lib wxmsw29ud_core.lib wxmsw29ud_adv.lib wxbase29ud.lib wxtiffd.lib wxjpegd.lib wxpngd.lib wxzlibd.lib \ + kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib ws2_32.lib shlwapi.lib + +WXDEFS=/DWIN32 /D__WXMSW__ /D_WINDOWS /DNOPCH +DEBUGFLAGS=/Zi /Od /D__WXDEBUG__ +CFLAGS=/c /nologo /Ob0 /MDd /EHsc /GR /Zm300 $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) +HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \ + script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h init.h sha.h + + +all: bitcoin.exe + + +.cpp{obj}.obj: + cl $(CFLAGS) /Fo$@ %s + +obj\util.obj: $(HEADERS) + +obj\script.obj: $(HEADERS) + +obj\db.obj: $(HEADERS) + +obj\net.obj: $(HEADERS) + +obj\irc.obj: $(HEADERS) + +obj\main.obj: $(HEADERS) + +obj\rpc.obj: $(HEADERS) + +obj\init.obj: $(HEADERS) + +obj\ui.obj: $(HEADERS) + +obj\uibase.obj: $(HEADERS) + +obj\sha.obj: sha.cpp sha.h + cl $(CFLAGS) /O2 /Fo$@ %s + +obj\ui.res: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp + rc $(INCLUDEPATHS) $(WXDEFS) /Fo$@ %s + +OBJS= \ + obj\util.obj \ + obj\script.obj \ + obj\db.obj \ + obj\net.obj \ + obj\irc.obj \ + obj\main.obj \ + obj\rpc.obj \ + obj\init.obj + +bitcoin.exe: $(OBJS) obj\ui.obj obj\uibase.obj obj\sha.obj obj\ui.res + link /nologo /DEBUG /SUBSYSTEM:WINDOWS /OUT:$@ $(LIBPATHS) $** $(LIBS) + + +.cpp{obj\nogui}.obj: + cl $(CFLAGS) /DwxUSE_GUI=0 /Fo$@ %s + +obj\nogui\util.obj: $(HEADERS) + +obj\nogui\script.obj: $(HEADERS) + +obj\nogui\db.obj: $(HEADERS) + +obj\nogui\net.obj: $(HEADERS) + +obj\nogui\irc.obj: $(HEADERS) + +obj\nogui\main.obj: $(HEADERS) + +obj\nogui\rpc.obj: $(HEADERS) + +obj\nogui\init.obj: $(HEADERS) + +bitcoind.exe: $(OBJS:obj\=obj\nogui\) obj\sha.obj obj\ui.res + link /nologo /DEBUG /OUT:$@ $(LIBPATHS) $** $(LIBS) + + +clean: + -del /Q obj\* + -del *.ilk + -del *.pdb @@ -1,1424 +1,1424 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
-
-#include "headers.h"
-
-void ThreadMessageHandler2(void* parg);
-void ThreadSocketHandler2(void* parg);
-void ThreadOpenConnections2(void* parg);
-bool OpenNetworkConnection(const CAddress& addrConnect);
-
-
-
-
-
-//
-// Global state variables
-//
-bool fClient = false;
-uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
-CAddress addrLocalHost(0, DEFAULT_PORT, nLocalServices);
-CNode* pnodeLocalHost = NULL;
-uint64 nLocalHostNonce = 0;
-array<int, 10> vnThreadsRunning;
-SOCKET hListenSocket = INVALID_SOCKET;
-int64 nThreadSocketHandlerHeartbeat = INT64_MAX;
-
-vector<CNode*> vNodes;
-CCriticalSection cs_vNodes;
-map<vector<unsigned char>, CAddress> mapAddresses;
-CCriticalSection cs_mapAddresses;
-map<CInv, CDataStream> mapRelay;
-deque<pair<int64, CInv> > vRelayExpiration;
-CCriticalSection cs_mapRelay;
-map<CInv, int64> mapAlreadyAskedFor;
-
-// Settings
-int fUseProxy = false;
-CAddress addrProxy("127.0.0.1:9050");
-
-
-
-
-
-void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
-{
- // Filter out duplicate requests
- if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
- return;
- pindexLastGetBlocksBegin = pindexBegin;
- hashLastGetBlocksEnd = hashEnd;
-
- PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
-}
-
-
-
-
-
-bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet)
-{
- hSocketRet = INVALID_SOCKET;
-
- SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (hSocket == INVALID_SOCKET)
- return false;
-#if defined(__BSD__) || defined(__WXOSX__)
- int set = 1;
- setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
-#endif
-
- bool fRoutable = !(addrConnect.GetByte(3) == 10 || (addrConnect.GetByte(3) == 192 && addrConnect.GetByte(2) == 168));
- bool fProxy = (fUseProxy && fRoutable);
- struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr());
-
- if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
- {
- closesocket(hSocket);
- return false;
- }
-
- if (fProxy)
- {
- printf("proxy connecting %s\n", addrConnect.ToStringLog().c_str());
- char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
- memcpy(pszSocks4IP + 2, &addrConnect.port, 2);
- memcpy(pszSocks4IP + 4, &addrConnect.ip, 4);
- char* pszSocks4 = pszSocks4IP;
- int nSize = sizeof(pszSocks4IP);
-
- int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL);
- if (ret != nSize)
- {
- closesocket(hSocket);
- return error("Error sending to proxy");
- }
- char pchRet[8];
- if (recv(hSocket, pchRet, 8, 0) != 8)
- {
- closesocket(hSocket);
- return error("Error reading proxy response");
- }
- if (pchRet[1] != 0x5a)
- {
- closesocket(hSocket);
- if (pchRet[1] != 0x5b)
- printf("ERROR: Proxy returned error %d\n", pchRet[1]);
- return false;
- }
- printf("proxy connected %s\n", addrConnect.ToStringLog().c_str());
- }
-
- hSocketRet = hSocket;
- return true;
-}
-
-
-
-bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const char* pszKeyword, unsigned int& ipRet)
-{
- SOCKET hSocket;
- if (!ConnectSocket(addrConnect, hSocket))
- return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
-
- send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
-
- string strLine;
- while (RecvLine(hSocket, strLine))
- {
- if (strLine.empty())
- {
- loop
- {
- if (!RecvLine(hSocket, strLine))
- {
- closesocket(hSocket);
- return false;
- }
- if (strLine.find(pszKeyword) != -1)
- {
- strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
- break;
- }
- }
- closesocket(hSocket);
- if (strLine.find("<"))
- strLine = strLine.substr(0, strLine.find("<"));
- strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
- while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
- strLine.resize(strLine.size()-1);
- CAddress addr(strLine.c_str());
- printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
- if (addr.ip == 0 || addr.ip == INADDR_NONE || !addr.IsRoutable())
- return false;
- ipRet = addr.ip;
- return true;
- }
- }
- closesocket(hSocket);
- return error("GetMyExternalIP() : connection closed");
-}
-
-
-bool GetMyExternalIP(unsigned int& ipRet)
-{
- CAddress addrConnect;
- const char* pszGet;
- const char* pszKeyword;
-
- if (fUseProxy)
- return false;
-
- for (int nLookup = 0; nLookup <= 1; nLookup++)
- for (int nHost = 1; nHost <= 2; nHost++)
- {
- if (nHost == 1)
- {
- addrConnect = CAddress("70.86.96.218:80"); // www.ipaddressworld.com
-
- if (nLookup == 1)
- {
- struct hostent* phostent = gethostbyname("www.ipaddressworld.com");
- if (phostent && phostent->h_addr_list && phostent->h_addr_list[0])
- addrConnect = CAddress(*(u_long*)phostent->h_addr_list[0], htons(80));
- }
-
- pszGet = "GET /ip.php HTTP/1.1\r\n"
- "Host: www.ipaddressworld.com\r\n"
- "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
- "Connection: close\r\n"
- "\r\n";
-
- pszKeyword = "IP:";
- }
- else if (nHost == 2)
- {
- addrConnect = CAddress("208.78.68.70:80"); // checkip.dyndns.org
-
- if (nLookup == 1)
- {
- struct hostent* phostent = gethostbyname("checkip.dyndns.org");
- if (phostent && phostent->h_addr_list && phostent->h_addr_list[0])
- addrConnect = CAddress(*(u_long*)phostent->h_addr_list[0], htons(80));
- }
-
- pszGet = "GET / HTTP/1.1\r\n"
- "Host: checkip.dyndns.org\r\n"
- "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
- "Connection: close\r\n"
- "\r\n";
-
- pszKeyword = "Address:";
- }
-
- if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
- return true;
- }
-
- return false;
-}
-
-
-
-
-
-bool AddAddress(CAddress addr)
-{
- if (!addr.IsRoutable())
- return false;
- if (addr.ip == addrLocalHost.ip)
- return false;
- CRITICAL_BLOCK(cs_mapAddresses)
- {
- map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
- if (it == mapAddresses.end())
- {
- // New address
- printf("AddAddress(%s)\n", addr.ToStringLog().c_str());
- mapAddresses.insert(make_pair(addr.GetKey(), addr));
- CAddrDB().WriteAddress(addr);
- return true;
- }
- else
- {
- bool fUpdated = false;
- CAddress& addrFound = (*it).second;
- if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
- {
- // Services have been added
- addrFound.nServices |= addr.nServices;
- fUpdated = true;
- }
- bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
- int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
- if (addrFound.nTime < addr.nTime - nUpdateInterval)
- {
- // Periodically update most recently seen time
- addrFound.nTime = addr.nTime;
- fUpdated = true;
- }
- if (fUpdated)
- CAddrDB().WriteAddress(addrFound);
- }
- }
- return false;
-}
-
-void AddressCurrentlyConnected(const CAddress& addr)
-{
- CRITICAL_BLOCK(cs_mapAddresses)
- {
- // Only if it's been published already
- map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
- if (it != mapAddresses.end())
- {
- CAddress& addrFound = (*it).second;
- int64 nUpdateInterval = 20 * 60;
- if (addrFound.nTime < GetAdjustedTime() - nUpdateInterval)
- {
- // Periodically update most recently seen time
- addrFound.nTime = GetAdjustedTime();
- CAddrDB addrdb;
- addrdb.WriteAddress(addrFound);
- }
- }
- }
-}
-
-
-
-
-
-void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
-{
- // If the dialog might get closed before the reply comes back,
- // call this in the destructor so it doesn't get called after it's deleted.
- CRITICAL_BLOCK(cs_vNodes)
- {
- foreach(CNode* pnode, vNodes)
- {
- CRITICAL_BLOCK(pnode->cs_mapRequests)
- {
- for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
- {
- CRequestTracker& tracker = (*mi).second;
- if (tracker.fn == fn && tracker.param1 == param1)
- pnode->mapRequests.erase(mi++);
- else
- mi++;
- }
- }
- }
- }
-}
-
-
-
-
-
-
-
-//
-// Subscription methods for the broadcast and subscription system.
-// Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
-//
-// The subscription system uses a meet-in-the-middle strategy.
-// With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
-// subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
-//
-
-bool AnySubscribed(unsigned int nChannel)
-{
- if (pnodeLocalHost->IsSubscribed(nChannel))
- return true;
- CRITICAL_BLOCK(cs_vNodes)
- foreach(CNode* pnode, vNodes)
- if (pnode->IsSubscribed(nChannel))
- return true;
- return false;
-}
-
-bool CNode::IsSubscribed(unsigned int nChannel)
-{
- if (nChannel >= vfSubscribe.size())
- return false;
- return vfSubscribe[nChannel];
-}
-
-void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
-{
- if (nChannel >= vfSubscribe.size())
- return;
-
- if (!AnySubscribed(nChannel))
- {
- // Relay subscribe
- CRITICAL_BLOCK(cs_vNodes)
- foreach(CNode* pnode, vNodes)
- if (pnode != this)
- pnode->PushMessage("subscribe", nChannel, nHops);
- }
-
- vfSubscribe[nChannel] = true;
-}
-
-void CNode::CancelSubscribe(unsigned int nChannel)
-{
- if (nChannel >= vfSubscribe.size())
- return;
-
- // Prevent from relaying cancel if wasn't subscribed
- if (!vfSubscribe[nChannel])
- return;
- vfSubscribe[nChannel] = false;
-
- if (!AnySubscribed(nChannel))
- {
- // Relay subscription cancel
- CRITICAL_BLOCK(cs_vNodes)
- foreach(CNode* pnode, vNodes)
- if (pnode != this)
- pnode->PushMessage("sub-cancel", nChannel);
- }
-}
-
-
-
-
-
-
-
-
-
-CNode* FindNode(unsigned int ip)
-{
- CRITICAL_BLOCK(cs_vNodes)
- {
- foreach(CNode* pnode, vNodes)
- if (pnode->addr.ip == ip)
- return (pnode);
- }
- return NULL;
-}
-
-CNode* FindNode(CAddress addr)
-{
- CRITICAL_BLOCK(cs_vNodes)
- {
- foreach(CNode* pnode, vNodes)
- if (pnode->addr == addr)
- return (pnode);
- }
- return NULL;
-}
-
-CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
-{
- if (addrConnect.ip == addrLocalHost.ip)
- return NULL;
-
- // Look for an existing connection
- CNode* pnode = FindNode(addrConnect.ip);
- if (pnode)
- {
- if (nTimeout != 0)
- pnode->AddRef(nTimeout);
- else
- pnode->AddRef();
- return pnode;
- }
-
- /// debug print
- printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n",
- addrConnect.ToStringLog().c_str(),
- (double)(addrConnect.nTime - GetAdjustedTime())/3600.0,
- (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0);
-
- CRITICAL_BLOCK(cs_mapAddresses)
- mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime();
-
- // Connect
- SOCKET hSocket;
- if (ConnectSocket(addrConnect, hSocket))
- {
- /// debug print
- printf("connected %s\n", addrConnect.ToStringLog().c_str());
-
- // Set to nonblocking
-#ifdef __WXMSW__
- u_long nOne = 1;
- if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
- printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
-#else
- if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
- printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
-#endif
-
- // Add node
- CNode* pnode = new CNode(hSocket, addrConnect, false);
- if (nTimeout != 0)
- pnode->AddRef(nTimeout);
- else
- pnode->AddRef();
- CRITICAL_BLOCK(cs_vNodes)
- vNodes.push_back(pnode);
-
- pnode->nTimeConnected = GetTime();
- return pnode;
- }
- else
- {
- return NULL;
- }
-}
-
-void CNode::CloseSocketDisconnect()
-{
- fDisconnect = true;
- if (hSocket != INVALID_SOCKET)
- {
- if (fDebug)
- printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
- printf("disconnecting node %s\n", addr.ToStringLog().c_str());
- closesocket(hSocket);
- hSocket = INVALID_SOCKET;
- }
-}
-
-void CNode::Cleanup()
-{
- // All of a nodes broadcasts and subscriptions are automatically torn down
- // when it goes down, so a node has to stay up to keep its broadcast going.
-
- // Cancel subscriptions
- for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
- if (vfSubscribe[nChannel])
- CancelSubscribe(nChannel);
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-void ThreadSocketHandler(void* parg)
-{
- IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
- try
- {
- vnThreadsRunning[0]++;
- ThreadSocketHandler2(parg);
- vnThreadsRunning[0]--;
- }
- catch (std::exception& e) {
- vnThreadsRunning[0]--;
- PrintException(&e, "ThreadSocketHandler()");
- } catch (...) {
- vnThreadsRunning[0]--;
- throw; // support pthread_cancel()
- }
- printf("ThreadSocketHandler exiting\n");
-}
-
-void ThreadSocketHandler2(void* parg)
-{
- printf("ThreadSocketHandler started\n");
- list<CNode*> vNodesDisconnected;
- int nPrevNodeCount = 0;
-
- loop
- {
- //
- // Disconnect nodes
- //
- CRITICAL_BLOCK(cs_vNodes)
- {
- // Disconnect unused nodes
- vector<CNode*> vNodesCopy = vNodes;
- foreach(CNode* pnode, vNodesCopy)
- {
- if (pnode->fDisconnect ||
- (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
- {
- // remove from vNodes
- vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
-
- // close socket and cleanup
- pnode->CloseSocketDisconnect();
- pnode->Cleanup();
-
- // hold in disconnected pool until all refs are released
- pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
- if (pnode->fNetworkNode || pnode->fInbound)
- pnode->Release();
- vNodesDisconnected.push_back(pnode);
- }
- }
-
- // Delete disconnected nodes
- list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
- foreach(CNode* pnode, vNodesDisconnectedCopy)
- {
- // wait until threads are done using it
- if (pnode->GetRefCount() <= 0)
- {
- bool fDelete = false;
- TRY_CRITICAL_BLOCK(pnode->cs_vSend)
- TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
- TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
- TRY_CRITICAL_BLOCK(pnode->cs_inventory)
- fDelete = true;
- if (fDelete)
- {
- vNodesDisconnected.remove(pnode);
- delete pnode;
- }
- }
- }
- }
- if (vNodes.size() != nPrevNodeCount)
- {
- nPrevNodeCount = vNodes.size();
- MainFrameRepaint();
- }
-
-
- //
- // Find which sockets have data to receive
- //
- struct timeval timeout;
- timeout.tv_sec = 0;
- timeout.tv_usec = 50000; // frequency to poll pnode->vSend
-
- fd_set fdsetRecv;
- fd_set fdsetSend;
- fd_set fdsetError;
- FD_ZERO(&fdsetRecv);
- FD_ZERO(&fdsetSend);
- FD_ZERO(&fdsetError);
- SOCKET hSocketMax = 0;
- FD_SET(hListenSocket, &fdsetRecv);
- hSocketMax = max(hSocketMax, hListenSocket);
- CRITICAL_BLOCK(cs_vNodes)
- {
- foreach(CNode* pnode, vNodes)
- {
- if (pnode->hSocket == INVALID_SOCKET || pnode->hSocket < 0)
- continue;
- FD_SET(pnode->hSocket, &fdsetRecv);
- FD_SET(pnode->hSocket, &fdsetError);
- hSocketMax = max(hSocketMax, pnode->hSocket);
- TRY_CRITICAL_BLOCK(pnode->cs_vSend)
- if (!pnode->vSend.empty())
- FD_SET(pnode->hSocket, &fdsetSend);
- }
- }
-
- vnThreadsRunning[0]--;
- int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
- vnThreadsRunning[0]++;
- if (fShutdown)
- return;
- if (nSelect == SOCKET_ERROR)
- {
- int nErr = WSAGetLastError();
- printf("socket select error %d\n", nErr);
- for (int i = 0; i <= hSocketMax; i++)
- FD_SET(i, &fdsetRecv);
- FD_ZERO(&fdsetSend);
- FD_ZERO(&fdsetError);
- Sleep(timeout.tv_usec/1000);
- }
-
-
- //
- // Accept new connections
- //
- if (FD_ISSET(hListenSocket, &fdsetRecv))
- {
- struct sockaddr_in sockaddr;
- socklen_t len = sizeof(sockaddr);
- SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
- CAddress addr(sockaddr);
- if (hSocket == INVALID_SOCKET)
- {
- if (WSAGetLastError() != WSAEWOULDBLOCK)
- printf("socket error accept failed: %d\n", WSAGetLastError());
- }
- else
- {
- printf("accepted connection %s\n", addr.ToStringLog().c_str());
- CNode* pnode = new CNode(hSocket, addr, true);
- pnode->AddRef();
- CRITICAL_BLOCK(cs_vNodes)
- vNodes.push_back(pnode);
- }
- }
-
-
- //
- // Service each socket
- //
- vector<CNode*> vNodesCopy;
- CRITICAL_BLOCK(cs_vNodes)
- {
- vNodesCopy = vNodes;
- foreach(CNode* pnode, vNodesCopy)
- pnode->AddRef();
- }
- foreach(CNode* pnode, vNodesCopy)
- {
- if (fShutdown)
- return;
-
- //
- // Receive
- //
- if (pnode->hSocket == INVALID_SOCKET)
- continue;
- if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
- {
- TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
- {
- CDataStream& vRecv = pnode->vRecv;
- unsigned int nPos = vRecv.size();
-
- // typical socket buffer is 8K-64K
- char pchBuf[0x10000];
- int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
- if (nBytes > 0)
- {
- vRecv.resize(nPos + nBytes);
- memcpy(&vRecv[nPos], pchBuf, nBytes);
- pnode->nLastRecv = GetTime();
- }
- else if (nBytes == 0)
- {
- // socket closed gracefully
- if (!pnode->fDisconnect)
- printf("socket closed\n");
- pnode->CloseSocketDisconnect();
- }
- else if (nBytes < 0)
- {
- // error
- int nErr = WSAGetLastError();
- if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
- {
- if (!pnode->fDisconnect)
- printf("socket recv error %d\n", nErr);
- pnode->CloseSocketDisconnect();
- }
- }
- }
- }
-
- //
- // Send
- //
- if (pnode->hSocket == INVALID_SOCKET)
- continue;
- if (FD_ISSET(pnode->hSocket, &fdsetSend))
- {
- TRY_CRITICAL_BLOCK(pnode->cs_vSend)
- {
- CDataStream& vSend = pnode->vSend;
- if (!vSend.empty())
- {
- int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
- if (nBytes > 0)
- {
- vSend.erase(vSend.begin(), vSend.begin() + nBytes);
- pnode->nLastSend = GetTime();
- }
- else if (nBytes < 0)
- {
- // error
- int nErr = WSAGetLastError();
- if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
- {
- printf("socket send error %d\n", nErr);
- pnode->CloseSocketDisconnect();
- }
- }
- }
- }
- }
-
- //
- // Inactivity checking
- //
- if (pnode->vSend.empty())
- pnode->nLastSendEmpty = GetTime();
- if (GetTime() - pnode->nTimeConnected > 60)
- {
- if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
- {
- printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
- pnode->fDisconnect = true;
- }
- else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
- {
- printf("socket not sending\n");
- pnode->fDisconnect = true;
- }
- else if (GetTime() - pnode->nLastRecv > 90*60)
- {
- printf("socket inactivity timeout\n");
- pnode->fDisconnect = true;
- }
- }
- }
- CRITICAL_BLOCK(cs_vNodes)
- {
- foreach(CNode* pnode, vNodesCopy)
- pnode->Release();
- }
-
- nThreadSocketHandlerHeartbeat = GetTime();
- Sleep(10);
- }
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-unsigned int pnSeed[] =
-{
- 0x35218252, 0x9c9c9618, 0xda6bacad, 0xb9aca862, 0x97c235c6,
- 0x146f9562, 0xb67b9e4b, 0x87cf4bc0, 0xb83945d0, 0x984333ad,
- 0xbbeec555, 0x6f0eb440, 0xe0005318, 0x7797e460, 0xddc60fcc,
- 0xb3bbd24a, 0x1ac85746, 0x641846a6, 0x85ee1155, 0xbb2e7a4c,
- 0x9cb8514b, 0xfc342648, 0x62958fae, 0xd0a8c87a, 0xa800795b,
- 0xda8c814e, 0x256a0c80, 0x3f23ec63, 0xd565df43, 0x997d9044,
- 0xaa121448, 0xbed8688e, 0x59d09a5e, 0xb2931243, 0x3730ba18,
- 0xdd3462d0, 0x4e4d1448, 0x171df645, 0x84ee1155,
- 0x248ac445, 0x0e634444, 0x0ded1b63, 0x30c01e60,
- 0xa2b9a094, 0x29e4fd43, 0x9ce61b4c, 0xdae09744,
-};
-
-
-
-void ThreadOpenConnections(void* parg)
-{
- IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
- try
- {
- vnThreadsRunning[1]++;
- ThreadOpenConnections2(parg);
- vnThreadsRunning[1]--;
- }
- catch (std::exception& e) {
- vnThreadsRunning[1]--;
- PrintException(&e, "ThreadOpenConnections()");
- } catch (...) {
- vnThreadsRunning[1]--;
- PrintException(NULL, "ThreadOpenConnections()");
- }
- printf("ThreadOpenConnections exiting\n");
-}
-
-void ThreadOpenConnections2(void* parg)
-{
- printf("ThreadOpenConnections started\n");
-
- // Connect to specific addresses
- if (mapArgs.count("-connect"))
- {
- for (int64 nLoop = 0;; nLoop++)
- {
- foreach(string strAddr, mapMultiArgs["-connect"])
- {
- CAddress addr(strAddr, NODE_NETWORK);
- if (addr.IsValid())
- OpenNetworkConnection(addr);
- for (int i = 0; i < 10 && i < nLoop; i++)
- {
- Sleep(500);
- if (fShutdown)
- return;
- }
- }
- }
- }
-
- // Connect to manually added nodes first
- if (mapArgs.count("-addnode"))
- {
- foreach(string strAddr, mapMultiArgs["-addnode"])
- {
- CAddress addr(strAddr, NODE_NETWORK);
- if (addr.IsValid())
- {
- OpenNetworkConnection(addr);
- Sleep(500);
- if (fShutdown)
- return;
- }
- }
- }
-
- // Initiate network connections
- int64 nStart = GetTime();
- loop
- {
- // Wait
- vnThreadsRunning[1]--;
- Sleep(500);
- const int nMaxConnections = 8;
- while (vNodes.size() >= nMaxConnections)
- {
- Sleep(2000);
- if (fShutdown)
- return;
- }
- vnThreadsRunning[1]++;
- if (fShutdown)
- return;
-
- CRITICAL_BLOCK(cs_mapAddresses)
- {
- // Add seed nodes if IRC isn't working
- static bool fSeedUsed;
- bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
- if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR))
- {
- for (int i = 0; i < ARRAYLEN(pnSeed); i++)
- {
- // It'll only connect to one or two seed nodes because once it connects,
- // it'll get a pile of addresses with newer timestamps.
- CAddress addr;
- addr.ip = pnSeed[i];
- addr.nTime = 0;
- AddAddress(addr);
- }
- fSeedUsed = true;
- }
-
- if (fSeedUsed && mapAddresses.size() > ARRAYLEN(pnSeed) + 100)
- {
- // Disconnect seed nodes
- set<unsigned int> setSeed(pnSeed, pnSeed + ARRAYLEN(pnSeed));
- static int64 nSeedDisconnected;
- if (nSeedDisconnected == 0)
- {
- nSeedDisconnected = GetTime();
- CRITICAL_BLOCK(cs_vNodes)
- foreach(CNode* pnode, vNodes)
- if (setSeed.count(pnode->addr.ip))
- pnode->fDisconnect = true;
- }
-
- // Keep setting timestamps to 0 so they won't reconnect
- if (GetTime() - nSeedDisconnected < 60 * 60)
- {
- foreach(PAIRTYPE(const vector<unsigned char>, CAddress)& item, mapAddresses)
- {
- if (setSeed.count(item.second.ip))
- {
- item.second.nTime = 0;
- CAddrDB().WriteAddress(item.second);
- }
- }
- }
- }
- }
-
-
- //
- // Choose an address to connect to based on most recently seen
- //
- CAddress addrConnect;
- int64 nBest = INT64_MIN;
-
- // Do this here so we don't have to critsect vNodes inside mapAddresses critsect
- set<unsigned int> setConnected;
- CRITICAL_BLOCK(cs_vNodes)
- foreach(CNode* pnode, vNodes)
- setConnected.insert(pnode->addr.ip);
-
- CRITICAL_BLOCK(cs_mapAddresses)
- {
- foreach(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
- {
- const CAddress& addr = item.second;
- if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip))
- continue;
- int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime;
- int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry;
-
- // Randomize the order in a deterministic way, putting the standard port first
- int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
- if (addr.port != DEFAULT_PORT)
- nRandomizer += 2 * 60 * 60;
-
- // Last seen Base retry frequency
- // <1 hour 10 min
- // 1 hour 1 hour
- // 4 hours 2 hours
- // 24 hours 5 hours
- // 48 hours 7 hours
- // 7 days 13 hours
- // 30 days 27 hours
- // 90 days 46 hours
- // 365 days 93 hours
- int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
-
- // Fast reconnect for one hour after last seen
- if (nSinceLastSeen < 60 * 60)
- nDelay = 10 * 60;
-
- // Limit retry frequency
- if (nSinceLastTry < nDelay)
- continue;
-
- // If we have IRC, we'll be notified when they first come online,
- // and again every 24 hours by the refresh broadcast.
- if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
- continue;
-
- // Only try the old stuff if we don't have enough connections
- if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
- continue;
-
- // If multiple addresses are ready, prioritize by time since
- // last seen and time since last tried.
- int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
- if (nScore > nBest)
- {
- nBest = nScore;
- addrConnect = addr;
- }
- }
- }
-
- if (addrConnect.IsValid())
- OpenNetworkConnection(addrConnect);
- }
-}
-
-bool OpenNetworkConnection(const CAddress& addrConnect)
-{
- //
- // Initiate outbound network connection
- //
- if (fShutdown)
- return false;
- if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))
- return false;
-
- vnThreadsRunning[1]--;
- CNode* pnode = ConnectNode(addrConnect);
- vnThreadsRunning[1]++;
- if (fShutdown)
- return false;
- if (!pnode)
- return false;
- pnode->fNetworkNode = true;
-
- if (addrLocalHost.IsRoutable() && !fUseProxy)
- {
- // Advertise our address
- vector<CAddress> vAddr;
- vAddr.push_back(addrLocalHost);
- pnode->PushMessage("addr", vAddr);
- }
-
- // Get as many addresses as we can
- pnode->PushMessage("getaddr");
- pnode->fGetAddr = true; // don't relay the results of the getaddr
-
- ////// should the one on the receiving end do this too?
- // Subscribe our local subscription list
- const unsigned int nHops = 0;
- for (unsigned int nChannel = 0; nChannel < pnodeLocalHost->vfSubscribe.size(); nChannel++)
- if (pnodeLocalHost->vfSubscribe[nChannel])
- pnode->PushMessage("subscribe", nChannel, nHops);
-
- return true;
-}
-
-
-
-
-
-
-
-
-void ThreadMessageHandler(void* parg)
-{
- IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
- try
- {
- vnThreadsRunning[2]++;
- ThreadMessageHandler2(parg);
- vnThreadsRunning[2]--;
- }
- catch (std::exception& e) {
- vnThreadsRunning[2]--;
- PrintException(&e, "ThreadMessageHandler()");
- } catch (...) {
- vnThreadsRunning[2]--;
- PrintException(NULL, "ThreadMessageHandler()");
- }
- printf("ThreadMessageHandler exiting\n");
-}
-
-void ThreadMessageHandler2(void* parg)
-{
- printf("ThreadMessageHandler started\n");
- SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
- while (!fShutdown)
- {
- vector<CNode*> vNodesCopy;
- CRITICAL_BLOCK(cs_vNodes)
- {
- vNodesCopy = vNodes;
- foreach(CNode* pnode, vNodesCopy)
- pnode->AddRef();
- }
-
- // Poll the connected nodes for messages
- CNode* pnodeTrickle = NULL;
- if (!vNodesCopy.empty())
- pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
- foreach(CNode* pnode, vNodesCopy)
- {
- // Receive messages
- TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
- ProcessMessages(pnode);
- if (fShutdown)
- return;
-
- // Send messages
- TRY_CRITICAL_BLOCK(pnode->cs_vSend)
- SendMessages(pnode, pnode == pnodeTrickle);
- if (fShutdown)
- return;
- }
-
- CRITICAL_BLOCK(cs_vNodes)
- {
- foreach(CNode* pnode, vNodesCopy)
- pnode->Release();
- }
-
- // Wait and allow messages to bunch up
- vnThreadsRunning[2]--;
- Sleep(100);
- vnThreadsRunning[2]++;
- if (fShutdown)
- return;
- }
-}
-
-
-
-
-
-
-
-
-
-bool BindListenPort(string& strError)
-{
- strError = "";
- int nOne = 1;
-
-#ifdef __WXMSW__
- // Initialize Windows Sockets
- WSADATA wsadata;
- int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
- if (ret != NO_ERROR)
- {
- strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
- printf("%s\n", strError.c_str());
- return false;
- }
-#endif
-
- // Create socket for listening for incoming connections
- hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (hListenSocket == INVALID_SOCKET)
- {
- strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
- printf("%s\n", strError.c_str());
- return false;
- }
-
-#if defined(__BSD__) || defined(__WXOSX__)
- // Different way of disabling SIGPIPE on BSD
- setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
-#endif
-
-#ifndef __WXMSW__
- // Allow binding if the port is still in TIME_WAIT state after
- // the program was closed and restarted. Not an issue on windows.
- setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
-#endif
-
-#ifdef __WXMSW__
- // Set to nonblocking, incoming connections will also inherit this
- if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
-#else
- if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
-#endif
- {
- strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
- printf("%s\n", strError.c_str());
- return false;
- }
-
- // The sockaddr_in structure specifies the address family,
- // IP address, and port for the socket that is being bound
- struct sockaddr_in sockaddr;
- memset(&sockaddr, 0, sizeof(sockaddr));
- sockaddr.sin_family = AF_INET;
- sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
- sockaddr.sin_port = DEFAULT_PORT;
- if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
- {
- int nErr = WSAGetLastError();
- if (nErr == WSAEADDRINUSE)
- strError = strprintf("Unable to bind to port %d on this computer. Bitcoin is probably already running.", ntohs(sockaddr.sin_port));
- else
- strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
- printf("%s\n", strError.c_str());
- return false;
- }
- printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
-
- // Listen for incoming connections
- if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
- {
- strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
- printf("%s\n", strError.c_str());
- return false;
- }
-
- return true;
-}
-
-void StartNode(void* parg)
-{
- if (pnodeLocalHost == NULL)
- pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices));
-
-#ifdef __WXMSW__
- // Get local host ip
- char pszHostName[1000] = "";
- if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
- {
- struct hostent* phostent = gethostbyname(pszHostName);
- if (phostent)
- {
- // Take the first IP that isn't loopback 127.x.x.x
- for (int i = 0; phostent->h_addr_list[i] != NULL; i++)
- printf("host ip %d: %s\n", i, CAddress(*(unsigned int*)phostent->h_addr_list[i]).ToStringIP().c_str());
- for (int i = 0; phostent->h_addr_list[i] != NULL; i++)
- {
- CAddress addr(*(unsigned int*)phostent->h_addr_list[i], DEFAULT_PORT, nLocalServices);
- if (addr.IsValid() && addr.GetByte(3) != 127)
- {
- addrLocalHost = addr;
- break;
- }
- }
- }
- }
-#else
- // Get local host ip
- struct ifaddrs* myaddrs;
- if (getifaddrs(&myaddrs) == 0)
- {
- for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
- {
- if (ifa->ifa_addr == NULL) continue;
- if ((ifa->ifa_flags & IFF_UP) == 0) continue;
- if (strcmp(ifa->ifa_name, "lo") == 0) continue;
- if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
- char pszIP[100];
- if (ifa->ifa_addr->sa_family == AF_INET)
- {
- struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
- if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
- printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
-
- // Take the first IP that isn't loopback 127.x.x.x
- CAddress addr(*(unsigned int*)&s4->sin_addr, DEFAULT_PORT, nLocalServices);
- if (addr.IsValid() && addr.GetByte(3) != 127)
- {
- addrLocalHost = addr;
- break;
- }
- }
- else if (ifa->ifa_addr->sa_family == AF_INET6)
- {
- struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
- if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
- printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
- }
- }
- freeifaddrs(myaddrs);
- }
-#endif
- printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
-
- // Get our external IP address for incoming connections
- if (fUseProxy)
- {
- // Proxies can't take incoming connections
- addrLocalHost.ip = CAddress("0.0.0.0").ip;
- printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
- }
- else
- {
- if (addrIncoming.IsValid())
- addrLocalHost.ip = addrIncoming.ip;
-
- if (GetMyExternalIP(addrLocalHost.ip))
- {
- addrIncoming = addrLocalHost;
- CWalletDB().WriteSetting("addrIncoming", addrIncoming);
- printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
- }
- }
-
- //
- // Start threads
- //
-
- // Get addresses from IRC and advertise ours
- if (!CreateThread(ThreadIRCSeed, NULL))
- printf("Error: CreateThread(ThreadIRCSeed) failed\n");
-
- // Send and receive from sockets, accept connections
- pthread_t hThreadSocketHandler = CreateThread(ThreadSocketHandler, NULL, true);
-
- // Initiate outbound connections
- if (!CreateThread(ThreadOpenConnections, NULL))
- printf("Error: CreateThread(ThreadOpenConnections) failed\n");
-
- // Process messages
- if (!CreateThread(ThreadMessageHandler, NULL))
- printf("Error: CreateThread(ThreadMessageHandler) failed\n");
-
- // Generate coins in the background
- GenerateBitcoins(fGenerateBitcoins);
-
- //
- // Thread monitoring
- // Not really needed anymore, the cause of the hanging was fixed
- //
- loop
- {
- Sleep(1000);
- if (fShutdown)
- return;
- if (GetTime() - nThreadSocketHandlerHeartbeat > 15 * 60)
- {
- // First see if closing sockets will free it
- printf("*** ThreadSocketHandler is stopped ***\n");
- CRITICAL_BLOCK(cs_vNodes)
- {
- foreach(CNode* pnode, vNodes)
- {
- bool fGot = false;
- TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
- TRY_CRITICAL_BLOCK(pnode->cs_vSend)
- fGot = true;
- if (!fGot)
- {
- printf("*** closing socket\n");
- pnode->CloseSocketDisconnect();
- }
- }
- }
- Sleep(10000);
- if (fShutdown)
- return;
- if (GetTime() - nThreadSocketHandlerHeartbeat < 60)
- continue;
-
- // Hopefully it never comes to this.
- // We know it'll always be hung in the recv or send call.
- // cs_vRecv or cs_vSend may be left permanently unreleased,
- // but we always only use TRY_CRITICAL_SECTION on them.
- printf("*** Restarting ThreadSocketHandler ***\n");
- TerminateThread(hThreadSocketHandler, 0);
- #ifdef __WXMSW__
- CloseHandle(hThreadSocketHandler);
- #endif
- vnThreadsRunning[0] = 0;
-
- // Restart
- hThreadSocketHandler = CreateThread(ThreadSocketHandler, NULL, true);
- nThreadSocketHandlerHeartbeat = GetTime();
- }
- }
-}
-
-bool StopNode()
-{
- printf("StopNode()\n");
- fShutdown = true;
- nTransactionsUpdated++;
- int64 nStart = GetTime();
- while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0)
- {
- if (GetTime() - nStart > 20)
- break;
- Sleep(20);
- }
- if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
- if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
- if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
- if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
- if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
- while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
- Sleep(20);
- Sleep(50);
-
- return true;
-}
-
-class CNetCleanup
-{
-public:
- CNetCleanup()
- {
- }
- ~CNetCleanup()
- {
- // Close sockets
- foreach(CNode* pnode, vNodes)
- if (pnode->hSocket != INVALID_SOCKET)
- closesocket(pnode->hSocket);
- if (hListenSocket != INVALID_SOCKET)
- if (closesocket(hListenSocket) == SOCKET_ERROR)
- printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
-
-#ifdef __WXMSW__
- // Shutdown Windows Sockets
- WSACleanup();
-#endif
- }
-}
-instance_of_cnetcleanup;
+// Copyright (c) 2009-2010 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +#include "headers.h" + +void ThreadMessageHandler2(void* parg); +void ThreadSocketHandler2(void* parg); +void ThreadOpenConnections2(void* parg); +bool OpenNetworkConnection(const CAddress& addrConnect); + + + + + +// +// Global state variables +// +bool fClient = false; +uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK); +CAddress addrLocalHost(0, DEFAULT_PORT, nLocalServices); +CNode* pnodeLocalHost = NULL; +uint64 nLocalHostNonce = 0; +array<int, 10> vnThreadsRunning; +SOCKET hListenSocket = INVALID_SOCKET; +int64 nThreadSocketHandlerHeartbeat = INT64_MAX; + +vector<CNode*> vNodes; +CCriticalSection cs_vNodes; +map<vector<unsigned char>, CAddress> mapAddresses; +CCriticalSection cs_mapAddresses; +map<CInv, CDataStream> mapRelay; +deque<pair<int64, CInv> > vRelayExpiration; +CCriticalSection cs_mapRelay; +map<CInv, int64> mapAlreadyAskedFor; + +// Settings +int fUseProxy = false; +CAddress addrProxy("127.0.0.1:9050"); + + + + + +void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd) +{ + // Filter out duplicate requests + if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd) + return; + pindexLastGetBlocksBegin = pindexBegin; + hashLastGetBlocksEnd = hashEnd; + + PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd); +} + + + + + +bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet) +{ + hSocketRet = INVALID_SOCKET; + + SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (hSocket == INVALID_SOCKET) + return false; +#if defined(__BSD__) || defined(__WXOSX__) + int set = 1; + setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int)); +#endif + + bool fRoutable = !(addrConnect.GetByte(3) == 10 || (addrConnect.GetByte(3) == 192 && addrConnect.GetByte(2) == 168)); + bool fProxy = (fUseProxy && fRoutable); + struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr()); + + if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR) + { + closesocket(hSocket); + return false; + } + + if (fProxy) + { + printf("proxy connecting %s\n", addrConnect.ToStringLog().c_str()); + char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user"; + memcpy(pszSocks4IP + 2, &addrConnect.port, 2); + memcpy(pszSocks4IP + 4, &addrConnect.ip, 4); + char* pszSocks4 = pszSocks4IP; + int nSize = sizeof(pszSocks4IP); + + int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL); + if (ret != nSize) + { + closesocket(hSocket); + return error("Error sending to proxy"); + } + char pchRet[8]; + if (recv(hSocket, pchRet, 8, 0) != 8) + { + closesocket(hSocket); + return error("Error reading proxy response"); + } + if (pchRet[1] != 0x5a) + { + closesocket(hSocket); + if (pchRet[1] != 0x5b) + printf("ERROR: Proxy returned error %d\n", pchRet[1]); + return false; + } + printf("proxy connected %s\n", addrConnect.ToStringLog().c_str()); + } + + hSocketRet = hSocket; + return true; +} + + + +bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const char* pszKeyword, unsigned int& ipRet) +{ + SOCKET hSocket; + if (!ConnectSocket(addrConnect, hSocket)) + return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str()); + + send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL); + + string strLine; + while (RecvLine(hSocket, strLine)) + { + if (strLine.empty()) + { + loop + { + if (!RecvLine(hSocket, strLine)) + { + closesocket(hSocket); + return false; + } + if (strLine.find(pszKeyword) != -1) + { + strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword)); + break; + } + } + closesocket(hSocket); + if (strLine.find("<")) + strLine = strLine.substr(0, strLine.find("<")); + strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r")); + while (strLine.size() > 0 && isspace(strLine[strLine.size()-1])) + strLine.resize(strLine.size()-1); + CAddress addr(strLine.c_str()); + printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str()); + if (addr.ip == 0 || addr.ip == INADDR_NONE || !addr.IsRoutable()) + return false; + ipRet = addr.ip; + return true; + } + } + closesocket(hSocket); + return error("GetMyExternalIP() : connection closed"); +} + + +bool GetMyExternalIP(unsigned int& ipRet) +{ + CAddress addrConnect; + const char* pszGet; + const char* pszKeyword; + + if (fUseProxy) + return false; + + for (int nLookup = 0; nLookup <= 1; nLookup++) + for (int nHost = 1; nHost <= 2; nHost++) + { + if (nHost == 1) + { + addrConnect = CAddress("70.86.96.218:80"); // www.ipaddressworld.com + + if (nLookup == 1) + { + struct hostent* phostent = gethostbyname("www.ipaddressworld.com"); + if (phostent && phostent->h_addr_list && phostent->h_addr_list[0]) + addrConnect = CAddress(*(u_long*)phostent->h_addr_list[0], htons(80)); + } + + pszGet = "GET /ip.php HTTP/1.1\r\n" + "Host: www.ipaddressworld.com\r\n" + "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n" + "Connection: close\r\n" + "\r\n"; + + pszKeyword = "IP:"; + } + else if (nHost == 2) + { + addrConnect = CAddress("208.78.68.70:80"); // checkip.dyndns.org + + if (nLookup == 1) + { + struct hostent* phostent = gethostbyname("checkip.dyndns.org"); + if (phostent && phostent->h_addr_list && phostent->h_addr_list[0]) + addrConnect = CAddress(*(u_long*)phostent->h_addr_list[0], htons(80)); + } + + pszGet = "GET / HTTP/1.1\r\n" + "Host: checkip.dyndns.org\r\n" + "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n" + "Connection: close\r\n" + "\r\n"; + + pszKeyword = "Address:"; + } + + if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet)) + return true; + } + + return false; +} + + + + + +bool AddAddress(CAddress addr) +{ + if (!addr.IsRoutable()) + return false; + if (addr.ip == addrLocalHost.ip) + return false; + CRITICAL_BLOCK(cs_mapAddresses) + { + map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey()); + if (it == mapAddresses.end()) + { + // New address + printf("AddAddress(%s)\n", addr.ToStringLog().c_str()); + mapAddresses.insert(make_pair(addr.GetKey(), addr)); + CAddrDB().WriteAddress(addr); + return true; + } + else + { + bool fUpdated = false; + CAddress& addrFound = (*it).second; + if ((addrFound.nServices | addr.nServices) != addrFound.nServices) + { + // Services have been added + addrFound.nServices |= addr.nServices; + fUpdated = true; + } + bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60); + int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60); + if (addrFound.nTime < addr.nTime - nUpdateInterval) + { + // Periodically update most recently seen time + addrFound.nTime = addr.nTime; + fUpdated = true; + } + if (fUpdated) + CAddrDB().WriteAddress(addrFound); + } + } + return false; +} + +void AddressCurrentlyConnected(const CAddress& addr) +{ + CRITICAL_BLOCK(cs_mapAddresses) + { + // Only if it's been published already + map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey()); + if (it != mapAddresses.end()) + { + CAddress& addrFound = (*it).second; + int64 nUpdateInterval = 20 * 60; + if (addrFound.nTime < GetAdjustedTime() - nUpdateInterval) + { + // Periodically update most recently seen time + addrFound.nTime = GetAdjustedTime(); + CAddrDB addrdb; + addrdb.WriteAddress(addrFound); + } + } + } +} + + + + + +void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1) +{ + // If the dialog might get closed before the reply comes back, + // call this in the destructor so it doesn't get called after it's deleted. + CRITICAL_BLOCK(cs_vNodes) + { + foreach(CNode* pnode, vNodes) + { + CRITICAL_BLOCK(pnode->cs_mapRequests) + { + for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();) + { + CRequestTracker& tracker = (*mi).second; + if (tracker.fn == fn && tracker.param1 == param1) + pnode->mapRequests.erase(mi++); + else + mi++; + } + } + } + } +} + + + + + + + +// +// Subscription methods for the broadcast and subscription system. +// Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT. +// +// The subscription system uses a meet-in-the-middle strategy. +// With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers +// subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through. +// + +bool AnySubscribed(unsigned int nChannel) +{ + if (pnodeLocalHost->IsSubscribed(nChannel)) + return true; + CRITICAL_BLOCK(cs_vNodes) + foreach(CNode* pnode, vNodes) + if (pnode->IsSubscribed(nChannel)) + return true; + return false; +} + +bool CNode::IsSubscribed(unsigned int nChannel) +{ + if (nChannel >= vfSubscribe.size()) + return false; + return vfSubscribe[nChannel]; +} + +void CNode::Subscribe(unsigned int nChannel, unsigned int nHops) +{ + if (nChannel >= vfSubscribe.size()) + return; + + if (!AnySubscribed(nChannel)) + { + // Relay subscribe + CRITICAL_BLOCK(cs_vNodes) + foreach(CNode* pnode, vNodes) + if (pnode != this) + pnode->PushMessage("subscribe", nChannel, nHops); + } + + vfSubscribe[nChannel] = true; +} + +void CNode::CancelSubscribe(unsigned int nChannel) +{ + if (nChannel >= vfSubscribe.size()) + return; + + // Prevent from relaying cancel if wasn't subscribed + if (!vfSubscribe[nChannel]) + return; + vfSubscribe[nChannel] = false; + + if (!AnySubscribed(nChannel)) + { + // Relay subscription cancel + CRITICAL_BLOCK(cs_vNodes) + foreach(CNode* pnode, vNodes) + if (pnode != this) + pnode->PushMessage("sub-cancel", nChannel); + } +} + + + + + + + + + +CNode* FindNode(unsigned int ip) +{ + CRITICAL_BLOCK(cs_vNodes) + { + foreach(CNode* pnode, vNodes) + if (pnode->addr.ip == ip) + return (pnode); + } + return NULL; +} + +CNode* FindNode(CAddress addr) +{ + CRITICAL_BLOCK(cs_vNodes) + { + foreach(CNode* pnode, vNodes) + if (pnode->addr == addr) + return (pnode); + } + return NULL; +} + +CNode* ConnectNode(CAddress addrConnect, int64 nTimeout) +{ + if (addrConnect.ip == addrLocalHost.ip) + return NULL; + + // Look for an existing connection + CNode* pnode = FindNode(addrConnect.ip); + if (pnode) + { + if (nTimeout != 0) + pnode->AddRef(nTimeout); + else + pnode->AddRef(); + return pnode; + } + + /// debug print + printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n", + addrConnect.ToStringLog().c_str(), + (double)(addrConnect.nTime - GetAdjustedTime())/3600.0, + (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0); + + CRITICAL_BLOCK(cs_mapAddresses) + mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime(); + + // Connect + SOCKET hSocket; + if (ConnectSocket(addrConnect, hSocket)) + { + /// debug print + printf("connected %s\n", addrConnect.ToStringLog().c_str()); + + // Set to nonblocking +#ifdef __WXMSW__ + u_long nOne = 1; + if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR) + printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError()); +#else + if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR) + printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno); +#endif + + // Add node + CNode* pnode = new CNode(hSocket, addrConnect, false); + if (nTimeout != 0) + pnode->AddRef(nTimeout); + else + pnode->AddRef(); + CRITICAL_BLOCK(cs_vNodes) + vNodes.push_back(pnode); + + pnode->nTimeConnected = GetTime(); + return pnode; + } + else + { + return NULL; + } +} + +void CNode::CloseSocketDisconnect() +{ + fDisconnect = true; + if (hSocket != INVALID_SOCKET) + { + if (fDebug) + printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); + printf("disconnecting node %s\n", addr.ToStringLog().c_str()); + closesocket(hSocket); + hSocket = INVALID_SOCKET; + } +} + +void CNode::Cleanup() +{ + // All of a nodes broadcasts and subscriptions are automatically torn down + // when it goes down, so a node has to stay up to keep its broadcast going. + + // Cancel subscriptions + for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++) + if (vfSubscribe[nChannel]) + CancelSubscribe(nChannel); +} + + + + + + + + + + + + + +void ThreadSocketHandler(void* parg) +{ + IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg)); + try + { + vnThreadsRunning[0]++; + ThreadSocketHandler2(parg); + vnThreadsRunning[0]--; + } + catch (std::exception& e) { + vnThreadsRunning[0]--; + PrintException(&e, "ThreadSocketHandler()"); + } catch (...) { + vnThreadsRunning[0]--; + throw; // support pthread_cancel() + } + printf("ThreadSocketHandler exiting\n"); +} + +void ThreadSocketHandler2(void* parg) +{ + printf("ThreadSocketHandler started\n"); + list<CNode*> vNodesDisconnected; + int nPrevNodeCount = 0; + + loop + { + // + // Disconnect nodes + // + CRITICAL_BLOCK(cs_vNodes) + { + // Disconnect unused nodes + vector<CNode*> vNodesCopy = vNodes; + foreach(CNode* pnode, vNodesCopy) + { + if (pnode->fDisconnect || + (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty())) + { + // remove from vNodes + vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end()); + + // close socket and cleanup + pnode->CloseSocketDisconnect(); + pnode->Cleanup(); + + // hold in disconnected pool until all refs are released + pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60); + if (pnode->fNetworkNode || pnode->fInbound) + pnode->Release(); + vNodesDisconnected.push_back(pnode); + } + } + + // Delete disconnected nodes + list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected; + foreach(CNode* pnode, vNodesDisconnectedCopy) + { + // wait until threads are done using it + if (pnode->GetRefCount() <= 0) + { + bool fDelete = false; + TRY_CRITICAL_BLOCK(pnode->cs_vSend) + TRY_CRITICAL_BLOCK(pnode->cs_vRecv) + TRY_CRITICAL_BLOCK(pnode->cs_mapRequests) + TRY_CRITICAL_BLOCK(pnode->cs_inventory) + fDelete = true; + if (fDelete) + { + vNodesDisconnected.remove(pnode); + delete pnode; + } + } + } + } + if (vNodes.size() != nPrevNodeCount) + { + nPrevNodeCount = vNodes.size(); + MainFrameRepaint(); + } + + + // + // Find which sockets have data to receive + // + struct timeval timeout; + timeout.tv_sec = 0; + timeout.tv_usec = 50000; // frequency to poll pnode->vSend + + fd_set fdsetRecv; + fd_set fdsetSend; + fd_set fdsetError; + FD_ZERO(&fdsetRecv); + FD_ZERO(&fdsetSend); + FD_ZERO(&fdsetError); + SOCKET hSocketMax = 0; + FD_SET(hListenSocket, &fdsetRecv); + hSocketMax = max(hSocketMax, hListenSocket); + CRITICAL_BLOCK(cs_vNodes) + { + foreach(CNode* pnode, vNodes) + { + if (pnode->hSocket == INVALID_SOCKET || pnode->hSocket < 0) + continue; + FD_SET(pnode->hSocket, &fdsetRecv); + FD_SET(pnode->hSocket, &fdsetError); + hSocketMax = max(hSocketMax, pnode->hSocket); + TRY_CRITICAL_BLOCK(pnode->cs_vSend) + if (!pnode->vSend.empty()) + FD_SET(pnode->hSocket, &fdsetSend); + } + } + + vnThreadsRunning[0]--; + int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout); + vnThreadsRunning[0]++; + if (fShutdown) + return; + if (nSelect == SOCKET_ERROR) + { + int nErr = WSAGetLastError(); + printf("socket select error %d\n", nErr); + for (int i = 0; i <= hSocketMax; i++) + FD_SET(i, &fdsetRecv); + FD_ZERO(&fdsetSend); + FD_ZERO(&fdsetError); + Sleep(timeout.tv_usec/1000); + } + + + // + // Accept new connections + // + if (FD_ISSET(hListenSocket, &fdsetRecv)) + { + struct sockaddr_in sockaddr; + socklen_t len = sizeof(sockaddr); + SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len); + CAddress addr(sockaddr); + if (hSocket == INVALID_SOCKET) + { + if (WSAGetLastError() != WSAEWOULDBLOCK) + printf("socket error accept failed: %d\n", WSAGetLastError()); + } + else + { + printf("accepted connection %s\n", addr.ToStringLog().c_str()); + CNode* pnode = new CNode(hSocket, addr, true); + pnode->AddRef(); + CRITICAL_BLOCK(cs_vNodes) + vNodes.push_back(pnode); + } + } + + + // + // Service each socket + // + vector<CNode*> vNodesCopy; + CRITICAL_BLOCK(cs_vNodes) + { + vNodesCopy = vNodes; + foreach(CNode* pnode, vNodesCopy) + pnode->AddRef(); + } + foreach(CNode* pnode, vNodesCopy) + { + if (fShutdown) + return; + + // + // Receive + // + if (pnode->hSocket == INVALID_SOCKET) + continue; + if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError)) + { + TRY_CRITICAL_BLOCK(pnode->cs_vRecv) + { + CDataStream& vRecv = pnode->vRecv; + unsigned int nPos = vRecv.size(); + + // typical socket buffer is 8K-64K + char pchBuf[0x10000]; + int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT); + if (nBytes > 0) + { + vRecv.resize(nPos + nBytes); + memcpy(&vRecv[nPos], pchBuf, nBytes); + pnode->nLastRecv = GetTime(); + } + else if (nBytes == 0) + { + // socket closed gracefully + if (!pnode->fDisconnect) + printf("socket closed\n"); + pnode->CloseSocketDisconnect(); + } + else if (nBytes < 0) + { + // error + int nErr = WSAGetLastError(); + if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS) + { + if (!pnode->fDisconnect) + printf("socket recv error %d\n", nErr); + pnode->CloseSocketDisconnect(); + } + } + } + } + + // + // Send + // + if (pnode->hSocket == INVALID_SOCKET) + continue; + if (FD_ISSET(pnode->hSocket, &fdsetSend)) + { + TRY_CRITICAL_BLOCK(pnode->cs_vSend) + { + CDataStream& vSend = pnode->vSend; + if (!vSend.empty()) + { + int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT); + if (nBytes > 0) + { + vSend.erase(vSend.begin(), vSend.begin() + nBytes); + pnode->nLastSend = GetTime(); + } + else if (nBytes < 0) + { + // error + int nErr = WSAGetLastError(); + if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS) + { + printf("socket send error %d\n", nErr); + pnode->CloseSocketDisconnect(); + } + } + } + } + } + + // + // Inactivity checking + // + if (pnode->vSend.empty()) + pnode->nLastSendEmpty = GetTime(); + if (GetTime() - pnode->nTimeConnected > 60) + { + if (pnode->nLastRecv == 0 || pnode->nLastSend == 0) + { + printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0); + pnode->fDisconnect = true; + } + else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60) + { + printf("socket not sending\n"); + pnode->fDisconnect = true; + } + else if (GetTime() - pnode->nLastRecv > 90*60) + { + printf("socket inactivity timeout\n"); + pnode->fDisconnect = true; + } + } + } + CRITICAL_BLOCK(cs_vNodes) + { + foreach(CNode* pnode, vNodesCopy) + pnode->Release(); + } + + nThreadSocketHandlerHeartbeat = GetTime(); + Sleep(10); + } +} + + + + + + + + + + + + + +unsigned int pnSeed[] = +{ + 0x35218252, 0x9c9c9618, 0xda6bacad, 0xb9aca862, 0x97c235c6, + 0x146f9562, 0xb67b9e4b, 0x87cf4bc0, 0xb83945d0, 0x984333ad, + 0xbbeec555, 0x6f0eb440, 0xe0005318, 0x7797e460, 0xddc60fcc, + 0xb3bbd24a, 0x1ac85746, 0x641846a6, 0x85ee1155, 0xbb2e7a4c, + 0x9cb8514b, 0xfc342648, 0x62958fae, 0xd0a8c87a, 0xa800795b, + 0xda8c814e, 0x256a0c80, 0x3f23ec63, 0xd565df43, 0x997d9044, + 0xaa121448, 0xbed8688e, 0x59d09a5e, 0xb2931243, 0x3730ba18, + 0xdd3462d0, 0x4e4d1448, 0x171df645, 0x84ee1155, + 0x248ac445, 0x0e634444, 0x0ded1b63, 0x30c01e60, + 0xa2b9a094, 0x29e4fd43, 0x9ce61b4c, 0xdae09744, +}; + + + +void ThreadOpenConnections(void* parg) +{ + IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg)); + try + { + vnThreadsRunning[1]++; + ThreadOpenConnections2(parg); + vnThreadsRunning[1]--; + } + catch (std::exception& e) { + vnThreadsRunning[1]--; + PrintException(&e, "ThreadOpenConnections()"); + } catch (...) { + vnThreadsRunning[1]--; + PrintException(NULL, "ThreadOpenConnections()"); + } + printf("ThreadOpenConnections exiting\n"); +} + +void ThreadOpenConnections2(void* parg) +{ + printf("ThreadOpenConnections started\n"); + + // Connect to specific addresses + if (mapArgs.count("-connect")) + { + for (int64 nLoop = 0;; nLoop++) + { + foreach(string strAddr, mapMultiArgs["-connect"]) + { + CAddress addr(strAddr, NODE_NETWORK); + if (addr.IsValid()) + OpenNetworkConnection(addr); + for (int i = 0; i < 10 && i < nLoop; i++) + { + Sleep(500); + if (fShutdown) + return; + } + } + } + } + + // Connect to manually added nodes first + if (mapArgs.count("-addnode")) + { + foreach(string strAddr, mapMultiArgs["-addnode"]) + { + CAddress addr(strAddr, NODE_NETWORK); + if (addr.IsValid()) + { + OpenNetworkConnection(addr); + Sleep(500); + if (fShutdown) + return; + } + } + } + + // Initiate network connections + int64 nStart = GetTime(); + loop + { + // Wait + vnThreadsRunning[1]--; + Sleep(500); + const int nMaxConnections = 8; + while (vNodes.size() >= nMaxConnections) + { + Sleep(2000); + if (fShutdown) + return; + } + vnThreadsRunning[1]++; + if (fShutdown) + return; + + CRITICAL_BLOCK(cs_mapAddresses) + { + // Add seed nodes if IRC isn't working + static bool fSeedUsed; + bool fTOR = (fUseProxy && addrProxy.port == htons(9050)); + if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR)) + { + for (int i = 0; i < ARRAYLEN(pnSeed); i++) + { + // It'll only connect to one or two seed nodes because once it connects, + // it'll get a pile of addresses with newer timestamps. + CAddress addr; + addr.ip = pnSeed[i]; + addr.nTime = 0; + AddAddress(addr); + } + fSeedUsed = true; + } + + if (fSeedUsed && mapAddresses.size() > ARRAYLEN(pnSeed) + 100) + { + // Disconnect seed nodes + set<unsigned int> setSeed(pnSeed, pnSeed + ARRAYLEN(pnSeed)); + static int64 nSeedDisconnected; + if (nSeedDisconnected == 0) + { + nSeedDisconnected = GetTime(); + CRITICAL_BLOCK(cs_vNodes) + foreach(CNode* pnode, vNodes) + if (setSeed.count(pnode->addr.ip)) + pnode->fDisconnect = true; + } + + // Keep setting timestamps to 0 so they won't reconnect + if (GetTime() - nSeedDisconnected < 60 * 60) + { + foreach(PAIRTYPE(const vector<unsigned char>, CAddress)& item, mapAddresses) + { + if (setSeed.count(item.second.ip)) + { + item.second.nTime = 0; + CAddrDB().WriteAddress(item.second); + } + } + } + } + } + + + // + // Choose an address to connect to based on most recently seen + // + CAddress addrConnect; + int64 nBest = INT64_MIN; + + // Do this here so we don't have to critsect vNodes inside mapAddresses critsect + set<unsigned int> setConnected; + CRITICAL_BLOCK(cs_vNodes) + foreach(CNode* pnode, vNodes) + setConnected.insert(pnode->addr.ip); + + CRITICAL_BLOCK(cs_mapAddresses) + { + foreach(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses) + { + const CAddress& addr = item.second; + if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip)) + continue; + int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime; + int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry; + + // Randomize the order in a deterministic way, putting the standard port first + int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60); + if (addr.port != DEFAULT_PORT) + nRandomizer += 2 * 60 * 60; + + // Last seen Base retry frequency + // <1 hour 10 min + // 1 hour 1 hour + // 4 hours 2 hours + // 24 hours 5 hours + // 48 hours 7 hours + // 7 days 13 hours + // 30 days 27 hours + // 90 days 46 hours + // 365 days 93 hours + int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer); + + // Fast reconnect for one hour after last seen + if (nSinceLastSeen < 60 * 60) + nDelay = 10 * 60; + + // Limit retry frequency + if (nSinceLastTry < nDelay) + continue; + + // If we have IRC, we'll be notified when they first come online, + // and again every 24 hours by the refresh broadcast. + if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60) + continue; + + // Only try the old stuff if we don't have enough connections + if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60) + continue; + + // If multiple addresses are ready, prioritize by time since + // last seen and time since last tried. + int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer; + if (nScore > nBest) + { + nBest = nScore; + addrConnect = addr; + } + } + } + + if (addrConnect.IsValid()) + OpenNetworkConnection(addrConnect); + } +} + +bool OpenNetworkConnection(const CAddress& addrConnect) +{ + // + // Initiate outbound network connection + // + if (fShutdown) + return false; + if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip)) + return false; + + vnThreadsRunning[1]--; + CNode* pnode = ConnectNode(addrConnect); + vnThreadsRunning[1]++; + if (fShutdown) + return false; + if (!pnode) + return false; + pnode->fNetworkNode = true; + + if (addrLocalHost.IsRoutable() && !fUseProxy) + { + // Advertise our address + vector<CAddress> vAddr; + vAddr.push_back(addrLocalHost); + pnode->PushMessage("addr", vAddr); + } + + // Get as many addresses as we can + pnode->PushMessage("getaddr"); + pnode->fGetAddr = true; // don't relay the results of the getaddr + + ////// should the one on the receiving end do this too? + // Subscribe our local subscription list + const unsigned int nHops = 0; + for (unsigned int nChannel = 0; nChannel < pnodeLocalHost->vfSubscribe.size(); nChannel++) + if (pnodeLocalHost->vfSubscribe[nChannel]) + pnode->PushMessage("subscribe", nChannel, nHops); + + return true; +} + + + + + + + + +void ThreadMessageHandler(void* parg) +{ + IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg)); + try + { + vnThreadsRunning[2]++; + ThreadMessageHandler2(parg); + vnThreadsRunning[2]--; + } + catch (std::exception& e) { + vnThreadsRunning[2]--; + PrintException(&e, "ThreadMessageHandler()"); + } catch (...) { + vnThreadsRunning[2]--; + PrintException(NULL, "ThreadMessageHandler()"); + } + printf("ThreadMessageHandler exiting\n"); +} + +void ThreadMessageHandler2(void* parg) +{ + printf("ThreadMessageHandler started\n"); + SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL); + while (!fShutdown) + { + vector<CNode*> vNodesCopy; + CRITICAL_BLOCK(cs_vNodes) + { + vNodesCopy = vNodes; + foreach(CNode* pnode, vNodesCopy) + pnode->AddRef(); + } + + // Poll the connected nodes for messages + CNode* pnodeTrickle = NULL; + if (!vNodesCopy.empty()) + pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())]; + foreach(CNode* pnode, vNodesCopy) + { + // Receive messages + TRY_CRITICAL_BLOCK(pnode->cs_vRecv) + ProcessMessages(pnode); + if (fShutdown) + return; + + // Send messages + TRY_CRITICAL_BLOCK(pnode->cs_vSend) + SendMessages(pnode, pnode == pnodeTrickle); + if (fShutdown) + return; + } + + CRITICAL_BLOCK(cs_vNodes) + { + foreach(CNode* pnode, vNodesCopy) + pnode->Release(); + } + + // Wait and allow messages to bunch up + vnThreadsRunning[2]--; + Sleep(100); + vnThreadsRunning[2]++; + if (fShutdown) + return; + } +} + + + + + + + + + +bool BindListenPort(string& strError) +{ + strError = ""; + int nOne = 1; + +#ifdef __WXMSW__ + // Initialize Windows Sockets + WSADATA wsadata; + int ret = WSAStartup(MAKEWORD(2,2), &wsadata); + if (ret != NO_ERROR) + { + strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret); + printf("%s\n", strError.c_str()); + return false; + } +#endif + + // Create socket for listening for incoming connections + hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (hListenSocket == INVALID_SOCKET) + { + strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError()); + printf("%s\n", strError.c_str()); + return false; + } + +#if defined(__BSD__) || defined(__WXOSX__) + // Different way of disabling SIGPIPE on BSD + setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int)); +#endif + +#ifndef __WXMSW__ + // Allow binding if the port is still in TIME_WAIT state after + // the program was closed and restarted. Not an issue on windows. + setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int)); +#endif + +#ifdef __WXMSW__ + // Set to nonblocking, incoming connections will also inherit this + if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR) +#else + if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR) +#endif + { + strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError()); + printf("%s\n", strError.c_str()); + return false; + } + + // The sockaddr_in structure specifies the address family, + // IP address, and port for the socket that is being bound + struct sockaddr_in sockaddr; + memset(&sockaddr, 0, sizeof(sockaddr)); + sockaddr.sin_family = AF_INET; + sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer + sockaddr.sin_port = DEFAULT_PORT; + if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR) + { + int nErr = WSAGetLastError(); + if (nErr == WSAEADDRINUSE) + strError = strprintf("Unable to bind to port %d on this computer. Bitcoin is probably already running.", ntohs(sockaddr.sin_port)); + else + strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr); + printf("%s\n", strError.c_str()); + return false; + } + printf("Bound to port %d\n", ntohs(sockaddr.sin_port)); + + // Listen for incoming connections + if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR) + { + strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError()); + printf("%s\n", strError.c_str()); + return false; + } + + return true; +} + +void StartNode(void* parg) +{ + if (pnodeLocalHost == NULL) + pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices)); + +#ifdef __WXMSW__ + // Get local host ip + char pszHostName[1000] = ""; + if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR) + { + struct hostent* phostent = gethostbyname(pszHostName); + if (phostent) + { + // Take the first IP that isn't loopback 127.x.x.x + for (int i = 0; phostent->h_addr_list[i] != NULL; i++) + printf("host ip %d: %s\n", i, CAddress(*(unsigned int*)phostent->h_addr_list[i]).ToStringIP().c_str()); + for (int i = 0; phostent->h_addr_list[i] != NULL; i++) + { + CAddress addr(*(unsigned int*)phostent->h_addr_list[i], DEFAULT_PORT, nLocalServices); + if (addr.IsValid() && addr.GetByte(3) != 127) + { + addrLocalHost = addr; + break; + } + } + } + } +#else + // Get local host ip + struct ifaddrs* myaddrs; + if (getifaddrs(&myaddrs) == 0) + { + for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next) + { + if (ifa->ifa_addr == NULL) continue; + if ((ifa->ifa_flags & IFF_UP) == 0) continue; + if (strcmp(ifa->ifa_name, "lo") == 0) continue; + if (strcmp(ifa->ifa_name, "lo0") == 0) continue; + char pszIP[100]; + if (ifa->ifa_addr->sa_family == AF_INET) + { + struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr); + if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL) + printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP); + + // Take the first IP that isn't loopback 127.x.x.x + CAddress addr(*(unsigned int*)&s4->sin_addr, DEFAULT_PORT, nLocalServices); + if (addr.IsValid() && addr.GetByte(3) != 127) + { + addrLocalHost = addr; + break; + } + } + else if (ifa->ifa_addr->sa_family == AF_INET6) + { + struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr); + if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL) + printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP); + } + } + freeifaddrs(myaddrs); + } +#endif + printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str()); + + // Get our external IP address for incoming connections + if (fUseProxy) + { + // Proxies can't take incoming connections + addrLocalHost.ip = CAddress("0.0.0.0").ip; + printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str()); + } + else + { + if (addrIncoming.IsValid()) + addrLocalHost.ip = addrIncoming.ip; + + if (GetMyExternalIP(addrLocalHost.ip)) + { + addrIncoming = addrLocalHost; + CWalletDB().WriteSetting("addrIncoming", addrIncoming); + printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str()); + } + } + + // + // Start threads + // + + // Get addresses from IRC and advertise ours + if (!CreateThread(ThreadIRCSeed, NULL)) + printf("Error: CreateThread(ThreadIRCSeed) failed\n"); + + // Send and receive from sockets, accept connections + pthread_t hThreadSocketHandler = CreateThread(ThreadSocketHandler, NULL, true); + + // Initiate outbound connections + if (!CreateThread(ThreadOpenConnections, NULL)) + printf("Error: CreateThread(ThreadOpenConnections) failed\n"); + + // Process messages + if (!CreateThread(ThreadMessageHandler, NULL)) + printf("Error: CreateThread(ThreadMessageHandler) failed\n"); + + // Generate coins in the background + GenerateBitcoins(fGenerateBitcoins); + + // + // Thread monitoring + // Not really needed anymore, the cause of the hanging was fixed + // + loop + { + Sleep(1000); + if (fShutdown) + return; + if (GetTime() - nThreadSocketHandlerHeartbeat > 15 * 60) + { + // First see if closing sockets will free it + printf("*** ThreadSocketHandler is stopped ***\n"); + CRITICAL_BLOCK(cs_vNodes) + { + foreach(CNode* pnode, vNodes) + { + bool fGot = false; + TRY_CRITICAL_BLOCK(pnode->cs_vRecv) + TRY_CRITICAL_BLOCK(pnode->cs_vSend) + fGot = true; + if (!fGot) + { + printf("*** closing socket\n"); + pnode->CloseSocketDisconnect(); + } + } + } + Sleep(10000); + if (fShutdown) + return; + if (GetTime() - nThreadSocketHandlerHeartbeat < 60) + continue; + + // Hopefully it never comes to this. + // We know it'll always be hung in the recv or send call. + // cs_vRecv or cs_vSend may be left permanently unreleased, + // but we always only use TRY_CRITICAL_SECTION on them. + printf("*** Restarting ThreadSocketHandler ***\n"); + TerminateThread(hThreadSocketHandler, 0); + #ifdef __WXMSW__ + CloseHandle(hThreadSocketHandler); + #endif + vnThreadsRunning[0] = 0; + + // Restart + hThreadSocketHandler = CreateThread(ThreadSocketHandler, NULL, true); + nThreadSocketHandlerHeartbeat = GetTime(); + } + } +} + +bool StopNode() +{ + printf("StopNode()\n"); + fShutdown = true; + nTransactionsUpdated++; + int64 nStart = GetTime(); + while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0) + { + if (GetTime() - nStart > 20) + break; + Sleep(20); + } + if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n"); + if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n"); + if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n"); + if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n"); + if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n"); + while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0) + Sleep(20); + Sleep(50); + + return true; +} + +class CNetCleanup +{ +public: + CNetCleanup() + { + } + ~CNetCleanup() + { + // Close sockets + foreach(CNode* pnode, vNodes) + if (pnode->hSocket != INVALID_SOCKET) + closesocket(pnode->hSocket); + if (hListenSocket != INVALID_SOCKET) + if (closesocket(hListenSocket) == SOCKET_ERROR) + printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError()); + +#ifdef __WXMSW__ + // Shutdown Windows Sockets + WSACleanup(); +#endif + } +} +instance_of_cnetcleanup; @@ -1,1052 +1,1052 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
-
-class CMessageHeader;
-class CAddress;
-class CInv;
-class CRequestTracker;
-class CNode;
-class CBlockIndex;
-extern int nBestHeight;
-
-
-
-static const unsigned short DEFAULT_PORT = 0x8d20; // htons(8333)
-static const unsigned int PUBLISH_HOPS = 5;
-enum
-{
- NODE_NETWORK = (1 << 0),
-};
-
-
-
-
-bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet);
-bool GetMyExternalIP(unsigned int& ipRet);
-bool AddAddress(CAddress addr);
-void AddressCurrentlyConnected(const CAddress& addr);
-CNode* FindNode(unsigned int ip);
-CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0);
-void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1);
-bool AnySubscribed(unsigned int nChannel);
-bool BindListenPort(string& strError=REF(string()));
-void StartNode(void* parg);
-bool StopNode();
-
-
-
-
-
-
-
-
-//
-// Message header
-// (4) message start
-// (12) command
-// (4) size
-// (4) checksum
-
-// The message start string is designed to be unlikely to occur in normal data.
-// The characters are rarely used upper ascii, not valid as UTF-8, and produce
-// a large 4-byte int at any alignment.
-static const char pchMessageStart[4] = { 0xf9, 0xbe, 0xb4, 0xd9 };
-
-class CMessageHeader
-{
-public:
- enum { COMMAND_SIZE=12 };
- char pchMessageStart[sizeof(::pchMessageStart)];
- char pchCommand[COMMAND_SIZE];
- unsigned int nMessageSize;
- unsigned int nChecksum;
-
- CMessageHeader()
- {
- memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart));
- memset(pchCommand, 0, sizeof(pchCommand));
- pchCommand[1] = 1;
- nMessageSize = -1;
- nChecksum = 0;
- }
-
- CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn)
- {
- memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart));
- strncpy(pchCommand, pszCommand, COMMAND_SIZE);
- nMessageSize = nMessageSizeIn;
- nChecksum = 0;
- }
-
- IMPLEMENT_SERIALIZE
- (
- READWRITE(FLATDATA(pchMessageStart));
- READWRITE(FLATDATA(pchCommand));
- READWRITE(nMessageSize);
- if (nVersion >= 209)
- READWRITE(nChecksum);
- )
-
- string GetCommand()
- {
- if (pchCommand[COMMAND_SIZE-1] == 0)
- return string(pchCommand, pchCommand + strlen(pchCommand));
- else
- return string(pchCommand, pchCommand + COMMAND_SIZE);
- }
-
- bool IsValid()
- {
- // Check start string
- if (memcmp(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)) != 0)
- return false;
-
- // Check the command string for errors
- for (char* p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; p1++)
- {
- if (*p1 == 0)
- {
- // Must be all zeros after the first zero
- for (; p1 < pchCommand + COMMAND_SIZE; p1++)
- if (*p1 != 0)
- return false;
- }
- else if (*p1 < ' ' || *p1 > 0x7E)
- return false;
- }
-
- // Message size
- if (nMessageSize > 0x10000000)
- {
- printf("CMessageHeader::IsValid() : nMessageSize too large %u\n", nMessageSize);
- return false;
- }
-
- return true;
- }
-};
-
-
-
-
-
-
-static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
-
-class CAddress
-{
-public:
- uint64 nServices;
- unsigned char pchReserved[12];
- unsigned int ip;
- unsigned short port;
-
- // disk only
- unsigned int nTime;
-
- // memory only
- unsigned int nLastTry;
-
- CAddress()
- {
- Init();
- }
-
- CAddress(unsigned int ipIn, unsigned short portIn=DEFAULT_PORT, uint64 nServicesIn=NODE_NETWORK)
- {
- Init();
- ip = ipIn;
- port = portIn;
- nServices = nServicesIn;
- }
-
- explicit CAddress(const struct sockaddr_in& sockaddr, uint64 nServicesIn=NODE_NETWORK)
- {
- Init();
- ip = sockaddr.sin_addr.s_addr;
- port = sockaddr.sin_port;
- nServices = nServicesIn;
- }
-
- explicit CAddress(const char* pszIn, uint64 nServicesIn=NODE_NETWORK)
- {
- Init();
- SetAddress(pszIn);
- nServices = nServicesIn;
- }
-
- explicit CAddress(string strIn, uint64 nServicesIn=NODE_NETWORK)
- {
- Init();
- SetAddress(strIn.c_str());
- nServices = nServicesIn;
- }
-
- void Init()
- {
- nServices = NODE_NETWORK;
- memcpy(pchReserved, pchIPv4, sizeof(pchReserved));
- ip = INADDR_NONE;
- port = DEFAULT_PORT;
- nTime = GetAdjustedTime();
- nLastTry = 0;
- }
-
- bool SetAddress(const char* pszIn)
- {
- ip = INADDR_NONE;
- port = DEFAULT_PORT;
- char psz[100];
- strlcpy(psz, pszIn, sizeof(psz));
- unsigned int a=0, b=0, c=0, d=0, e=0;
- if (sscanf(psz, "%u.%u.%u.%u:%u", &a, &b, &c, &d, &e) < 4)
- return false;
- char* pszPort = strchr(psz, ':');
- if (pszPort)
- {
- *pszPort++ = '\0';
- port = htons(atoi(pszPort));
- if (atoi(pszPort) < 0 || atoi(pszPort) > USHRT_MAX)
- port = htons(USHRT_MAX);
- }
- ip = inet_addr(psz);
- return IsValid();
- }
-
- bool SetAddress(string strIn)
- {
- return SetAddress(strIn.c_str());
- }
-
- IMPLEMENT_SERIALIZE
- (
- if (nType & SER_DISK)
- {
- READWRITE(nVersion);
- READWRITE(nTime);
- }
- READWRITE(nServices);
- READWRITE(FLATDATA(pchReserved)); // for IPv6
- READWRITE(ip);
- READWRITE(port);
- )
-
- friend inline bool operator==(const CAddress& a, const CAddress& b)
- {
- return (memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved)) == 0 &&
- a.ip == b.ip &&
- a.port == b.port);
- }
-
- friend inline bool operator!=(const CAddress& a, const CAddress& b)
- {
- return (!(a == b));
- }
-
- friend inline bool operator<(const CAddress& a, const CAddress& b)
- {
- int ret = memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved));
- if (ret < 0)
- return true;
- else if (ret == 0)
- {
- if (ntohl(a.ip) < ntohl(b.ip))
- return true;
- else if (a.ip == b.ip)
- return ntohs(a.port) < ntohs(b.port);
- }
- return false;
- }
-
- vector<unsigned char> GetKey() const
- {
- CDataStream ss;
- ss.reserve(18);
- ss << FLATDATA(pchReserved) << ip << port;
-
- #if defined(_MSC_VER) && _MSC_VER < 1300
- return vector<unsigned char>((unsigned char*)&ss.begin()[0], (unsigned char*)&ss.end()[0]);
- #else
- return vector<unsigned char>(ss.begin(), ss.end());
- #endif
- }
-
- struct sockaddr_in GetSockAddr() const
- {
- struct sockaddr_in sockaddr;
- memset(&sockaddr, 0, sizeof(sockaddr));
- sockaddr.sin_family = AF_INET;
- sockaddr.sin_addr.s_addr = ip;
- sockaddr.sin_port = port;
- return sockaddr;
- }
-
- bool IsIPv4() const
- {
- return (memcmp(pchReserved, pchIPv4, sizeof(pchIPv4)) == 0);
- }
-
- bool IsRoutable() const
- {
- return IsValid() &&
- !(GetByte(3) == 10 ||
- (GetByte(3) == 192 && GetByte(2) == 168) ||
- GetByte(3) == 127 ||
- GetByte(3) == 0);
- }
-
- bool IsValid() const
- {
- // Clean up 3-byte shifted addresses caused by garbage in size field
- // of addr messages from versions before 0.2.9 checksum.
- // Two consecutive addr messages look like this:
- // header20 vectorlen3 addr26 addr26 addr26 header20 vectorlen3 addr26 addr26 addr26...
- // so if the first length field is garbled, it reads the second batch
- // of addr misaligned by 3 bytes.
- if (memcmp(pchReserved, pchIPv4+3, sizeof(pchIPv4)-3) == 0)
- return false;
-
- return (ip != 0 && ip != INADDR_NONE && port != htons(USHRT_MAX));
- }
-
- unsigned char GetByte(int n) const
- {
- return ((unsigned char*)&ip)[3-n];
- }
-
- string ToStringIPPort() const
- {
- return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port));
- }
-
- string ToStringIP() const
- {
- return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0));
- }
-
- string ToStringPort() const
- {
- return strprintf("%u", ntohs(port));
- }
-
- string ToStringLog() const
- {
- return "";
- }
-
- string ToString() const
- {
- return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port));
- }
-
- void print() const
- {
- printf("CAddress(%s)\n", ToString().c_str());
- }
-};
-
-
-
-
-
-
-
-enum
-{
- MSG_TX = 1,
- MSG_BLOCK,
-};
-
-static const char* ppszTypeName[] =
-{
- "ERROR",
- "tx",
- "block",
-};
-
-class CInv
-{
-public:
- int type;
- uint256 hash;
-
- CInv()
- {
- type = 0;
- hash = 0;
- }
-
- CInv(int typeIn, const uint256& hashIn)
- {
- type = typeIn;
- hash = hashIn;
- }
-
- CInv(const string& strType, const uint256& hashIn)
- {
- int i;
- for (i = 1; i < ARRAYLEN(ppszTypeName); i++)
- {
- if (strType == ppszTypeName[i])
- {
- type = i;
- break;
- }
- }
- if (i == ARRAYLEN(ppszTypeName))
- throw std::out_of_range(strprintf("CInv::CInv(string, uint256) : unknown type '%s'", strType.c_str()));
- hash = hashIn;
- }
-
- IMPLEMENT_SERIALIZE
- (
- READWRITE(type);
- READWRITE(hash);
- )
-
- friend inline bool operator<(const CInv& a, const CInv& b)
- {
- return (a.type < b.type || (a.type == b.type && a.hash < b.hash));
- }
-
- bool IsKnownType() const
- {
- return (type >= 1 && type < ARRAYLEN(ppszTypeName));
- }
-
- const char* GetCommand() const
- {
- if (!IsKnownType())
- throw std::out_of_range(strprintf("CInv::GetCommand() : type=% unknown type", type));
- return ppszTypeName[type];
- }
-
- string ToString() const
- {
- return strprintf("%s %s", GetCommand(), hash.ToString().substr(0,16).c_str());
- }
-
- void print() const
- {
- printf("CInv(%s)\n", ToString().c_str());
- }
-};
-
-
-
-
-
-class CRequestTracker
-{
-public:
- void (*fn)(void*, CDataStream&);
- void* param1;
-
- explicit CRequestTracker(void (*fnIn)(void*, CDataStream&)=NULL, void* param1In=NULL)
- {
- fn = fnIn;
- param1 = param1In;
- }
-
- bool IsNull()
- {
- return fn == NULL;
- }
-};
-
-
-
-
-
-extern bool fClient;
-extern uint64 nLocalServices;
-extern CAddress addrLocalHost;
-extern CNode* pnodeLocalHost;
-extern uint64 nLocalHostNonce;
-extern array<int, 10> vnThreadsRunning;
-extern SOCKET hListenSocket;
-extern int64 nThreadSocketHandlerHeartbeat;
-
-extern vector<CNode*> vNodes;
-extern CCriticalSection cs_vNodes;
-extern map<vector<unsigned char>, CAddress> mapAddresses;
-extern CCriticalSection cs_mapAddresses;
-extern map<CInv, CDataStream> mapRelay;
-extern deque<pair<int64, CInv> > vRelayExpiration;
-extern CCriticalSection cs_mapRelay;
-extern map<CInv, int64> mapAlreadyAskedFor;
-
-// Settings
-extern int fUseProxy;
-extern CAddress addrProxy;
-
-
-
-
-
-
-class CNode
-{
-public:
- // socket
- uint64 nServices;
- SOCKET hSocket;
- CDataStream vSend;
- CDataStream vRecv;
- CCriticalSection cs_vSend;
- CCriticalSection cs_vRecv;
- int64 nLastSend;
- int64 nLastRecv;
- int64 nLastSendEmpty;
- int64 nTimeConnected;
- unsigned int nHeaderStart;
- unsigned int nMessageStart;
- CAddress addr;
- int nVersion;
- bool fClient;
- bool fInbound;
- bool fNetworkNode;
- bool fSuccessfullyConnected;
- bool fDisconnect;
-protected:
- int nRefCount;
-public:
- int64 nReleaseTime;
- map<uint256, CRequestTracker> mapRequests;
- CCriticalSection cs_mapRequests;
- uint256 hashContinue;
- CBlockIndex* pindexLastGetBlocksBegin;
- uint256 hashLastGetBlocksEnd;
- int nStartingHeight;
-
- // flood
- vector<CAddress> vAddrToSend;
- set<CAddress> setAddrKnown;
- bool fGetAddr;
-
- // inventory based relay
- set<CInv> setInventoryKnown;
- vector<CInv> vInventoryToSend;
- CCriticalSection cs_inventory;
- multimap<int64, CInv> mapAskFor;
-
- // publish and subscription
- vector<char> vfSubscribe;
-
-
- CNode(SOCKET hSocketIn, CAddress addrIn, bool fInboundIn=false)
- {
- nServices = 0;
- hSocket = hSocketIn;
- vSend.SetType(SER_NETWORK);
- vSend.SetVersion(0);
- vRecv.SetType(SER_NETWORK);
- vRecv.SetVersion(0);
- // Version 0.2 obsoletes 20 Feb 2012
- if (GetTime() > 1329696000)
- {
- vSend.SetVersion(209);
- vRecv.SetVersion(209);
- }
- nLastSend = 0;
- nLastRecv = 0;
- nLastSendEmpty = GetTime();
- nTimeConnected = GetTime();
- nHeaderStart = -1;
- nMessageStart = -1;
- addr = addrIn;
- nVersion = 0;
- fClient = false; // set by version message
- fInbound = fInboundIn;
- fNetworkNode = false;
- fSuccessfullyConnected = false;
- fDisconnect = false;
- nRefCount = 0;
- nReleaseTime = 0;
- hashContinue = 0;
- pindexLastGetBlocksBegin = 0;
- hashLastGetBlocksEnd = 0;
- nStartingHeight = -1;
- fGetAddr = false;
- vfSubscribe.assign(256, false);
-
- // Push a version message
- /// when NTP implemented, change to just nTime = GetAdjustedTime()
- int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
- CAddress addrYou = (fUseProxy ? CAddress("0.0.0.0") : addr);
- CAddress addrMe = (fUseProxy ? CAddress("0.0.0.0") : addrLocalHost);
- RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
- PushMessage("version", VERSION, nLocalServices, nTime, addrYou, addrMe,
- nLocalHostNonce, string(pszSubVer), nBestHeight);
- }
-
- ~CNode()
- {
- if (hSocket != INVALID_SOCKET)
- {
- closesocket(hSocket);
- hSocket = INVALID_SOCKET;
- }
- }
-
-private:
- CNode(const CNode&);
- void operator=(const CNode&);
-public:
-
-
- int GetRefCount()
- {
- return max(nRefCount, 0) + (GetTime() < nReleaseTime ? 1 : 0);
- }
-
- CNode* AddRef(int64 nTimeout=0)
- {
- if (nTimeout != 0)
- nReleaseTime = max(nReleaseTime, GetTime() + nTimeout);
- else
- nRefCount++;
- return this;
- }
-
- void Release()
- {
- nRefCount--;
- }
-
-
-
- void AddAddressKnown(const CAddress& addr)
- {
- setAddrKnown.insert(addr);
- }
-
- void PushAddress(const CAddress& addr)
- {
- // Known checking here is only to save space from duplicates.
- // SendMessages will filter it again for knowns that were added
- // after addresses were pushed.
- if (addr.IsValid() && !setAddrKnown.count(addr))
- vAddrToSend.push_back(addr);
- }
-
-
- void AddInventoryKnown(const CInv& inv)
- {
- CRITICAL_BLOCK(cs_inventory)
- setInventoryKnown.insert(inv);
- }
-
- void PushInventory(const CInv& inv)
- {
- CRITICAL_BLOCK(cs_inventory)
- if (!setInventoryKnown.count(inv))
- vInventoryToSend.push_back(inv);
- }
-
- void AskFor(const CInv& inv)
- {
- // We're using mapAskFor as a priority queue,
- // the key is the earliest time the request can be sent
- int64& nRequestTime = mapAlreadyAskedFor[inv];
- printf("askfor %s %"PRI64d"\n", inv.ToString().c_str(), nRequestTime);
-
- // Make sure not to reuse time indexes to keep things in the same order
- int64 nNow = (GetTime() - 1) * 1000000;
- static int64 nLastTime;
- nLastTime = nNow = max(nNow, ++nLastTime);
-
- // Each retry is 2 minutes after the last
- nRequestTime = max(nRequestTime + 2 * 60 * 1000000, nNow);
- mapAskFor.insert(make_pair(nRequestTime, inv));
- }
-
-
-
- void BeginMessage(const char* pszCommand)
- {
- cs_vSend.Enter();
- if (nHeaderStart != -1)
- AbortMessage();
- nHeaderStart = vSend.size();
- vSend << CMessageHeader(pszCommand, 0);
- nMessageStart = vSend.size();
- if (fDebug)
- printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
- printf("sending: %s ", pszCommand);
- }
-
- void AbortMessage()
- {
- if (nHeaderStart == -1)
- return;
- vSend.resize(nHeaderStart);
- nHeaderStart = -1;
- nMessageStart = -1;
- cs_vSend.Leave();
- printf("(aborted)\n");
- }
-
- void EndMessage()
- {
- if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
- {
- printf("dropmessages DROPPING SEND MESSAGE\n");
- AbortMessage();
- return;
- }
-
- if (nHeaderStart == -1)
- return;
-
- // Set the size
- unsigned int nSize = vSend.size() - nMessageStart;
- memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize));
-
- // Set the checksum
- if (vSend.GetVersion() >= 209)
- {
- uint256 hash = Hash(vSend.begin() + nMessageStart, vSend.end());
- unsigned int nChecksum = 0;
- memcpy(&nChecksum, &hash, sizeof(nChecksum));
- assert(nMessageStart - nHeaderStart >= offsetof(CMessageHeader, nChecksum) + sizeof(nChecksum));
- memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nChecksum), &nChecksum, sizeof(nChecksum));
- }
-
- printf("(%d bytes) ", nSize);
- printf("\n");
-
- nHeaderStart = -1;
- nMessageStart = -1;
- cs_vSend.Leave();
- }
-
- void EndMessageAbortIfEmpty()
- {
- if (nHeaderStart == -1)
- return;
- int nSize = vSend.size() - nMessageStart;
- if (nSize > 0)
- EndMessage();
- else
- AbortMessage();
- }
-
- const char* GetMessageCommand() const
- {
- if (nHeaderStart == -1)
- return "";
- return &vSend[nHeaderStart] + offsetof(CMessageHeader, pchCommand);
- }
-
-
-
-
- void PushMessage(const char* pszCommand)
- {
- try
- {
- BeginMessage(pszCommand);
- EndMessage();
- }
- catch (...)
- {
- AbortMessage();
- throw;
- }
- }
-
- template<typename T1>
- void PushMessage(const char* pszCommand, const T1& a1)
- {
- try
- {
- BeginMessage(pszCommand);
- vSend << a1;
- EndMessage();
- }
- catch (...)
- {
- AbortMessage();
- throw;
- }
- }
-
- template<typename T1, typename T2>
- void PushMessage(const char* pszCommand, const T1& a1, const T2& a2)
- {
- try
- {
- BeginMessage(pszCommand);
- vSend << a1 << a2;
- EndMessage();
- }
- catch (...)
- {
- AbortMessage();
- throw;
- }
- }
-
- template<typename T1, typename T2, typename T3>
- void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3)
- {
- try
- {
- BeginMessage(pszCommand);
- vSend << a1 << a2 << a3;
- EndMessage();
- }
- catch (...)
- {
- AbortMessage();
- throw;
- }
- }
-
- template<typename T1, typename T2, typename T3, typename T4>
- void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4)
- {
- try
- {
- BeginMessage(pszCommand);
- vSend << a1 << a2 << a3 << a4;
- EndMessage();
- }
- catch (...)
- {
- AbortMessage();
- throw;
- }
- }
-
- template<typename T1, typename T2, typename T3, typename T4, typename T5>
- void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5)
- {
- try
- {
- BeginMessage(pszCommand);
- vSend << a1 << a2 << a3 << a4 << a5;
- EndMessage();
- }
- catch (...)
- {
- AbortMessage();
- throw;
- }
- }
-
- template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
- void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6)
- {
- try
- {
- BeginMessage(pszCommand);
- vSend << a1 << a2 << a3 << a4 << a5 << a6;
- EndMessage();
- }
- catch (...)
- {
- AbortMessage();
- throw;
- }
- }
-
- template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
- void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7)
- {
- try
- {
- BeginMessage(pszCommand);
- vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7;
- EndMessage();
- }
- catch (...)
- {
- AbortMessage();
- throw;
- }
- }
-
- template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
- void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7, const T8& a8)
- {
- try
- {
- BeginMessage(pszCommand);
- vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8;
- EndMessage();
- }
- catch (...)
- {
- AbortMessage();
- throw;
- }
- }
-
- template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
- void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7, const T8& a8, const T9& a9)
- {
- try
- {
- BeginMessage(pszCommand);
- vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9;
- EndMessage();
- }
- catch (...)
- {
- AbortMessage();
- throw;
- }
- }
-
-
- void PushRequest(const char* pszCommand,
- void (*fn)(void*, CDataStream&), void* param1)
- {
- uint256 hashReply;
- RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
-
- CRITICAL_BLOCK(cs_mapRequests)
- mapRequests[hashReply] = CRequestTracker(fn, param1);
-
- PushMessage(pszCommand, hashReply);
- }
-
- template<typename T1>
- void PushRequest(const char* pszCommand, const T1& a1,
- void (*fn)(void*, CDataStream&), void* param1)
- {
- uint256 hashReply;
- RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
-
- CRITICAL_BLOCK(cs_mapRequests)
- mapRequests[hashReply] = CRequestTracker(fn, param1);
-
- PushMessage(pszCommand, hashReply, a1);
- }
-
- template<typename T1, typename T2>
- void PushRequest(const char* pszCommand, const T1& a1, const T2& a2,
- void (*fn)(void*, CDataStream&), void* param1)
- {
- uint256 hashReply;
- RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
-
- CRITICAL_BLOCK(cs_mapRequests)
- mapRequests[hashReply] = CRequestTracker(fn, param1);
-
- PushMessage(pszCommand, hashReply, a1, a2);
- }
-
-
-
- void PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd);
- bool IsSubscribed(unsigned int nChannel);
- void Subscribe(unsigned int nChannel, unsigned int nHops=0);
- void CancelSubscribe(unsigned int nChannel);
- void CloseSocketDisconnect();
- void Cleanup();
-};
-
-
-
-
-
-
-
-
-
-
-inline void RelayInventory(const CInv& inv)
-{
- // Put on lists to offer to the other nodes
- CRITICAL_BLOCK(cs_vNodes)
- foreach(CNode* pnode, vNodes)
- pnode->PushInventory(inv);
-}
-
-template<typename T>
-void RelayMessage(const CInv& inv, const T& a)
-{
- CDataStream ss(SER_NETWORK);
- ss.reserve(10000);
- ss << a;
- RelayMessage(inv, ss);
-}
-
-template<>
-inline void RelayMessage<>(const CInv& inv, const CDataStream& ss)
-{
- CRITICAL_BLOCK(cs_mapRelay)
- {
- // Expire old relay messages
- while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
- {
- mapRelay.erase(vRelayExpiration.front().second);
- vRelayExpiration.pop_front();
- }
-
- // Save original serialized message so newer versions are preserved
- mapRelay[inv] = ss;
- vRelayExpiration.push_back(make_pair(GetTime() + 15 * 60, inv));
- }
-
- RelayInventory(inv);
-}
-
-
-
-
-
-
-
-
-//
-// Templates for the publish and subscription system.
-// The object being published as T& obj needs to have:
-// a set<unsigned int> setSources member
-// specializations of AdvertInsert and AdvertErase
-// Currently implemented for CTable and CProduct.
-//
-
-template<typename T>
-void AdvertStartPublish(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj)
-{
- // Add to sources
- obj.setSources.insert(pfrom->addr.ip);
-
- if (!AdvertInsert(obj))
- return;
-
- // Relay
- CRITICAL_BLOCK(cs_vNodes)
- foreach(CNode* pnode, vNodes)
- if (pnode != pfrom && (nHops < PUBLISH_HOPS || pnode->IsSubscribed(nChannel)))
- pnode->PushMessage("publish", nChannel, nHops, obj);
-}
-
-template<typename T>
-void AdvertStopPublish(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj)
-{
- uint256 hash = obj.GetHash();
-
- CRITICAL_BLOCK(cs_vNodes)
- foreach(CNode* pnode, vNodes)
- if (pnode != pfrom && (nHops < PUBLISH_HOPS || pnode->IsSubscribed(nChannel)))
- pnode->PushMessage("pub-cancel", nChannel, nHops, hash);
-
- AdvertErase(obj);
-}
-
-template<typename T>
-void AdvertRemoveSource(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj)
-{
- // Remove a source
- obj.setSources.erase(pfrom->addr.ip);
-
- // If no longer supported by any sources, cancel it
- if (obj.setSources.empty())
- AdvertStopPublish(pfrom, nChannel, nHops, obj);
-}
+// Copyright (c) 2009-2010 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +class CMessageHeader; +class CAddress; +class CInv; +class CRequestTracker; +class CNode; +class CBlockIndex; +extern int nBestHeight; + + + +static const unsigned short DEFAULT_PORT = 0x8d20; // htons(8333) +static const unsigned int PUBLISH_HOPS = 5; +enum +{ + NODE_NETWORK = (1 << 0), +}; + + + + +bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet); +bool GetMyExternalIP(unsigned int& ipRet); +bool AddAddress(CAddress addr); +void AddressCurrentlyConnected(const CAddress& addr); +CNode* FindNode(unsigned int ip); +CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0); +void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1); +bool AnySubscribed(unsigned int nChannel); +bool BindListenPort(string& strError=REF(string())); +void StartNode(void* parg); +bool StopNode(); + + + + + + + + +// +// Message header +// (4) message start +// (12) command +// (4) size +// (4) checksum + +// The message start string is designed to be unlikely to occur in normal data. +// The characters are rarely used upper ascii, not valid as UTF-8, and produce +// a large 4-byte int at any alignment. +static const char pchMessageStart[4] = { 0xf9, 0xbe, 0xb4, 0xd9 }; + +class CMessageHeader +{ +public: + enum { COMMAND_SIZE=12 }; + char pchMessageStart[sizeof(::pchMessageStart)]; + char pchCommand[COMMAND_SIZE]; + unsigned int nMessageSize; + unsigned int nChecksum; + + CMessageHeader() + { + memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)); + memset(pchCommand, 0, sizeof(pchCommand)); + pchCommand[1] = 1; + nMessageSize = -1; + nChecksum = 0; + } + + CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn) + { + memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)); + strncpy(pchCommand, pszCommand, COMMAND_SIZE); + nMessageSize = nMessageSizeIn; + nChecksum = 0; + } + + IMPLEMENT_SERIALIZE + ( + READWRITE(FLATDATA(pchMessageStart)); + READWRITE(FLATDATA(pchCommand)); + READWRITE(nMessageSize); + if (nVersion >= 209) + READWRITE(nChecksum); + ) + + string GetCommand() + { + if (pchCommand[COMMAND_SIZE-1] == 0) + return string(pchCommand, pchCommand + strlen(pchCommand)); + else + return string(pchCommand, pchCommand + COMMAND_SIZE); + } + + bool IsValid() + { + // Check start string + if (memcmp(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)) != 0) + return false; + + // Check the command string for errors + for (char* p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; p1++) + { + if (*p1 == 0) + { + // Must be all zeros after the first zero + for (; p1 < pchCommand + COMMAND_SIZE; p1++) + if (*p1 != 0) + return false; + } + else if (*p1 < ' ' || *p1 > 0x7E) + return false; + } + + // Message size + if (nMessageSize > 0x10000000) + { + printf("CMessageHeader::IsValid() : nMessageSize too large %u\n", nMessageSize); + return false; + } + + return true; + } +}; + + + + + + +static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }; + +class CAddress +{ +public: + uint64 nServices; + unsigned char pchReserved[12]; + unsigned int ip; + unsigned short port; + + // disk only + unsigned int nTime; + + // memory only + unsigned int nLastTry; + + CAddress() + { + Init(); + } + + CAddress(unsigned int ipIn, unsigned short portIn=DEFAULT_PORT, uint64 nServicesIn=NODE_NETWORK) + { + Init(); + ip = ipIn; + port = portIn; + nServices = nServicesIn; + } + + explicit CAddress(const struct sockaddr_in& sockaddr, uint64 nServicesIn=NODE_NETWORK) + { + Init(); + ip = sockaddr.sin_addr.s_addr; + port = sockaddr.sin_port; + nServices = nServicesIn; + } + + explicit CAddress(const char* pszIn, uint64 nServicesIn=NODE_NETWORK) + { + Init(); + SetAddress(pszIn); + nServices = nServicesIn; + } + + explicit CAddress(string strIn, uint64 nServicesIn=NODE_NETWORK) + { + Init(); + SetAddress(strIn.c_str()); + nServices = nServicesIn; + } + + void Init() + { + nServices = NODE_NETWORK; + memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); + ip = INADDR_NONE; + port = DEFAULT_PORT; + nTime = GetAdjustedTime(); + nLastTry = 0; + } + + bool SetAddress(const char* pszIn) + { + ip = INADDR_NONE; + port = DEFAULT_PORT; + char psz[100]; + strlcpy(psz, pszIn, sizeof(psz)); + unsigned int a=0, b=0, c=0, d=0, e=0; + if (sscanf(psz, "%u.%u.%u.%u:%u", &a, &b, &c, &d, &e) < 4) + return false; + char* pszPort = strchr(psz, ':'); + if (pszPort) + { + *pszPort++ = '\0'; + port = htons(atoi(pszPort)); + if (atoi(pszPort) < 0 || atoi(pszPort) > USHRT_MAX) + port = htons(USHRT_MAX); + } + ip = inet_addr(psz); + return IsValid(); + } + + bool SetAddress(string strIn) + { + return SetAddress(strIn.c_str()); + } + + IMPLEMENT_SERIALIZE + ( + if (nType & SER_DISK) + { + READWRITE(nVersion); + READWRITE(nTime); + } + READWRITE(nServices); + READWRITE(FLATDATA(pchReserved)); // for IPv6 + READWRITE(ip); + READWRITE(port); + ) + + friend inline bool operator==(const CAddress& a, const CAddress& b) + { + return (memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved)) == 0 && + a.ip == b.ip && + a.port == b.port); + } + + friend inline bool operator!=(const CAddress& a, const CAddress& b) + { + return (!(a == b)); + } + + friend inline bool operator<(const CAddress& a, const CAddress& b) + { + int ret = memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved)); + if (ret < 0) + return true; + else if (ret == 0) + { + if (ntohl(a.ip) < ntohl(b.ip)) + return true; + else if (a.ip == b.ip) + return ntohs(a.port) < ntohs(b.port); + } + return false; + } + + vector<unsigned char> GetKey() const + { + CDataStream ss; + ss.reserve(18); + ss << FLATDATA(pchReserved) << ip << port; + + #if defined(_MSC_VER) && _MSC_VER < 1300 + return vector<unsigned char>((unsigned char*)&ss.begin()[0], (unsigned char*)&ss.end()[0]); + #else + return vector<unsigned char>(ss.begin(), ss.end()); + #endif + } + + struct sockaddr_in GetSockAddr() const + { + struct sockaddr_in sockaddr; + memset(&sockaddr, 0, sizeof(sockaddr)); + sockaddr.sin_family = AF_INET; + sockaddr.sin_addr.s_addr = ip; + sockaddr.sin_port = port; + return sockaddr; + } + + bool IsIPv4() const + { + return (memcmp(pchReserved, pchIPv4, sizeof(pchIPv4)) == 0); + } + + bool IsRoutable() const + { + return IsValid() && + !(GetByte(3) == 10 || + (GetByte(3) == 192 && GetByte(2) == 168) || + GetByte(3) == 127 || + GetByte(3) == 0); + } + + bool IsValid() const + { + // Clean up 3-byte shifted addresses caused by garbage in size field + // of addr messages from versions before 0.2.9 checksum. + // Two consecutive addr messages look like this: + // header20 vectorlen3 addr26 addr26 addr26 header20 vectorlen3 addr26 addr26 addr26... + // so if the first length field is garbled, it reads the second batch + // of addr misaligned by 3 bytes. + if (memcmp(pchReserved, pchIPv4+3, sizeof(pchIPv4)-3) == 0) + return false; + + return (ip != 0 && ip != INADDR_NONE && port != htons(USHRT_MAX)); + } + + unsigned char GetByte(int n) const + { + return ((unsigned char*)&ip)[3-n]; + } + + string ToStringIPPort() const + { + return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port)); + } + + string ToStringIP() const + { + return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0)); + } + + string ToStringPort() const + { + return strprintf("%u", ntohs(port)); + } + + string ToStringLog() const + { + return ""; + } + + string ToString() const + { + return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port)); + } + + void print() const + { + printf("CAddress(%s)\n", ToString().c_str()); + } +}; + + + + + + + +enum +{ + MSG_TX = 1, + MSG_BLOCK, +}; + +static const char* ppszTypeName[] = +{ + "ERROR", + "tx", + "block", +}; + +class CInv +{ +public: + int type; + uint256 hash; + + CInv() + { + type = 0; + hash = 0; + } + + CInv(int typeIn, const uint256& hashIn) + { + type = typeIn; + hash = hashIn; + } + + CInv(const string& strType, const uint256& hashIn) + { + int i; + for (i = 1; i < ARRAYLEN(ppszTypeName); i++) + { + if (strType == ppszTypeName[i]) + { + type = i; + break; + } + } + if (i == ARRAYLEN(ppszTypeName)) + throw std::out_of_range(strprintf("CInv::CInv(string, uint256) : unknown type '%s'", strType.c_str())); + hash = hashIn; + } + + IMPLEMENT_SERIALIZE + ( + READWRITE(type); + READWRITE(hash); + ) + + friend inline bool operator<(const CInv& a, const CInv& b) + { + return (a.type < b.type || (a.type == b.type && a.hash < b.hash)); + } + + bool IsKnownType() const + { + return (type >= 1 && type < ARRAYLEN(ppszTypeName)); + } + + const char* GetCommand() const + { + if (!IsKnownType()) + throw std::out_of_range(strprintf("CInv::GetCommand() : type=% unknown type", type)); + return ppszTypeName[type]; + } + + string ToString() const + { + return strprintf("%s %s", GetCommand(), hash.ToString().substr(0,16).c_str()); + } + + void print() const + { + printf("CInv(%s)\n", ToString().c_str()); + } +}; + + + + + +class CRequestTracker +{ +public: + void (*fn)(void*, CDataStream&); + void* param1; + + explicit CRequestTracker(void (*fnIn)(void*, CDataStream&)=NULL, void* param1In=NULL) + { + fn = fnIn; + param1 = param1In; + } + + bool IsNull() + { + return fn == NULL; + } +}; + + + + + +extern bool fClient; +extern uint64 nLocalServices; +extern CAddress addrLocalHost; +extern CNode* pnodeLocalHost; +extern uint64 nLocalHostNonce; +extern array<int, 10> vnThreadsRunning; +extern SOCKET hListenSocket; +extern int64 nThreadSocketHandlerHeartbeat; + +extern vector<CNode*> vNodes; +extern CCriticalSection cs_vNodes; +extern map<vector<unsigned char>, CAddress> mapAddresses; +extern CCriticalSection cs_mapAddresses; +extern map<CInv, CDataStream> mapRelay; +extern deque<pair<int64, CInv> > vRelayExpiration; +extern CCriticalSection cs_mapRelay; +extern map<CInv, int64> mapAlreadyAskedFor; + +// Settings +extern int fUseProxy; +extern CAddress addrProxy; + + + + + + +class CNode +{ +public: + // socket + uint64 nServices; + SOCKET hSocket; + CDataStream vSend; + CDataStream vRecv; + CCriticalSection cs_vSend; + CCriticalSection cs_vRecv; + int64 nLastSend; + int64 nLastRecv; + int64 nLastSendEmpty; + int64 nTimeConnected; + unsigned int nHeaderStart; + unsigned int nMessageStart; + CAddress addr; + int nVersion; + bool fClient; + bool fInbound; + bool fNetworkNode; + bool fSuccessfullyConnected; + bool fDisconnect; +protected: + int nRefCount; +public: + int64 nReleaseTime; + map<uint256, CRequestTracker> mapRequests; + CCriticalSection cs_mapRequests; + uint256 hashContinue; + CBlockIndex* pindexLastGetBlocksBegin; + uint256 hashLastGetBlocksEnd; + int nStartingHeight; + + // flood + vector<CAddress> vAddrToSend; + set<CAddress> setAddrKnown; + bool fGetAddr; + + // inventory based relay + set<CInv> setInventoryKnown; + vector<CInv> vInventoryToSend; + CCriticalSection cs_inventory; + multimap<int64, CInv> mapAskFor; + + // publish and subscription + vector<char> vfSubscribe; + + + CNode(SOCKET hSocketIn, CAddress addrIn, bool fInboundIn=false) + { + nServices = 0; + hSocket = hSocketIn; + vSend.SetType(SER_NETWORK); + vSend.SetVersion(0); + vRecv.SetType(SER_NETWORK); + vRecv.SetVersion(0); + // Version 0.2 obsoletes 20 Feb 2012 + if (GetTime() > 1329696000) + { + vSend.SetVersion(209); + vRecv.SetVersion(209); + } + nLastSend = 0; + nLastRecv = 0; + nLastSendEmpty = GetTime(); + nTimeConnected = GetTime(); + nHeaderStart = -1; + nMessageStart = -1; + addr = addrIn; + nVersion = 0; + fClient = false; // set by version message + fInbound = fInboundIn; + fNetworkNode = false; + fSuccessfullyConnected = false; + fDisconnect = false; + nRefCount = 0; + nReleaseTime = 0; + hashContinue = 0; + pindexLastGetBlocksBegin = 0; + hashLastGetBlocksEnd = 0; + nStartingHeight = -1; + fGetAddr = false; + vfSubscribe.assign(256, false); + + // Push a version message + /// when NTP implemented, change to just nTime = GetAdjustedTime() + int64 nTime = (fInbound ? GetAdjustedTime() : GetTime()); + CAddress addrYou = (fUseProxy ? CAddress("0.0.0.0") : addr); + CAddress addrMe = (fUseProxy ? CAddress("0.0.0.0") : addrLocalHost); + RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce)); + PushMessage("version", VERSION, nLocalServices, nTime, addrYou, addrMe, + nLocalHostNonce, string(pszSubVer), nBestHeight); + } + + ~CNode() + { + if (hSocket != INVALID_SOCKET) + { + closesocket(hSocket); + hSocket = INVALID_SOCKET; + } + } + +private: + CNode(const CNode&); + void operator=(const CNode&); +public: + + + int GetRefCount() + { + return max(nRefCount, 0) + (GetTime() < nReleaseTime ? 1 : 0); + } + + CNode* AddRef(int64 nTimeout=0) + { + if (nTimeout != 0) + nReleaseTime = max(nReleaseTime, GetTime() + nTimeout); + else + nRefCount++; + return this; + } + + void Release() + { + nRefCount--; + } + + + + void AddAddressKnown(const CAddress& addr) + { + setAddrKnown.insert(addr); + } + + void PushAddress(const CAddress& addr) + { + // Known checking here is only to save space from duplicates. + // SendMessages will filter it again for knowns that were added + // after addresses were pushed. + if (addr.IsValid() && !setAddrKnown.count(addr)) + vAddrToSend.push_back(addr); + } + + + void AddInventoryKnown(const CInv& inv) + { + CRITICAL_BLOCK(cs_inventory) + setInventoryKnown.insert(inv); + } + + void PushInventory(const CInv& inv) + { + CRITICAL_BLOCK(cs_inventory) + if (!setInventoryKnown.count(inv)) + vInventoryToSend.push_back(inv); + } + + void AskFor(const CInv& inv) + { + // We're using mapAskFor as a priority queue, + // the key is the earliest time the request can be sent + int64& nRequestTime = mapAlreadyAskedFor[inv]; + printf("askfor %s %"PRI64d"\n", inv.ToString().c_str(), nRequestTime); + + // Make sure not to reuse time indexes to keep things in the same order + int64 nNow = (GetTime() - 1) * 1000000; + static int64 nLastTime; + nLastTime = nNow = max(nNow, ++nLastTime); + + // Each retry is 2 minutes after the last + nRequestTime = max(nRequestTime + 2 * 60 * 1000000, nNow); + mapAskFor.insert(make_pair(nRequestTime, inv)); + } + + + + void BeginMessage(const char* pszCommand) + { + cs_vSend.Enter(); + if (nHeaderStart != -1) + AbortMessage(); + nHeaderStart = vSend.size(); + vSend << CMessageHeader(pszCommand, 0); + nMessageStart = vSend.size(); + if (fDebug) + printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); + printf("sending: %s ", pszCommand); + } + + void AbortMessage() + { + if (nHeaderStart == -1) + return; + vSend.resize(nHeaderStart); + nHeaderStart = -1; + nMessageStart = -1; + cs_vSend.Leave(); + printf("(aborted)\n"); + } + + void EndMessage() + { + if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0) + { + printf("dropmessages DROPPING SEND MESSAGE\n"); + AbortMessage(); + return; + } + + if (nHeaderStart == -1) + return; + + // Set the size + unsigned int nSize = vSend.size() - nMessageStart; + memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize)); + + // Set the checksum + if (vSend.GetVersion() >= 209) + { + uint256 hash = Hash(vSend.begin() + nMessageStart, vSend.end()); + unsigned int nChecksum = 0; + memcpy(&nChecksum, &hash, sizeof(nChecksum)); + assert(nMessageStart - nHeaderStart >= offsetof(CMessageHeader, nChecksum) + sizeof(nChecksum)); + memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nChecksum), &nChecksum, sizeof(nChecksum)); + } + + printf("(%d bytes) ", nSize); + printf("\n"); + + nHeaderStart = -1; + nMessageStart = -1; + cs_vSend.Leave(); + } + + void EndMessageAbortIfEmpty() + { + if (nHeaderStart == -1) + return; + int nSize = vSend.size() - nMessageStart; + if (nSize > 0) + EndMessage(); + else + AbortMessage(); + } + + const char* GetMessageCommand() const + { + if (nHeaderStart == -1) + return ""; + return &vSend[nHeaderStart] + offsetof(CMessageHeader, pchCommand); + } + + + + + void PushMessage(const char* pszCommand) + { + try + { + BeginMessage(pszCommand); + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template<typename T1> + void PushMessage(const char* pszCommand, const T1& a1) + { + try + { + BeginMessage(pszCommand); + vSend << a1; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template<typename T1, typename T2> + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template<typename T1, typename T2, typename T3> + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2 << a3; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template<typename T1, typename T2, typename T3, typename T4> + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2 << a3 << a4; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template<typename T1, typename T2, typename T3, typename T4, typename T5> + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2 << a3 << a4 << a5; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2 << a3 << a4 << a5 << a6; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7> + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7, const T8& a8) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9> + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7, const T8& a8, const T9& a9) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + + void PushRequest(const char* pszCommand, + void (*fn)(void*, CDataStream&), void* param1) + { + uint256 hashReply; + RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply)); + + CRITICAL_BLOCK(cs_mapRequests) + mapRequests[hashReply] = CRequestTracker(fn, param1); + + PushMessage(pszCommand, hashReply); + } + + template<typename T1> + void PushRequest(const char* pszCommand, const T1& a1, + void (*fn)(void*, CDataStream&), void* param1) + { + uint256 hashReply; + RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply)); + + CRITICAL_BLOCK(cs_mapRequests) + mapRequests[hashReply] = CRequestTracker(fn, param1); + + PushMessage(pszCommand, hashReply, a1); + } + + template<typename T1, typename T2> + void PushRequest(const char* pszCommand, const T1& a1, const T2& a2, + void (*fn)(void*, CDataStream&), void* param1) + { + uint256 hashReply; + RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply)); + + CRITICAL_BLOCK(cs_mapRequests) + mapRequests[hashReply] = CRequestTracker(fn, param1); + + PushMessage(pszCommand, hashReply, a1, a2); + } + + + + void PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd); + bool IsSubscribed(unsigned int nChannel); + void Subscribe(unsigned int nChannel, unsigned int nHops=0); + void CancelSubscribe(unsigned int nChannel); + void CloseSocketDisconnect(); + void Cleanup(); +}; + + + + + + + + + + +inline void RelayInventory(const CInv& inv) +{ + // Put on lists to offer to the other nodes + CRITICAL_BLOCK(cs_vNodes) + foreach(CNode* pnode, vNodes) + pnode->PushInventory(inv); +} + +template<typename T> +void RelayMessage(const CInv& inv, const T& a) +{ + CDataStream ss(SER_NETWORK); + ss.reserve(10000); + ss << a; + RelayMessage(inv, ss); +} + +template<> +inline void RelayMessage<>(const CInv& inv, const CDataStream& ss) +{ + CRITICAL_BLOCK(cs_mapRelay) + { + // Expire old relay messages + while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime()) + { + mapRelay.erase(vRelayExpiration.front().second); + vRelayExpiration.pop_front(); + } + + // Save original serialized message so newer versions are preserved + mapRelay[inv] = ss; + vRelayExpiration.push_back(make_pair(GetTime() + 15 * 60, inv)); + } + + RelayInventory(inv); +} + + + + + + + + +// +// Templates for the publish and subscription system. +// The object being published as T& obj needs to have: +// a set<unsigned int> setSources member +// specializations of AdvertInsert and AdvertErase +// Currently implemented for CTable and CProduct. +// + +template<typename T> +void AdvertStartPublish(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj) +{ + // Add to sources + obj.setSources.insert(pfrom->addr.ip); + + if (!AdvertInsert(obj)) + return; + + // Relay + CRITICAL_BLOCK(cs_vNodes) + foreach(CNode* pnode, vNodes) + if (pnode != pfrom && (nHops < PUBLISH_HOPS || pnode->IsSubscribed(nChannel))) + pnode->PushMessage("publish", nChannel, nHops, obj); +} + +template<typename T> +void AdvertStopPublish(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj) +{ + uint256 hash = obj.GetHash(); + + CRITICAL_BLOCK(cs_vNodes) + foreach(CNode* pnode, vNodes) + if (pnode != pfrom && (nHops < PUBLISH_HOPS || pnode->IsSubscribed(nChannel))) + pnode->PushMessage("pub-cancel", nChannel, nHops, hash); + + AdvertErase(obj); +} + +template<typename T> +void AdvertRemoveSource(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj) +{ + // Remove a source + obj.setSources.erase(pfrom->addr.ip); + + // If no longer supported by any sources, cancel it + if (obj.setSources.empty()) + AdvertStopPublish(pfrom, nChannel, nHops, obj); +} @@ -1,986 +1,986 @@ -// Copyright (c) 2010 Satoshi Nakamoto
-// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
-
-#include "headers.h"
-#undef printf
-#include <boost/asio.hpp>
-#include "json/json_spirit_reader_template.h"
-#include "json/json_spirit_writer_template.h"
-#include "json/json_spirit_utils.h"
-#define printf OutputDebugStringF
-// MinGW 3.4.5 gets "fatal error: had to relocate PCH" if the json headers are
-// precompiled in headers.h. The problem might be when the pch file goes over
-// a certain size around 145MB. If we need access to json_spirit outside this
-// file, we could use the compiled json_spirit option.
-
-using boost::asio::ip::tcp;
-using namespace json_spirit;
-
-void ThreadRPCServer2(void* parg);
-typedef Value(*rpcfn_type)(const Array& params, bool fHelp);
-extern map<string, rpcfn_type> mapCallTable;
-
-
-
-
-
-
-
-///
-/// Note: This interface may still be subject to change.
-///
-
-
-
-Value help(const Array& params, bool fHelp)
-{
- if (fHelp || params.size() != 0)
- throw runtime_error(
- "help\n"
- "List commands.");
-
- string strRet;
- for (map<string, rpcfn_type>::iterator mi = mapCallTable.begin(); mi != mapCallTable.end(); ++mi)
- {
- try
- {
- Array params;
- (*(*mi).second)(params, true);
- }
- catch (std::exception& e)
- {
- // Help text is returned in an exception
- string strHelp = string(e.what());
- if (strHelp.find('\n') != -1)
- strHelp = strHelp.substr(0, strHelp.find('\n'));
- strRet += strHelp + "\n";
- }
- }
- strRet = strRet.substr(0,strRet.size()-1);
- return strRet;
-}
-
-
-Value stop(const Array& params, bool fHelp)
-{
- if (fHelp || params.size() != 0)
- throw runtime_error(
- "stop\n"
- "Stop bitcoin server.");
-
- // Shutdown will take long enough that the response should get back
- CreateThread(Shutdown, NULL);
- return "bitcoin server stopping";
-}
-
-
-Value getblockcount(const Array& params, bool fHelp)
-{
- if (fHelp || params.size() != 0)
- throw runtime_error(
- "getblockcount\n"
- "Returns the number of blocks in the longest block chain.");
-
- return nBestHeight + 1;
-}
-
-
-Value getblocknumber(const Array& params, bool fHelp)
-{
- if (fHelp || params.size() != 0)
- throw runtime_error(
- "getblocknumber\n"
- "Returns the block number of the latest block in the longest block chain.");
-
- return nBestHeight;
-}
-
-
-Value getconnectioncount(const Array& params, bool fHelp)
-{
- if (fHelp || params.size() != 0)
- throw runtime_error(
- "getconnectioncount\n"
- "Returns the number of connections to other nodes.");
-
- return (int)vNodes.size();
-}
-
-
-double GetDifficulty()
-{
- // Floating point number that is a multiple of the minimum difficulty,
- // minimum difficulty = 1.0.
- if (pindexBest == NULL)
- return 1.0;
- int nShift = 256 - 32 - 31; // to fit in a uint
- double dMinimum = (CBigNum().SetCompact(bnProofOfWorkLimit.GetCompact()) >> nShift).getuint();
- double dCurrently = (CBigNum().SetCompact(pindexBest->nBits) >> nShift).getuint();
- return dMinimum / dCurrently;
-}
-
-Value getdifficulty(const Array& params, bool fHelp)
-{
- if (fHelp || params.size() != 0)
- throw runtime_error(
- "getdifficulty\n"
- "Returns the proof-of-work difficulty as a multiple of the minimum difficulty.");
-
- return GetDifficulty();
-}
-
-
-Value getbalance(const Array& params, bool fHelp)
-{
- if (fHelp || params.size() != 0)
- throw runtime_error(
- "getbalance\n"
- "Returns the server's available balance.");
-
- return ((double)GetBalance() / (double)COIN);
-}
-
-
-Value getgenerate(const Array& params, bool fHelp)
-{
- if (fHelp || params.size() != 0)
- throw runtime_error(
- "getgenerate\n"
- "Returns true or false.");
-
- return (bool)fGenerateBitcoins;
-}
-
-
-Value setgenerate(const Array& params, bool fHelp)
-{
- if (fHelp || params.size() < 1 || params.size() > 2)
- throw runtime_error(
- "setgenerate <generate> [genproclimit]\n"
- "<generate> is true or false to turn generation on or off.\n"
- "Generation is limited to [genproclimit] processors, -1 is unlimited.");
-
- bool fGenerate = true;
- if (params.size() > 0)
- fGenerate = params[0].get_bool();
-
- if (params.size() > 1)
- {
- int nGenProcLimit = params[1].get_int();
- fLimitProcessors = (nGenProcLimit != -1);
- CWalletDB().WriteSetting("fLimitProcessors", fLimitProcessors);
- if (nGenProcLimit != -1)
- CWalletDB().WriteSetting("nLimitProcessors", nLimitProcessors = nGenProcLimit);
- }
-
- GenerateBitcoins(fGenerate);
- return Value::null;
-}
-
-
-Value getinfo(const Array& params, bool fHelp)
-{
- if (fHelp || params.size() != 0)
- throw runtime_error(
- "getinfo");
-
- Object obj;
- obj.push_back(Pair("balance", (double)GetBalance() / (double)COIN));
- obj.push_back(Pair("blocks", (int)nBestHeight + 1));
- obj.push_back(Pair("connections", (int)vNodes.size()));
- obj.push_back(Pair("proxy", (fUseProxy ? addrProxy.ToStringIPPort() : string())));
- obj.push_back(Pair("generate", (bool)fGenerateBitcoins));
- obj.push_back(Pair("genproclimit", (int)(fLimitProcessors ? nLimitProcessors : -1)));
- obj.push_back(Pair("difficulty", (double)GetDifficulty()));
- return obj;
-}
-
-
-Value getnewaddress(const Array& params, bool fHelp)
-{
- if (fHelp || params.size() > 1)
- throw runtime_error(
- "getnewaddress [label]\n"
- "Returns a new bitcoin address for receiving payments. "
- "If [label] is specified (recommended), it is added to the address book "
- "so payments received with the address will be labeled.");
-
- // Parse the label first so we don't generate a key if there's an error
- string strLabel;
- if (params.size() > 0)
- strLabel = params[0].get_str();
-
- // Generate a new key that is added to wallet
- string strAddress = PubKeyToAddress(GenerateNewKey());
-
- SetAddressBookName(strAddress, strLabel);
- return strAddress;
-}
-
-
-Value setlabel(const Array& params, bool fHelp)
-{
- if (fHelp || params.size() < 1 || params.size() > 2)
- throw runtime_error(
- "setlabel <bitcoinaddress> <label>\n"
- "Sets the label associated with the given address.");
-
- string strAddress = params[0].get_str();
- string strLabel;
- if (params.size() > 1)
- strLabel = params[1].get_str();
-
- SetAddressBookName(strAddress, strLabel);
- return Value::null;
-}
-
-
-Value getlabel(const Array& params, bool fHelp)
-{
- if (fHelp || params.size() != 1)
- throw runtime_error(
- "getlabel <bitcoinaddress>\n"
- "Returns the label associated with the given address.");
-
- string strAddress = params[0].get_str();
-
- string strLabel;
- CRITICAL_BLOCK(cs_mapAddressBook)
- {
- map<string, string>::iterator mi = mapAddressBook.find(strAddress);
- if (mi != mapAddressBook.end() && !(*mi).second.empty())
- strLabel = (*mi).second;
- }
- return strLabel;
-}
-
-
-Value getaddressesbylabel(const Array& params, bool fHelp)
-{
- if (fHelp || params.size() != 1)
- throw runtime_error(
- "getaddressesbylabel <label>\n"
- "Returns the list of addresses with the given label.");
-
- string strLabel = params[0].get_str();
-
- // Find all addresses that have the given label
- Array ret;
- CRITICAL_BLOCK(cs_mapAddressBook)
- {
- foreach(const PAIRTYPE(string, string)& item, mapAddressBook)
- {
- const string& strAddress = item.first;
- const string& strName = item.second;
- if (strName == strLabel)
- {
- // We're only adding valid bitcoin addresses and not ip addresses
- CScript scriptPubKey;
- if (scriptPubKey.SetBitcoinAddress(strAddress))
- ret.push_back(strAddress);
- }
- }
- }
- return ret;
-}
-
-
-Value sendtoaddress(const Array& params, bool fHelp)
-{
- if (fHelp || params.size() < 2 || params.size() > 4)
- throw runtime_error(
- "sendtoaddress <bitcoinaddress> <amount> [comment] [comment-to]\n"
- "<amount> is a real and is rounded to the nearest 0.01");
-
- string strAddress = params[0].get_str();
-
- // Amount
- if (params[1].get_real() <= 0.0 || params[1].get_real() > 21000000.0)
- throw runtime_error("Invalid amount");
- int64 nAmount = roundint64(params[1].get_real() * 100.00) * CENT;
-
- // Wallet comments
- CWalletTx wtx;
- if (params.size() > 2 && params[2].type() != null_type && !params[2].get_str().empty())
- wtx.mapValue["message"] = params[2].get_str();
- if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty())
- wtx.mapValue["to"] = params[3].get_str();
-
- string strError = SendMoneyToBitcoinAddress(strAddress, nAmount, wtx);
- if (strError != "")
- throw runtime_error(strError);
- return "sent";
-}
-
-
-Value listtransactions(const Array& params, bool fHelp)
-{
- if (fHelp || params.size() > 2)
- throw runtime_error(
- "listtransactions [count=10] [includegenerated=false]\n"
- "Returns up to [count] most recent transactions.");
-
- int64 nCount = 10;
- if (params.size() > 0)
- nCount = params[0].get_int64();
- bool fGenerated = false;
- if (params.size() > 1)
- fGenerated = params[1].get_bool();
-
- Array ret;
- //// not finished
- ret.push_back("not implemented yet");
- return ret;
-}
-
-
-Value getreceivedbyaddress(const Array& params, bool fHelp)
-{
- if (fHelp || params.size() < 1 || params.size() > 2)
- throw runtime_error(
- "getreceivedbyaddress <bitcoinaddress> [minconf=1]\n"
- "Returns the total amount received by <bitcoinaddress> in transactions with at least [minconf] confirmations.");
-
- // Bitcoin address
- string strAddress = params[0].get_str();
- CScript scriptPubKey;
- if (!scriptPubKey.SetBitcoinAddress(strAddress))
- throw runtime_error("Invalid bitcoin address");
- if (!IsMine(scriptPubKey))
- return (double)0.0;
-
- // Minimum confirmations
- int nMinDepth = 1;
- if (params.size() > 1)
- nMinDepth = params[1].get_int();
-
- // Tally
- int64 nAmount = 0;
- CRITICAL_BLOCK(cs_mapWallet)
- {
- for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
- {
- const CWalletTx& wtx = (*it).second;
- if (wtx.IsCoinBase() || !wtx.IsFinal())
- continue;
-
- foreach(const CTxOut& txout, wtx.vout)
- if (txout.scriptPubKey == scriptPubKey)
- if (wtx.GetDepthInMainChain() >= nMinDepth)
- nAmount += txout.nValue;
- }
- }
-
- return (double)nAmount / (double)COIN;
-}
-
-
-Value getreceivedbylabel(const Array& params, bool fHelp)
-{
- if (fHelp || params.size() < 1 || params.size() > 2)
- throw runtime_error(
- "getreceivedbylabel <label> [minconf=1]\n"
- "Returns the total amount received by addresses with <label> in transactions with at least [minconf] confirmations.");
-
- // Get the set of pub keys that have the label
- string strLabel = params[0].get_str();
- set<CScript> setPubKey;
- CRITICAL_BLOCK(cs_mapAddressBook)
- {
- foreach(const PAIRTYPE(string, string)& item, mapAddressBook)
- {
- const string& strAddress = item.first;
- const string& strName = item.second;
- if (strName == strLabel)
- {
- // We're only counting our own valid bitcoin addresses and not ip addresses
- CScript scriptPubKey;
- if (scriptPubKey.SetBitcoinAddress(strAddress))
- if (IsMine(scriptPubKey))
- setPubKey.insert(scriptPubKey);
- }
- }
- }
-
- // Minimum confirmations
- int nMinDepth = 1;
- if (params.size() > 1)
- nMinDepth = params[1].get_int();
-
- // Tally
- int64 nAmount = 0;
- CRITICAL_BLOCK(cs_mapWallet)
- {
- for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
- {
- const CWalletTx& wtx = (*it).second;
- if (wtx.IsCoinBase() || !wtx.IsFinal())
- continue;
-
- foreach(const CTxOut& txout, wtx.vout)
- if (setPubKey.count(txout.scriptPubKey))
- if (wtx.GetDepthInMainChain() >= nMinDepth)
- nAmount += txout.nValue;
- }
- }
-
- return (double)nAmount / (double)COIN;
-}
-
-
-struct tallyitem
-{
- int64 nAmount;
- int nConf;
- tallyitem()
- {
- nAmount = 0;
- nConf = INT_MAX;
- }
-};
-
-Value ListReceived(const Array& params, bool fByLabels)
-{
- // Minimum confirmations
- int nMinDepth = 1;
- if (params.size() > 0)
- nMinDepth = params[0].get_int();
-
- // Whether to include empty accounts
- bool fIncludeEmpty = false;
- if (params.size() > 1)
- fIncludeEmpty = params[1].get_bool();
-
- // Tally
- map<uint160, tallyitem> mapTally;
- CRITICAL_BLOCK(cs_mapWallet)
- {
- for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
- {
- const CWalletTx& wtx = (*it).second;
- if (wtx.IsCoinBase() || !wtx.IsFinal())
- continue;
-
- int nDepth = wtx.GetDepthInMainChain();
- if (nDepth < nMinDepth)
- continue;
-
- foreach(const CTxOut& txout, wtx.vout)
- {
- // Only counting our own bitcoin addresses and not ip addresses
- uint160 hash160 = txout.scriptPubKey.GetBitcoinAddressHash160();
- if (hash160 == 0 || !mapPubKeys.count(hash160)) // IsMine
- continue;
-
- tallyitem& item = mapTally[hash160];
- item.nAmount += txout.nValue;
- item.nConf = min(item.nConf, nDepth);
- }
- }
- }
-
- // Reply
- Array ret;
- map<string, tallyitem> mapLabelTally;
- CRITICAL_BLOCK(cs_mapAddressBook)
- {
- foreach(const PAIRTYPE(string, string)& item, mapAddressBook)
- {
- const string& strAddress = item.first;
- const string& strLabel = item.second;
- uint160 hash160;
- if (!AddressToHash160(strAddress, hash160))
- continue;
- map<uint160, tallyitem>::iterator it = mapTally.find(hash160);
- if (it == mapTally.end() && !fIncludeEmpty)
- continue;
-
- int64 nAmount = 0;
- int nConf = INT_MAX;
- if (it != mapTally.end())
- {
- nAmount = (*it).second.nAmount;
- nConf = (*it).second.nConf;
- }
-
- if (fByLabels)
- {
- tallyitem& item = mapLabelTally[strLabel];
- item.nAmount += nAmount;
- item.nConf = min(item.nConf, nConf);
- }
- else
- {
- Object obj;
- obj.push_back(Pair("address", strAddress));
- obj.push_back(Pair("label", strLabel));
- obj.push_back(Pair("amount", (double)nAmount / (double)COIN));
- obj.push_back(Pair("confirmations", (nConf == INT_MAX ? 0 : nConf)));
- ret.push_back(obj);
- }
- }
- }
-
- if (fByLabels)
- {
- for (map<string, tallyitem>::iterator it = mapLabelTally.begin(); it != mapLabelTally.end(); ++it)
- {
- int64 nAmount = (*it).second.nAmount;
- int nConf = (*it).second.nConf;
- Object obj;
- obj.push_back(Pair("label", (*it).first));
- obj.push_back(Pair("amount", (double)nAmount / (double)COIN));
- obj.push_back(Pair("confirmations", (nConf == INT_MAX ? 0 : nConf)));
- ret.push_back(obj);
- }
- }
-
- return ret;
-}
-
-Value listreceivedbyaddress(const Array& params, bool fHelp)
-{
- if (fHelp || params.size() > 2)
- throw runtime_error(
- "listreceivedbyaddress [minconf=1] [includeempty=false]\n"
- "[minconf] is the minimum number of confirmations before payments are included.\n"
- "[includeempty] whether to include addresses that haven't received any payments.\n"
- "Returns an array of objects containing:\n"
- " \"address\" : receiving address\n"
- " \"label\" : the label of the receiving address\n"
- " \"amount\" : total amount received by the address\n"
- " \"confirmations\" : number of confirmations of the most recent transaction included");
-
- return ListReceived(params, false);
-}
-
-Value listreceivedbylabel(const Array& params, bool fHelp)
-{
- if (fHelp || params.size() > 2)
- throw runtime_error(
- "listreceivedbylabel [minconf=1] [includeempty=false]\n"
- "[minconf] is the minimum number of confirmations before payments are included.\n"
- "[includeempty] whether to include labels that haven't received any payments.\n"
- "Returns an array of objects containing:\n"
- " \"label\" : the label of the receiving addresses\n"
- " \"amount\" : total amount received by addresses with this label\n"
- " \"confirmations\" : number of confirmations of the most recent transaction included");
-
- return ListReceived(params, true);
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-//
-// Call Table
-//
-
-pair<string, rpcfn_type> pCallTable[] =
-{
- make_pair("help", &help),
- make_pair("stop", &stop),
- make_pair("getblockcount", &getblockcount),
- make_pair("getblocknumber", &getblocknumber),
- make_pair("getconnectioncount", &getconnectioncount),
- make_pair("getdifficulty", &getdifficulty),
- make_pair("getbalance", &getbalance),
- make_pair("getgenerate", &getgenerate),
- make_pair("setgenerate", &setgenerate),
- make_pair("getinfo", &getinfo),
- make_pair("getnewaddress", &getnewaddress),
- make_pair("setlabel", &setlabel),
- make_pair("getlabel", &getlabel),
- make_pair("getaddressesbylabel", &getaddressesbylabel),
- make_pair("sendtoaddress", &sendtoaddress),
- make_pair("listtransactions", &listtransactions),
- make_pair("getamountreceived", &getreceivedbyaddress), // deprecated, renamed to getreceivedbyaddress
- make_pair("getallreceived", &listreceivedbyaddress), // deprecated, renamed to listreceivedbyaddress
- make_pair("getreceivedbyaddress", &getreceivedbyaddress),
- make_pair("getreceivedbylabel", &getreceivedbylabel),
- make_pair("listreceivedbyaddress", &listreceivedbyaddress),
- make_pair("listreceivedbylabel", &listreceivedbylabel),
-};
-map<string, rpcfn_type> mapCallTable(pCallTable, pCallTable + sizeof(pCallTable)/sizeof(pCallTable[0]));
-
-
-
-
-//
-// HTTP protocol
-//
-// This ain't Apache. We're just using HTTP header for the length field
-// and to be compatible with other JSON-RPC implementations.
-//
-
-string HTTPPost(const string& strMsg)
-{
- return strprintf(
- "POST / HTTP/1.1\r\n"
- "User-Agent: json-rpc/1.0\r\n"
- "Host: 127.0.0.1\r\n"
- "Content-Type: application/json\r\n"
- "Content-Length: %d\r\n"
- "Accept: application/json\r\n"
- "\r\n"
- "%s",
- strMsg.size(),
- strMsg.c_str());
-}
-
-string HTTPReply(const string& strMsg, int nStatus=200)
-{
- string strStatus;
- if (nStatus == 200) strStatus = "OK";
- if (nStatus == 500) strStatus = "Internal Server Error";
- return strprintf(
- "HTTP/1.1 %d %s\r\n"
- "Connection: close\r\n"
- "Content-Length: %d\r\n"
- "Content-Type: application/json\r\n"
- "Date: Sat, 08 Jul 2006 12:04:08 GMT\r\n"
- "Server: json-rpc/1.0\r\n"
- "\r\n"
- "%s",
- nStatus,
- strStatus.c_str(),
- strMsg.size(),
- strMsg.c_str());
-}
-
-int ReadHTTPHeader(tcp::iostream& stream)
-{
- int nLen = 0;
- loop
- {
- string str;
- std::getline(stream, str);
- if (str.empty() || str == "\r")
- break;
- if (str.substr(0,15) == "Content-Length:")
- nLen = atoi(str.substr(15));
- }
- return nLen;
-}
-
-inline string ReadHTTP(tcp::iostream& stream)
-{
- // Read header
- int nLen = ReadHTTPHeader(stream);
- if (nLen <= 0)
- return string();
-
- // Read message
- vector<char> vch(nLen);
- stream.read(&vch[0], nLen);
- return string(vch.begin(), vch.end());
-}
-
-
-
-//
-// JSON-RPC protocol
-//
-// http://json-rpc.org/wiki/specification
-// http://www.codeproject.com/KB/recipes/JSON_Spirit.aspx
-//
-
-string JSONRPCRequest(const string& strMethod, const Array& params, const Value& id)
-{
- Object request;
- request.push_back(Pair("method", strMethod));
- request.push_back(Pair("params", params));
- request.push_back(Pair("id", id));
- return write_string(Value(request), false) + "\n";
-}
-
-string JSONRPCReply(const Value& result, const Value& error, const Value& id)
-{
- Object reply;
- if (error.type() != null_type)
- reply.push_back(Pair("result", Value::null));
- else
- reply.push_back(Pair("result", result));
- reply.push_back(Pair("error", error));
- reply.push_back(Pair("id", id));
- return write_string(Value(reply), false) + "\n";
-}
-
-
-
-
-void ThreadRPCServer(void* parg)
-{
- IMPLEMENT_RANDOMIZE_STACK(ThreadRPCServer(parg));
- try
- {
- vnThreadsRunning[4]++;
- ThreadRPCServer2(parg);
- vnThreadsRunning[4]--;
- }
- catch (std::exception& e) {
- vnThreadsRunning[4]--;
- PrintException(&e, "ThreadRPCServer()");
- } catch (...) {
- vnThreadsRunning[4]--;
- PrintException(NULL, "ThreadRPCServer()");
- }
- printf("ThreadRPCServer exiting\n");
-}
-
-void ThreadRPCServer2(void* parg)
-{
- printf("ThreadRPCServer started\n");
-
- // Bind to loopback 127.0.0.1 so the socket can only be accessed locally
- boost::asio::io_service io_service;
- tcp::endpoint endpoint(boost::asio::ip::address_v4::loopback(), 8332);
- tcp::acceptor acceptor(io_service, endpoint);
-
- loop
- {
- // Accept connection
- tcp::iostream stream;
- tcp::endpoint peer;
- vnThreadsRunning[4]--;
- acceptor.accept(*stream.rdbuf(), peer);
- vnThreadsRunning[4]++;
- if (fShutdown)
- return;
-
- // Shouldn't be possible for anyone else to connect, but just in case
- if (peer.address().to_string() != "127.0.0.1")
- continue;
-
- // Receive request
- string strRequest = ReadHTTP(stream);
- printf("ThreadRPCServer request=%s", strRequest.c_str());
-
- // Handle multiple invocations per request
- string::iterator begin = strRequest.begin();
- while (skipspaces(begin), begin != strRequest.end())
- {
- string::iterator prev = begin;
- Value id;
- try
- {
- // Parse request
- Value valRequest;
- if (!read_range(begin, strRequest.end(), valRequest))
- throw runtime_error("Parse error.");
- const Object& request = valRequest.get_obj();
- if (find_value(request, "method").type() != str_type ||
- find_value(request, "params").type() != array_type)
- throw runtime_error("Invalid request.");
-
- string strMethod = find_value(request, "method").get_str();
- const Array& params = find_value(request, "params").get_array();
- id = find_value(request, "id");
-
- // Execute
- map<string, rpcfn_type>::iterator mi = mapCallTable.find(strMethod);
- if (mi == mapCallTable.end())
- throw runtime_error("Method not found.");
- Value result = (*(*mi).second)(params, false);
-
- // Send reply
- string strReply = JSONRPCReply(result, Value::null, id);
- stream << HTTPReply(strReply, 200) << std::flush;
- }
- catch (std::exception& e)
- {
- // Send error reply
- string strReply = JSONRPCReply(Value::null, e.what(), id);
- stream << HTTPReply(strReply, 500) << std::flush;
- }
- if (begin == prev)
- break;
- }
- }
-}
-
-
-
-
-Value CallRPC(const string& strMethod, const Array& params)
-{
- // Connect to localhost
- tcp::iostream stream("127.0.0.1", "8332");
- if (stream.fail())
- throw runtime_error("couldn't connect to server");
-
- // Send request
- string strRequest = JSONRPCRequest(strMethod, params, 1);
- stream << HTTPPost(strRequest) << std::flush;
-
- // Receive reply
- string strReply = ReadHTTP(stream);
- if (strReply.empty())
- throw runtime_error("no response from server");
-
- // Parse reply
- Value valReply;
- if (!read_string(strReply, valReply))
- throw runtime_error("couldn't parse reply from server");
- const Object& reply = valReply.get_obj();
- if (reply.empty())
- throw runtime_error("expected reply to have result, error and id properties");
-
- const Value& result = find_value(reply, "result");
- const Value& error = find_value(reply, "error");
- const Value& id = find_value(reply, "id");
-
- if (error.type() == str_type)
- throw runtime_error(error.get_str());
- else if (error.type() != null_type)
- throw runtime_error(write_string(error, false));
- return result;
-}
-
-
-
-
-template<typename T>
-void ConvertTo(Value& value)
-{
- if (value.type() == str_type)
- {
- // reinterpret string as unquoted json value
- Value value2;
- if (!read_string(value.get_str(), value2))
- throw runtime_error("type mismatch");
- value = value2.get_value<T>();
- }
- else
- {
- value = value.get_value<T>();
- }
-}
-
-int CommandLineRPC(int argc, char *argv[])
-{
- try
- {
- // Check that method exists
- if (argc < 2)
- throw runtime_error("too few parameters");
- string strMethod = argv[1];
- if (!mapCallTable.count(strMethod))
- throw runtime_error(strprintf("unknown command: %s", strMethod.c_str()));
-
- Value result;
- if (argc == 3 && strcmp(argv[2], "-?") == 0)
- {
- // Call help locally, help text is returned in an exception
- try
- {
- map<string, rpcfn_type>::iterator mi = mapCallTable.find(strMethod);
- Array params;
- (*(*mi).second)(params, true);
- }
- catch (std::exception& e)
- {
- result = e.what();
- }
- }
- else
- {
- // Parameters default to strings
- Array params;
- for (int i = 2; i < argc; i++)
- params.push_back(argv[i]);
- int n = params.size();
-
- //
- // Special case non-string parameter types
- //
- if (strMethod == "setgenerate" && n > 0) ConvertTo<bool>(params[0]);
- if (strMethod == "setgenerate" && n > 1) ConvertTo<boost::int64_t>(params[1]);
- if (strMethod == "sendtoaddress" && n > 1) ConvertTo<double>(params[1]);
- if (strMethod == "listtransactions" && n > 0) ConvertTo<boost::int64_t>(params[0]);
- if (strMethod == "listtransactions" && n > 1) ConvertTo<bool>(params[1]);
- if (strMethod == "getamountreceived" && n > 1) ConvertTo<boost::int64_t>(params[1]); // deprecated
- if (strMethod == "getreceivedbyaddress" && n > 1) ConvertTo<boost::int64_t>(params[1]);
- if (strMethod == "getreceivedbylabel" && n > 1) ConvertTo<boost::int64_t>(params[1]);
- if (strMethod == "getallreceived" && n > 0) ConvertTo<boost::int64_t>(params[0]); // deprecated
- if (strMethod == "getallreceived" && n > 1) ConvertTo<bool>(params[1]);
- if (strMethod == "listreceivedbyaddress" && n > 0) ConvertTo<boost::int64_t>(params[0]);
- if (strMethod == "listreceivedbyaddress" && n > 1) ConvertTo<bool>(params[1]);
- if (strMethod == "listreceivedbylabel" && n > 0) ConvertTo<boost::int64_t>(params[0]);
- if (strMethod == "listreceivedbylabel" && n > 1) ConvertTo<bool>(params[1]);
-
- // Execute
- result = CallRPC(strMethod, params);
- }
-
- // Print result
- string strResult = (result.type() == str_type ? result.get_str() : write_string(result, true));
- if (result.type() != null_type)
- {
-#if defined(__WXMSW__) && wxUSE_GUI
- // Windows GUI apps can't print to command line,
- // so settle for a message box yuck
- MyMessageBox(strResult.c_str(), "Bitcoin", wxOK);
-#else
- fprintf(stdout, "%s\n", strResult.c_str());
-#endif
- }
- return 0;
- }
- catch (std::exception& e) {
-#if defined(__WXMSW__) && wxUSE_GUI
- MyMessageBox(strprintf("error: %s\n", e.what()).c_str(), "Bitcoin", wxOK);
-#else
- fprintf(stderr, "error: %s\n", e.what());
-#endif
- } catch (...) {
- PrintException(NULL, "CommandLineRPC()");
- }
- return 1;
-}
-
-
-
-
-#ifdef TEST
-int main(int argc, char *argv[])
-{
-#ifdef _MSC_VER
- // Turn off microsoft heap dump noise
- _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
- _CrtSetReportFile(_CRT_WARN, CreateFile("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0));
-#endif
- setbuf(stdin, NULL);
- setbuf(stdout, NULL);
- setbuf(stderr, NULL);
-
- try
- {
- if (argc >= 2 && string(argv[1]) == "-server")
- {
- printf("server ready\n");
- ThreadRPCServer(NULL);
- }
- else
- {
- return CommandLineRPC(argc, argv);
- }
- }
- catch (std::exception& e) {
- PrintException(&e, "main()");
- } catch (...) {
- PrintException(NULL, "main()");
- }
- return 0;
-}
-#endif
+// Copyright (c) 2010 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +#include "headers.h" +#undef printf +#include <boost/asio.hpp> +#include "json/json_spirit_reader_template.h" +#include "json/json_spirit_writer_template.h" +#include "json/json_spirit_utils.h" +#define printf OutputDebugStringF +// MinGW 3.4.5 gets "fatal error: had to relocate PCH" if the json headers are +// precompiled in headers.h. The problem might be when the pch file goes over +// a certain size around 145MB. If we need access to json_spirit outside this +// file, we could use the compiled json_spirit option. + +using boost::asio::ip::tcp; +using namespace json_spirit; + +void ThreadRPCServer2(void* parg); +typedef Value(*rpcfn_type)(const Array& params, bool fHelp); +extern map<string, rpcfn_type> mapCallTable; + + + + + + + +/// +/// Note: This interface may still be subject to change. +/// + + + +Value help(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "help\n" + "List commands."); + + string strRet; + for (map<string, rpcfn_type>::iterator mi = mapCallTable.begin(); mi != mapCallTable.end(); ++mi) + { + try + { + Array params; + (*(*mi).second)(params, true); + } + catch (std::exception& e) + { + // Help text is returned in an exception + string strHelp = string(e.what()); + if (strHelp.find('\n') != -1) + strHelp = strHelp.substr(0, strHelp.find('\n')); + strRet += strHelp + "\n"; + } + } + strRet = strRet.substr(0,strRet.size()-1); + return strRet; +} + + +Value stop(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "stop\n" + "Stop bitcoin server."); + + // Shutdown will take long enough that the response should get back + CreateThread(Shutdown, NULL); + return "bitcoin server stopping"; +} + + +Value getblockcount(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getblockcount\n" + "Returns the number of blocks in the longest block chain."); + + return nBestHeight + 1; +} + + +Value getblocknumber(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getblocknumber\n" + "Returns the block number of the latest block in the longest block chain."); + + return nBestHeight; +} + + +Value getconnectioncount(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getconnectioncount\n" + "Returns the number of connections to other nodes."); + + return (int)vNodes.size(); +} + + +double GetDifficulty() +{ + // Floating point number that is a multiple of the minimum difficulty, + // minimum difficulty = 1.0. + if (pindexBest == NULL) + return 1.0; + int nShift = 256 - 32 - 31; // to fit in a uint + double dMinimum = (CBigNum().SetCompact(bnProofOfWorkLimit.GetCompact()) >> nShift).getuint(); + double dCurrently = (CBigNum().SetCompact(pindexBest->nBits) >> nShift).getuint(); + return dMinimum / dCurrently; +} + +Value getdifficulty(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getdifficulty\n" + "Returns the proof-of-work difficulty as a multiple of the minimum difficulty."); + + return GetDifficulty(); +} + + +Value getbalance(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getbalance\n" + "Returns the server's available balance."); + + return ((double)GetBalance() / (double)COIN); +} + + +Value getgenerate(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getgenerate\n" + "Returns true or false."); + + return (bool)fGenerateBitcoins; +} + + +Value setgenerate(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 2) + throw runtime_error( + "setgenerate <generate> [genproclimit]\n" + "<generate> is true or false to turn generation on or off.\n" + "Generation is limited to [genproclimit] processors, -1 is unlimited."); + + bool fGenerate = true; + if (params.size() > 0) + fGenerate = params[0].get_bool(); + + if (params.size() > 1) + { + int nGenProcLimit = params[1].get_int(); + fLimitProcessors = (nGenProcLimit != -1); + CWalletDB().WriteSetting("fLimitProcessors", fLimitProcessors); + if (nGenProcLimit != -1) + CWalletDB().WriteSetting("nLimitProcessors", nLimitProcessors = nGenProcLimit); + } + + GenerateBitcoins(fGenerate); + return Value::null; +} + + +Value getinfo(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getinfo"); + + Object obj; + obj.push_back(Pair("balance", (double)GetBalance() / (double)COIN)); + obj.push_back(Pair("blocks", (int)nBestHeight + 1)); + obj.push_back(Pair("connections", (int)vNodes.size())); + obj.push_back(Pair("proxy", (fUseProxy ? addrProxy.ToStringIPPort() : string()))); + obj.push_back(Pair("generate", (bool)fGenerateBitcoins)); + obj.push_back(Pair("genproclimit", (int)(fLimitProcessors ? nLimitProcessors : -1))); + obj.push_back(Pair("difficulty", (double)GetDifficulty())); + return obj; +} + + +Value getnewaddress(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 1) + throw runtime_error( + "getnewaddress [label]\n" + "Returns a new bitcoin address for receiving payments. " + "If [label] is specified (recommended), it is added to the address book " + "so payments received with the address will be labeled."); + + // Parse the label first so we don't generate a key if there's an error + string strLabel; + if (params.size() > 0) + strLabel = params[0].get_str(); + + // Generate a new key that is added to wallet + string strAddress = PubKeyToAddress(GenerateNewKey()); + + SetAddressBookName(strAddress, strLabel); + return strAddress; +} + + +Value setlabel(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 2) + throw runtime_error( + "setlabel <bitcoinaddress> <label>\n" + "Sets the label associated with the given address."); + + string strAddress = params[0].get_str(); + string strLabel; + if (params.size() > 1) + strLabel = params[1].get_str(); + + SetAddressBookName(strAddress, strLabel); + return Value::null; +} + + +Value getlabel(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "getlabel <bitcoinaddress>\n" + "Returns the label associated with the given address."); + + string strAddress = params[0].get_str(); + + string strLabel; + CRITICAL_BLOCK(cs_mapAddressBook) + { + map<string, string>::iterator mi = mapAddressBook.find(strAddress); + if (mi != mapAddressBook.end() && !(*mi).second.empty()) + strLabel = (*mi).second; + } + return strLabel; +} + + +Value getaddressesbylabel(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "getaddressesbylabel <label>\n" + "Returns the list of addresses with the given label."); + + string strLabel = params[0].get_str(); + + // Find all addresses that have the given label + Array ret; + CRITICAL_BLOCK(cs_mapAddressBook) + { + foreach(const PAIRTYPE(string, string)& item, mapAddressBook) + { + const string& strAddress = item.first; + const string& strName = item.second; + if (strName == strLabel) + { + // We're only adding valid bitcoin addresses and not ip addresses + CScript scriptPubKey; + if (scriptPubKey.SetBitcoinAddress(strAddress)) + ret.push_back(strAddress); + } + } + } + return ret; +} + + +Value sendtoaddress(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 2 || params.size() > 4) + throw runtime_error( + "sendtoaddress <bitcoinaddress> <amount> [comment] [comment-to]\n" + "<amount> is a real and is rounded to the nearest 0.01"); + + string strAddress = params[0].get_str(); + + // Amount + if (params[1].get_real() <= 0.0 || params[1].get_real() > 21000000.0) + throw runtime_error("Invalid amount"); + int64 nAmount = roundint64(params[1].get_real() * 100.00) * CENT; + + // Wallet comments + CWalletTx wtx; + if (params.size() > 2 && params[2].type() != null_type && !params[2].get_str().empty()) + wtx.mapValue["message"] = params[2].get_str(); + if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty()) + wtx.mapValue["to"] = params[3].get_str(); + + string strError = SendMoneyToBitcoinAddress(strAddress, nAmount, wtx); + if (strError != "") + throw runtime_error(strError); + return "sent"; +} + + +Value listtransactions(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 2) + throw runtime_error( + "listtransactions [count=10] [includegenerated=false]\n" + "Returns up to [count] most recent transactions."); + + int64 nCount = 10; + if (params.size() > 0) + nCount = params[0].get_int64(); + bool fGenerated = false; + if (params.size() > 1) + fGenerated = params[1].get_bool(); + + Array ret; + //// not finished + ret.push_back("not implemented yet"); + return ret; +} + + +Value getreceivedbyaddress(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 2) + throw runtime_error( + "getreceivedbyaddress <bitcoinaddress> [minconf=1]\n" + "Returns the total amount received by <bitcoinaddress> in transactions with at least [minconf] confirmations."); + + // Bitcoin address + string strAddress = params[0].get_str(); + CScript scriptPubKey; + if (!scriptPubKey.SetBitcoinAddress(strAddress)) + throw runtime_error("Invalid bitcoin address"); + if (!IsMine(scriptPubKey)) + return (double)0.0; + + // Minimum confirmations + int nMinDepth = 1; + if (params.size() > 1) + nMinDepth = params[1].get_int(); + + // Tally + int64 nAmount = 0; + CRITICAL_BLOCK(cs_mapWallet) + { + for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx& wtx = (*it).second; + if (wtx.IsCoinBase() || !wtx.IsFinal()) + continue; + + foreach(const CTxOut& txout, wtx.vout) + if (txout.scriptPubKey == scriptPubKey) + if (wtx.GetDepthInMainChain() >= nMinDepth) + nAmount += txout.nValue; + } + } + + return (double)nAmount / (double)COIN; +} + + +Value getreceivedbylabel(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 2) + throw runtime_error( + "getreceivedbylabel <label> [minconf=1]\n" + "Returns the total amount received by addresses with <label> in transactions with at least [minconf] confirmations."); + + // Get the set of pub keys that have the label + string strLabel = params[0].get_str(); + set<CScript> setPubKey; + CRITICAL_BLOCK(cs_mapAddressBook) + { + foreach(const PAIRTYPE(string, string)& item, mapAddressBook) + { + const string& strAddress = item.first; + const string& strName = item.second; + if (strName == strLabel) + { + // We're only counting our own valid bitcoin addresses and not ip addresses + CScript scriptPubKey; + if (scriptPubKey.SetBitcoinAddress(strAddress)) + if (IsMine(scriptPubKey)) + setPubKey.insert(scriptPubKey); + } + } + } + + // Minimum confirmations + int nMinDepth = 1; + if (params.size() > 1) + nMinDepth = params[1].get_int(); + + // Tally + int64 nAmount = 0; + CRITICAL_BLOCK(cs_mapWallet) + { + for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx& wtx = (*it).second; + if (wtx.IsCoinBase() || !wtx.IsFinal()) + continue; + + foreach(const CTxOut& txout, wtx.vout) + if (setPubKey.count(txout.scriptPubKey)) + if (wtx.GetDepthInMainChain() >= nMinDepth) + nAmount += txout.nValue; + } + } + + return (double)nAmount / (double)COIN; +} + + +struct tallyitem +{ + int64 nAmount; + int nConf; + tallyitem() + { + nAmount = 0; + nConf = INT_MAX; + } +}; + +Value ListReceived(const Array& params, bool fByLabels) +{ + // Minimum confirmations + int nMinDepth = 1; + if (params.size() > 0) + nMinDepth = params[0].get_int(); + + // Whether to include empty accounts + bool fIncludeEmpty = false; + if (params.size() > 1) + fIncludeEmpty = params[1].get_bool(); + + // Tally + map<uint160, tallyitem> mapTally; + CRITICAL_BLOCK(cs_mapWallet) + { + for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx& wtx = (*it).second; + if (wtx.IsCoinBase() || !wtx.IsFinal()) + continue; + + int nDepth = wtx.GetDepthInMainChain(); + if (nDepth < nMinDepth) + continue; + + foreach(const CTxOut& txout, wtx.vout) + { + // Only counting our own bitcoin addresses and not ip addresses + uint160 hash160 = txout.scriptPubKey.GetBitcoinAddressHash160(); + if (hash160 == 0 || !mapPubKeys.count(hash160)) // IsMine + continue; + + tallyitem& item = mapTally[hash160]; + item.nAmount += txout.nValue; + item.nConf = min(item.nConf, nDepth); + } + } + } + + // Reply + Array ret; + map<string, tallyitem> mapLabelTally; + CRITICAL_BLOCK(cs_mapAddressBook) + { + foreach(const PAIRTYPE(string, string)& item, mapAddressBook) + { + const string& strAddress = item.first; + const string& strLabel = item.second; + uint160 hash160; + if (!AddressToHash160(strAddress, hash160)) + continue; + map<uint160, tallyitem>::iterator it = mapTally.find(hash160); + if (it == mapTally.end() && !fIncludeEmpty) + continue; + + int64 nAmount = 0; + int nConf = INT_MAX; + if (it != mapTally.end()) + { + nAmount = (*it).second.nAmount; + nConf = (*it).second.nConf; + } + + if (fByLabels) + { + tallyitem& item = mapLabelTally[strLabel]; + item.nAmount += nAmount; + item.nConf = min(item.nConf, nConf); + } + else + { + Object obj; + obj.push_back(Pair("address", strAddress)); + obj.push_back(Pair("label", strLabel)); + obj.push_back(Pair("amount", (double)nAmount / (double)COIN)); + obj.push_back(Pair("confirmations", (nConf == INT_MAX ? 0 : nConf))); + ret.push_back(obj); + } + } + } + + if (fByLabels) + { + for (map<string, tallyitem>::iterator it = mapLabelTally.begin(); it != mapLabelTally.end(); ++it) + { + int64 nAmount = (*it).second.nAmount; + int nConf = (*it).second.nConf; + Object obj; + obj.push_back(Pair("label", (*it).first)); + obj.push_back(Pair("amount", (double)nAmount / (double)COIN)); + obj.push_back(Pair("confirmations", (nConf == INT_MAX ? 0 : nConf))); + ret.push_back(obj); + } + } + + return ret; +} + +Value listreceivedbyaddress(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 2) + throw runtime_error( + "listreceivedbyaddress [minconf=1] [includeempty=false]\n" + "[minconf] is the minimum number of confirmations before payments are included.\n" + "[includeempty] whether to include addresses that haven't received any payments.\n" + "Returns an array of objects containing:\n" + " \"address\" : receiving address\n" + " \"label\" : the label of the receiving address\n" + " \"amount\" : total amount received by the address\n" + " \"confirmations\" : number of confirmations of the most recent transaction included"); + + return ListReceived(params, false); +} + +Value listreceivedbylabel(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 2) + throw runtime_error( + "listreceivedbylabel [minconf=1] [includeempty=false]\n" + "[minconf] is the minimum number of confirmations before payments are included.\n" + "[includeempty] whether to include labels that haven't received any payments.\n" + "Returns an array of objects containing:\n" + " \"label\" : the label of the receiving addresses\n" + " \"amount\" : total amount received by addresses with this label\n" + " \"confirmations\" : number of confirmations of the most recent transaction included"); + + return ListReceived(params, true); +} + + + + + + + + + + + + + +// +// Call Table +// + +pair<string, rpcfn_type> pCallTable[] = +{ + make_pair("help", &help), + make_pair("stop", &stop), + make_pair("getblockcount", &getblockcount), + make_pair("getblocknumber", &getblocknumber), + make_pair("getconnectioncount", &getconnectioncount), + make_pair("getdifficulty", &getdifficulty), + make_pair("getbalance", &getbalance), + make_pair("getgenerate", &getgenerate), + make_pair("setgenerate", &setgenerate), + make_pair("getinfo", &getinfo), + make_pair("getnewaddress", &getnewaddress), + make_pair("setlabel", &setlabel), + make_pair("getlabel", &getlabel), + make_pair("getaddressesbylabel", &getaddressesbylabel), + make_pair("sendtoaddress", &sendtoaddress), + make_pair("listtransactions", &listtransactions), + make_pair("getamountreceived", &getreceivedbyaddress), // deprecated, renamed to getreceivedbyaddress + make_pair("getallreceived", &listreceivedbyaddress), // deprecated, renamed to listreceivedbyaddress + make_pair("getreceivedbyaddress", &getreceivedbyaddress), + make_pair("getreceivedbylabel", &getreceivedbylabel), + make_pair("listreceivedbyaddress", &listreceivedbyaddress), + make_pair("listreceivedbylabel", &listreceivedbylabel), +}; +map<string, rpcfn_type> mapCallTable(pCallTable, pCallTable + sizeof(pCallTable)/sizeof(pCallTable[0])); + + + + +// +// HTTP protocol +// +// This ain't Apache. We're just using HTTP header for the length field +// and to be compatible with other JSON-RPC implementations. +// + +string HTTPPost(const string& strMsg) +{ + return strprintf( + "POST / HTTP/1.1\r\n" + "User-Agent: json-rpc/1.0\r\n" + "Host: 127.0.0.1\r\n" + "Content-Type: application/json\r\n" + "Content-Length: %d\r\n" + "Accept: application/json\r\n" + "\r\n" + "%s", + strMsg.size(), + strMsg.c_str()); +} + +string HTTPReply(const string& strMsg, int nStatus=200) +{ + string strStatus; + if (nStatus == 200) strStatus = "OK"; + if (nStatus == 500) strStatus = "Internal Server Error"; + return strprintf( + "HTTP/1.1 %d %s\r\n" + "Connection: close\r\n" + "Content-Length: %d\r\n" + "Content-Type: application/json\r\n" + "Date: Sat, 08 Jul 2006 12:04:08 GMT\r\n" + "Server: json-rpc/1.0\r\n" + "\r\n" + "%s", + nStatus, + strStatus.c_str(), + strMsg.size(), + strMsg.c_str()); +} + +int ReadHTTPHeader(tcp::iostream& stream) +{ + int nLen = 0; + loop + { + string str; + std::getline(stream, str); + if (str.empty() || str == "\r") + break; + if (str.substr(0,15) == "Content-Length:") + nLen = atoi(str.substr(15)); + } + return nLen; +} + +inline string ReadHTTP(tcp::iostream& stream) +{ + // Read header + int nLen = ReadHTTPHeader(stream); + if (nLen <= 0) + return string(); + + // Read message + vector<char> vch(nLen); + stream.read(&vch[0], nLen); + return string(vch.begin(), vch.end()); +} + + + +// +// JSON-RPC protocol +// +// http://json-rpc.org/wiki/specification +// http://www.codeproject.com/KB/recipes/JSON_Spirit.aspx +// + +string JSONRPCRequest(const string& strMethod, const Array& params, const Value& id) +{ + Object request; + request.push_back(Pair("method", strMethod)); + request.push_back(Pair("params", params)); + request.push_back(Pair("id", id)); + return write_string(Value(request), false) + "\n"; +} + +string JSONRPCReply(const Value& result, const Value& error, const Value& id) +{ + Object reply; + if (error.type() != null_type) + reply.push_back(Pair("result", Value::null)); + else + reply.push_back(Pair("result", result)); + reply.push_back(Pair("error", error)); + reply.push_back(Pair("id", id)); + return write_string(Value(reply), false) + "\n"; +} + + + + +void ThreadRPCServer(void* parg) +{ + IMPLEMENT_RANDOMIZE_STACK(ThreadRPCServer(parg)); + try + { + vnThreadsRunning[4]++; + ThreadRPCServer2(parg); + vnThreadsRunning[4]--; + } + catch (std::exception& e) { + vnThreadsRunning[4]--; + PrintException(&e, "ThreadRPCServer()"); + } catch (...) { + vnThreadsRunning[4]--; + PrintException(NULL, "ThreadRPCServer()"); + } + printf("ThreadRPCServer exiting\n"); +} + +void ThreadRPCServer2(void* parg) +{ + printf("ThreadRPCServer started\n"); + + // Bind to loopback 127.0.0.1 so the socket can only be accessed locally + boost::asio::io_service io_service; + tcp::endpoint endpoint(boost::asio::ip::address_v4::loopback(), 8332); + tcp::acceptor acceptor(io_service, endpoint); + + loop + { + // Accept connection + tcp::iostream stream; + tcp::endpoint peer; + vnThreadsRunning[4]--; + acceptor.accept(*stream.rdbuf(), peer); + vnThreadsRunning[4]++; + if (fShutdown) + return; + + // Shouldn't be possible for anyone else to connect, but just in case + if (peer.address().to_string() != "127.0.0.1") + continue; + + // Receive request + string strRequest = ReadHTTP(stream); + printf("ThreadRPCServer request=%s", strRequest.c_str()); + + // Handle multiple invocations per request + string::iterator begin = strRequest.begin(); + while (skipspaces(begin), begin != strRequest.end()) + { + string::iterator prev = begin; + Value id; + try + { + // Parse request + Value valRequest; + if (!read_range(begin, strRequest.end(), valRequest)) + throw runtime_error("Parse error."); + const Object& request = valRequest.get_obj(); + if (find_value(request, "method").type() != str_type || + find_value(request, "params").type() != array_type) + throw runtime_error("Invalid request."); + + string strMethod = find_value(request, "method").get_str(); + const Array& params = find_value(request, "params").get_array(); + id = find_value(request, "id"); + + // Execute + map<string, rpcfn_type>::iterator mi = mapCallTable.find(strMethod); + if (mi == mapCallTable.end()) + throw runtime_error("Method not found."); + Value result = (*(*mi).second)(params, false); + + // Send reply + string strReply = JSONRPCReply(result, Value::null, id); + stream << HTTPReply(strReply, 200) << std::flush; + } + catch (std::exception& e) + { + // Send error reply + string strReply = JSONRPCReply(Value::null, e.what(), id); + stream << HTTPReply(strReply, 500) << std::flush; + } + if (begin == prev) + break; + } + } +} + + + + +Value CallRPC(const string& strMethod, const Array& params) +{ + // Connect to localhost + tcp::iostream stream("127.0.0.1", "8332"); + if (stream.fail()) + throw runtime_error("couldn't connect to server"); + + // Send request + string strRequest = JSONRPCRequest(strMethod, params, 1); + stream << HTTPPost(strRequest) << std::flush; + + // Receive reply + string strReply = ReadHTTP(stream); + if (strReply.empty()) + throw runtime_error("no response from server"); + + // Parse reply + Value valReply; + if (!read_string(strReply, valReply)) + throw runtime_error("couldn't parse reply from server"); + const Object& reply = valReply.get_obj(); + if (reply.empty()) + throw runtime_error("expected reply to have result, error and id properties"); + + const Value& result = find_value(reply, "result"); + const Value& error = find_value(reply, "error"); + const Value& id = find_value(reply, "id"); + + if (error.type() == str_type) + throw runtime_error(error.get_str()); + else if (error.type() != null_type) + throw runtime_error(write_string(error, false)); + return result; +} + + + + +template<typename T> +void ConvertTo(Value& value) +{ + if (value.type() == str_type) + { + // reinterpret string as unquoted json value + Value value2; + if (!read_string(value.get_str(), value2)) + throw runtime_error("type mismatch"); + value = value2.get_value<T>(); + } + else + { + value = value.get_value<T>(); + } +} + +int CommandLineRPC(int argc, char *argv[]) +{ + try + { + // Check that method exists + if (argc < 2) + throw runtime_error("too few parameters"); + string strMethod = argv[1]; + if (!mapCallTable.count(strMethod)) + throw runtime_error(strprintf("unknown command: %s", strMethod.c_str())); + + Value result; + if (argc == 3 && strcmp(argv[2], "-?") == 0) + { + // Call help locally, help text is returned in an exception + try + { + map<string, rpcfn_type>::iterator mi = mapCallTable.find(strMethod); + Array params; + (*(*mi).second)(params, true); + } + catch (std::exception& e) + { + result = e.what(); + } + } + else + { + // Parameters default to strings + Array params; + for (int i = 2; i < argc; i++) + params.push_back(argv[i]); + int n = params.size(); + + // + // Special case non-string parameter types + // + if (strMethod == "setgenerate" && n > 0) ConvertTo<bool>(params[0]); + if (strMethod == "setgenerate" && n > 1) ConvertTo<boost::int64_t>(params[1]); + if (strMethod == "sendtoaddress" && n > 1) ConvertTo<double>(params[1]); + if (strMethod == "listtransactions" && n > 0) ConvertTo<boost::int64_t>(params[0]); + if (strMethod == "listtransactions" && n > 1) ConvertTo<bool>(params[1]); + if (strMethod == "getamountreceived" && n > 1) ConvertTo<boost::int64_t>(params[1]); // deprecated + if (strMethod == "getreceivedbyaddress" && n > 1) ConvertTo<boost::int64_t>(params[1]); + if (strMethod == "getreceivedbylabel" && n > 1) ConvertTo<boost::int64_t>(params[1]); + if (strMethod == "getallreceived" && n > 0) ConvertTo<boost::int64_t>(params[0]); // deprecated + if (strMethod == "getallreceived" && n > 1) ConvertTo<bool>(params[1]); + if (strMethod == "listreceivedbyaddress" && n > 0) ConvertTo<boost::int64_t>(params[0]); + if (strMethod == "listreceivedbyaddress" && n > 1) ConvertTo<bool>(params[1]); + if (strMethod == "listreceivedbylabel" && n > 0) ConvertTo<boost::int64_t>(params[0]); + if (strMethod == "listreceivedbylabel" && n > 1) ConvertTo<bool>(params[1]); + + // Execute + result = CallRPC(strMethod, params); + } + + // Print result + string strResult = (result.type() == str_type ? result.get_str() : write_string(result, true)); + if (result.type() != null_type) + { +#if defined(__WXMSW__) && wxUSE_GUI + // Windows GUI apps can't print to command line, + // so settle for a message box yuck + MyMessageBox(strResult.c_str(), "Bitcoin", wxOK); +#else + fprintf(stdout, "%s\n", strResult.c_str()); +#endif + } + return 0; + } + catch (std::exception& e) { +#if defined(__WXMSW__) && wxUSE_GUI + MyMessageBox(strprintf("error: %s\n", e.what()).c_str(), "Bitcoin", wxOK); +#else + fprintf(stderr, "error: %s\n", e.what()); +#endif + } catch (...) { + PrintException(NULL, "CommandLineRPC()"); + } + return 1; +} + + + + +#ifdef TEST +int main(int argc, char *argv[]) +{ +#ifdef _MSC_VER + // Turn off microsoft heap dump noise + _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); + _CrtSetReportFile(_CRT_WARN, CreateFile("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); +#endif + setbuf(stdin, NULL); + setbuf(stdout, NULL); + setbuf(stderr, NULL); + + try + { + if (argc >= 2 && string(argv[1]) == "-server") + { + printf("server ready\n"); + ThreadRPCServer(NULL); + } + else + { + return CommandLineRPC(argc, argv); + } + } + catch (std::exception& e) { + PrintException(&e, "main()"); + } catch (...) { + PrintException(NULL, "main()"); + } + return 0; +} +#endif @@ -1,6 +1,6 @@ -// Copyright (c) 2010 Satoshi Nakamoto
-// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
-
-void ThreadRPCServer(void* parg);
-int CommandLineRPC(int argc, char *argv[]);
+// Copyright (c) 2010 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +void ThreadRPCServer(void* parg); +int CommandLineRPC(int argc, char *argv[]); diff --git a/script.cpp b/script.cpp index 98f5afd5a7..fc4feaad81 100644 --- a/script.cpp +++ b/script.cpp @@ -1,1134 +1,1134 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
-
-#include "headers.h"
-
-bool CheckSig(vector<unsigned char> vchSig, vector<unsigned char> vchPubKey, CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType);
-
-
-
-typedef vector<unsigned char> valtype;
-static const valtype vchFalse(0);
-static const valtype vchZero(0);
-static const valtype vchTrue(1, 1);
-static const CBigNum bnZero(0);
-static const CBigNum bnOne(1);
-static const CBigNum bnFalse(0);
-static const CBigNum bnTrue(1);
-
-
-bool CastToBool(const valtype& vch)
-{
- return (CBigNum(vch) != bnZero);
-}
-
-void MakeSameSize(valtype& vch1, valtype& vch2)
-{
- // Lengthen the shorter one
- if (vch1.size() < vch2.size())
- vch1.resize(vch2.size(), 0);
- if (vch2.size() < vch1.size())
- vch2.resize(vch1.size(), 0);
-}
-
-
-
-//
-// Script is a stack machine (like Forth) that evaluates a predicate
-// returning a bool indicating valid or not. There are no loops.
-//
-#define stacktop(i) (stack.at(stack.size()+(i)))
-#define altstacktop(i) (altstack.at(altstack.size()+(i)))
-
-bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType,
- vector<vector<unsigned char> >* pvStackRet)
-{
- CAutoBN_CTX pctx;
- CScript::const_iterator pc = script.begin();
- CScript::const_iterator pend = script.end();
- CScript::const_iterator pbegincodehash = script.begin();
- vector<bool> vfExec;
- vector<valtype> stack;
- vector<valtype> altstack;
- if (pvStackRet)
- pvStackRet->clear();
-
-
- while (pc < pend)
- {
- bool fExec = !count(vfExec.begin(), vfExec.end(), false);
-
- //
- // Read instruction
- //
- opcodetype opcode;
- valtype vchPushValue;
- if (!script.GetOp(pc, opcode, vchPushValue))
- return false;
-
- if (fExec && opcode <= OP_PUSHDATA4)
- stack.push_back(vchPushValue);
- else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF))
- switch (opcode)
- {
- //
- // Push value
- //
- case OP_1NEGATE:
- case OP_1:
- case OP_2:
- case OP_3:
- case OP_4:
- case OP_5:
- case OP_6:
- case OP_7:
- case OP_8:
- case OP_9:
- case OP_10:
- case OP_11:
- case OP_12:
- case OP_13:
- case OP_14:
- case OP_15:
- case OP_16:
- {
- // ( -- value)
- CBigNum bn((int)opcode - (int)(OP_1 - 1));
- stack.push_back(bn.getvch());
- }
- break;
-
-
- //
- // Control
- //
- case OP_NOP:
- break;
-
- case OP_VER:
- {
- CBigNum bn(VERSION);
- stack.push_back(bn.getvch());
- }
- break;
-
- case OP_IF:
- case OP_NOTIF:
- case OP_VERIF:
- case OP_VERNOTIF:
- {
- // <expression> if [statements] [else [statements]] endif
- bool fValue = false;
- if (fExec)
- {
- if (stack.size() < 1)
- return false;
- valtype& vch = stacktop(-1);
- if (opcode == OP_VERIF || opcode == OP_VERNOTIF)
- fValue = (CBigNum(VERSION) >= CBigNum(vch));
- else
- fValue = CastToBool(vch);
- if (opcode == OP_NOTIF || opcode == OP_VERNOTIF)
- fValue = !fValue;
- stack.pop_back();
- }
- vfExec.push_back(fValue);
- }
- break;
-
- case OP_ELSE:
- {
- if (vfExec.empty())
- return false;
- vfExec.back() = !vfExec.back();
- }
- break;
-
- case OP_ENDIF:
- {
- if (vfExec.empty())
- return false;
- vfExec.pop_back();
- }
- break;
-
- case OP_VERIFY:
- {
- // (true -- ) or
- // (false -- false) and return
- if (stack.size() < 1)
- return false;
- bool fValue = CastToBool(stacktop(-1));
- if (fValue)
- stack.pop_back();
- else
- pc = pend;
- }
- break;
-
- case OP_RETURN:
- {
- pc = pend;
- }
- break;
-
-
- //
- // Stack ops
- //
- case OP_TOALTSTACK:
- {
- if (stack.size() < 1)
- return false;
- altstack.push_back(stacktop(-1));
- stack.pop_back();
- }
- break;
-
- case OP_FROMALTSTACK:
- {
- if (altstack.size() < 1)
- return false;
- stack.push_back(altstacktop(-1));
- altstack.pop_back();
- }
- break;
-
- case OP_2DROP:
- {
- // (x1 x2 -- )
- stack.pop_back();
- stack.pop_back();
- }
- break;
-
- case OP_2DUP:
- {
- // (x1 x2 -- x1 x2 x1 x2)
- if (stack.size() < 2)
- return false;
- valtype vch1 = stacktop(-2);
- valtype vch2 = stacktop(-1);
- stack.push_back(vch1);
- stack.push_back(vch2);
- }
- break;
-
- case OP_3DUP:
- {
- // (x1 x2 x3 -- x1 x2 x3 x1 x2 x3)
- if (stack.size() < 3)
- return false;
- valtype vch1 = stacktop(-3);
- valtype vch2 = stacktop(-2);
- valtype vch3 = stacktop(-1);
- stack.push_back(vch1);
- stack.push_back(vch2);
- stack.push_back(vch3);
- }
- break;
-
- case OP_2OVER:
- {
- // (x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2)
- if (stack.size() < 4)
- return false;
- valtype vch1 = stacktop(-4);
- valtype vch2 = stacktop(-3);
- stack.push_back(vch1);
- stack.push_back(vch2);
- }
- break;
-
- case OP_2ROT:
- {
- // (x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2)
- if (stack.size() < 6)
- return false;
- valtype vch1 = stacktop(-6);
- valtype vch2 = stacktop(-5);
- stack.erase(stack.end()-6, stack.end()-4);
- stack.push_back(vch1);
- stack.push_back(vch2);
- }
- break;
-
- case OP_2SWAP:
- {
- // (x1 x2 x3 x4 -- x3 x4 x1 x2)
- if (stack.size() < 4)
- return false;
- swap(stacktop(-4), stacktop(-2));
- swap(stacktop(-3), stacktop(-1));
- }
- break;
-
- case OP_IFDUP:
- {
- // (x - 0 | x x)
- if (stack.size() < 1)
- return false;
- valtype vch = stacktop(-1);
- if (CastToBool(vch))
- stack.push_back(vch);
- }
- break;
-
- case OP_DEPTH:
- {
- // -- stacksize
- CBigNum bn(stack.size());
- stack.push_back(bn.getvch());
- }
- break;
-
- case OP_DROP:
- {
- // (x -- )
- if (stack.size() < 1)
- return false;
- stack.pop_back();
- }
- break;
-
- case OP_DUP:
- {
- // (x -- x x)
- if (stack.size() < 1)
- return false;
- valtype vch = stacktop(-1);
- stack.push_back(vch);
- }
- break;
-
- case OP_NIP:
- {
- // (x1 x2 -- x2)
- if (stack.size() < 2)
- return false;
- stack.erase(stack.end() - 2);
- }
- break;
-
- case OP_OVER:
- {
- // (x1 x2 -- x1 x2 x1)
- if (stack.size() < 2)
- return false;
- valtype vch = stacktop(-2);
- stack.push_back(vch);
- }
- break;
-
- case OP_PICK:
- case OP_ROLL:
- {
- // (xn ... x2 x1 x0 n - xn ... x2 x1 x0 xn)
- // (xn ... x2 x1 x0 n - ... x2 x1 x0 xn)
- if (stack.size() < 2)
- return false;
- int n = CBigNum(stacktop(-1)).getint();
- stack.pop_back();
- if (n < 0 || n >= stack.size())
- return false;
- valtype vch = stacktop(-n-1);
- if (opcode == OP_ROLL)
- stack.erase(stack.end()-n-1);
- stack.push_back(vch);
- }
- break;
-
- case OP_ROT:
- {
- // (x1 x2 x3 -- x2 x3 x1)
- // x2 x1 x3 after first swap
- // x2 x3 x1 after second swap
- if (stack.size() < 3)
- return false;
- swap(stacktop(-3), stacktop(-2));
- swap(stacktop(-2), stacktop(-1));
- }
- break;
-
- case OP_SWAP:
- {
- // (x1 x2 -- x2 x1)
- if (stack.size() < 2)
- return false;
- swap(stacktop(-2), stacktop(-1));
- }
- break;
-
- case OP_TUCK:
- {
- // (x1 x2 -- x2 x1 x2)
- if (stack.size() < 2)
- return false;
- valtype vch = stacktop(-1);
- stack.insert(stack.end()-2, vch);
- }
- break;
-
-
- //
- // Splice ops
- //
- case OP_CAT:
- {
- // (x1 x2 -- out)
- if (stack.size() < 2)
- return false;
- valtype& vch1 = stacktop(-2);
- valtype& vch2 = stacktop(-1);
- vch1.insert(vch1.end(), vch2.begin(), vch2.end());
- stack.pop_back();
- }
- break;
-
- case OP_SUBSTR:
- {
- // (in begin size -- out)
- if (stack.size() < 3)
- return false;
- valtype& vch = stacktop(-3);
- int nBegin = CBigNum(stacktop(-2)).getint();
- int nEnd = nBegin + CBigNum(stacktop(-1)).getint();
- if (nBegin < 0 || nEnd < nBegin)
- return false;
- if (nBegin > vch.size())
- nBegin = vch.size();
- if (nEnd > vch.size())
- nEnd = vch.size();
- vch.erase(vch.begin() + nEnd, vch.end());
- vch.erase(vch.begin(), vch.begin() + nBegin);
- stack.pop_back();
- stack.pop_back();
- }
- break;
-
- case OP_LEFT:
- case OP_RIGHT:
- {
- // (in size -- out)
- if (stack.size() < 2)
- return false;
- valtype& vch = stacktop(-2);
- int nSize = CBigNum(stacktop(-1)).getint();
- if (nSize < 0)
- return false;
- if (nSize > vch.size())
- nSize = vch.size();
- if (opcode == OP_LEFT)
- vch.erase(vch.begin() + nSize, vch.end());
- else
- vch.erase(vch.begin(), vch.end() - nSize);
- stack.pop_back();
- }
- break;
-
- case OP_SIZE:
- {
- // (in -- in size)
- if (stack.size() < 1)
- return false;
- CBigNum bn(stacktop(-1).size());
- stack.push_back(bn.getvch());
- }
- break;
-
-
- //
- // Bitwise logic
- //
- case OP_INVERT:
- {
- // (in - out)
- if (stack.size() < 1)
- return false;
- valtype& vch = stacktop(-1);
- for (int i = 0; i < vch.size(); i++)
- vch[i] = ~vch[i];
- }
- break;
-
- case OP_AND:
- case OP_OR:
- case OP_XOR:
- {
- // (x1 x2 - out)
- if (stack.size() < 2)
- return false;
- valtype& vch1 = stacktop(-2);
- valtype& vch2 = stacktop(-1);
- MakeSameSize(vch1, vch2);
- if (opcode == OP_AND)
- {
- for (int i = 0; i < vch1.size(); i++)
- vch1[i] &= vch2[i];
- }
- else if (opcode == OP_OR)
- {
- for (int i = 0; i < vch1.size(); i++)
- vch1[i] |= vch2[i];
- }
- else if (opcode == OP_XOR)
- {
- for (int i = 0; i < vch1.size(); i++)
- vch1[i] ^= vch2[i];
- }
- stack.pop_back();
- }
- break;
-
- case OP_EQUAL:
- case OP_EQUALVERIFY:
- //case OP_NOTEQUAL: // use OP_NUMNOTEQUAL
- {
- // (x1 x2 - bool)
- if (stack.size() < 2)
- return false;
- valtype& vch1 = stacktop(-2);
- valtype& vch2 = stacktop(-1);
- bool fEqual = (vch1 == vch2);
- // OP_NOTEQUAL is disabled because it would be too easy to say
- // something like n != 1 and have some wiseguy pass in 1 with extra
- // zero bytes after it (numerically, 0x01 == 0x0001 == 0x000001)
- //if (opcode == OP_NOTEQUAL)
- // fEqual = !fEqual;
- stack.pop_back();
- stack.pop_back();
- stack.push_back(fEqual ? vchTrue : vchFalse);
- if (opcode == OP_EQUALVERIFY)
- {
- if (fEqual)
- stack.pop_back();
- else
- pc = pend;
- }
- }
- break;
-
-
- //
- // Numeric
- //
- case OP_1ADD:
- case OP_1SUB:
- case OP_2MUL:
- case OP_2DIV:
- case OP_NEGATE:
- case OP_ABS:
- case OP_NOT:
- case OP_0NOTEQUAL:
- {
- // (in -- out)
- if (stack.size() < 1)
- return false;
- CBigNum bn(stacktop(-1));
- switch (opcode)
- {
- case OP_1ADD: bn += bnOne; break;
- case OP_1SUB: bn -= bnOne; break;
- case OP_2MUL: bn <<= 1; break;
- case OP_2DIV: bn >>= 1; break;
- case OP_NEGATE: bn = -bn; break;
- case OP_ABS: if (bn < bnZero) bn = -bn; break;
- case OP_NOT: bn = (bn == bnZero); break;
- case OP_0NOTEQUAL: bn = (bn != bnZero); break;
- }
- stack.pop_back();
- stack.push_back(bn.getvch());
- }
- break;
-
- case OP_ADD:
- case OP_SUB:
- case OP_MUL:
- case OP_DIV:
- case OP_MOD:
- case OP_LSHIFT:
- case OP_RSHIFT:
- case OP_BOOLAND:
- case OP_BOOLOR:
- case OP_NUMEQUAL:
- case OP_NUMEQUALVERIFY:
- case OP_NUMNOTEQUAL:
- case OP_LESSTHAN:
- case OP_GREATERTHAN:
- case OP_LESSTHANOREQUAL:
- case OP_GREATERTHANOREQUAL:
- case OP_MIN:
- case OP_MAX:
- {
- // (x1 x2 -- out)
- if (stack.size() < 2)
- return false;
- CBigNum bn1(stacktop(-2));
- CBigNum bn2(stacktop(-1));
- CBigNum bn;
- switch (opcode)
- {
- case OP_ADD:
- bn = bn1 + bn2;
- break;
-
- case OP_SUB:
- bn = bn1 - bn2;
- break;
-
- case OP_MUL:
- if (!BN_mul(&bn, &bn1, &bn2, pctx))
- return false;
- break;
-
- case OP_DIV:
- if (!BN_div(&bn, NULL, &bn1, &bn2, pctx))
- return false;
- break;
-
- case OP_MOD:
- if (!BN_mod(&bn, &bn1, &bn2, pctx))
- return false;
- break;
-
- case OP_LSHIFT:
- if (bn2 < bnZero)
- return false;
- bn = bn1 << bn2.getulong();
- break;
-
- case OP_RSHIFT:
- if (bn2 < bnZero)
- return false;
- bn = bn1 >> bn2.getulong();
- break;
-
- case OP_BOOLAND: bn = (bn1 != bnZero && bn2 != bnZero); break;
- case OP_BOOLOR: bn = (bn1 != bnZero || bn2 != bnZero); break;
- case OP_NUMEQUAL: bn = (bn1 == bn2); break;
- case OP_NUMEQUALVERIFY: bn = (bn1 == bn2); break;
- case OP_NUMNOTEQUAL: bn = (bn1 != bn2); break;
- case OP_LESSTHAN: bn = (bn1 < bn2); break;
- case OP_GREATERTHAN: bn = (bn1 > bn2); break;
- case OP_LESSTHANOREQUAL: bn = (bn1 <= bn2); break;
- case OP_GREATERTHANOREQUAL: bn = (bn1 >= bn2); break;
- case OP_MIN: bn = (bn1 < bn2 ? bn1 : bn2); break;
- case OP_MAX: bn = (bn1 > bn2 ? bn1 : bn2); break;
- }
- stack.pop_back();
- stack.pop_back();
- stack.push_back(bn.getvch());
-
- if (opcode == OP_NUMEQUALVERIFY)
- {
- if (CastToBool(stacktop(-1)))
- stack.pop_back();
- else
- pc = pend;
- }
- }
- break;
-
- case OP_WITHIN:
- {
- // (x min max -- out)
- if (stack.size() < 3)
- return false;
- CBigNum bn1(stacktop(-3));
- CBigNum bn2(stacktop(-2));
- CBigNum bn3(stacktop(-1));
- bool fValue = (bn2 <= bn1 && bn1 < bn3);
- stack.pop_back();
- stack.pop_back();
- stack.pop_back();
- stack.push_back(fValue ? vchTrue : vchFalse);
- }
- break;
-
-
- //
- // Crypto
- //
- case OP_RIPEMD160:
- case OP_SHA1:
- case OP_SHA256:
- case OP_HASH160:
- case OP_HASH256:
- {
- // (in -- hash)
- if (stack.size() < 1)
- return false;
- valtype& vch = stacktop(-1);
- valtype vchHash((opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160) ? 20 : 32);
- if (opcode == OP_RIPEMD160)
- RIPEMD160(&vch[0], vch.size(), &vchHash[0]);
- else if (opcode == OP_SHA1)
- SHA1(&vch[0], vch.size(), &vchHash[0]);
- else if (opcode == OP_SHA256)
- SHA256(&vch[0], vch.size(), &vchHash[0]);
- else if (opcode == OP_HASH160)
- {
- uint160 hash160 = Hash160(vch);
- memcpy(&vchHash[0], &hash160, sizeof(hash160));
- }
- else if (opcode == OP_HASH256)
- {
- uint256 hash = Hash(vch.begin(), vch.end());
- memcpy(&vchHash[0], &hash, sizeof(hash));
- }
- stack.pop_back();
- stack.push_back(vchHash);
- }
- break;
-
- case OP_CODESEPARATOR:
- {
- // Hash starts after the code separator
- pbegincodehash = pc;
- }
- break;
-
- case OP_CHECKSIG:
- case OP_CHECKSIGVERIFY:
- {
- // (sig pubkey -- bool)
- if (stack.size() < 2)
- return false;
-
- valtype& vchSig = stacktop(-2);
- valtype& vchPubKey = stacktop(-1);
-
- ////// debug print
- //PrintHex(vchSig.begin(), vchSig.end(), "sig: %s\n");
- //PrintHex(vchPubKey.begin(), vchPubKey.end(), "pubkey: %s\n");
-
- // Subset of script starting at the most recent codeseparator
- CScript scriptCode(pbegincodehash, pend);
-
- // Drop the signature, since there's no way for a signature to sign itself
- scriptCode.FindAndDelete(CScript(vchSig));
-
- bool fSuccess = CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType);
-
- stack.pop_back();
- stack.pop_back();
- stack.push_back(fSuccess ? vchTrue : vchFalse);
- if (opcode == OP_CHECKSIGVERIFY)
- {
- if (fSuccess)
- stack.pop_back();
- else
- pc = pend;
- }
- }
- break;
-
- case OP_CHECKMULTISIG:
- case OP_CHECKMULTISIGVERIFY:
- {
- // ([sig ...] num_of_signatures [pubkey ...] num_of_pubkeys -- bool)
-
- int i = 1;
- if (stack.size() < i)
- return false;
-
- int nKeysCount = CBigNum(stacktop(-i)).getint();
- if (nKeysCount < 0)
- return false;
- int ikey = ++i;
- i += nKeysCount;
- if (stack.size() < i)
- return false;
-
- int nSigsCount = CBigNum(stacktop(-i)).getint();
- if (nSigsCount < 0 || nSigsCount > nKeysCount)
- return false;
- int isig = ++i;
- i += nSigsCount;
- if (stack.size() < i)
- return false;
-
- // Subset of script starting at the most recent codeseparator
- CScript scriptCode(pbegincodehash, pend);
-
- // Drop the signatures, since there's no way for a signature to sign itself
- for (int k = 0; k < nSigsCount; k++)
- {
- valtype& vchSig = stacktop(-isig-k);
- scriptCode.FindAndDelete(CScript(vchSig));
- }
-
- bool fSuccess = true;
- while (fSuccess && nSigsCount > 0)
- {
- valtype& vchSig = stacktop(-isig);
- valtype& vchPubKey = stacktop(-ikey);
-
- // Check signature
- if (CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType))
- {
- isig++;
- nSigsCount--;
- }
- ikey++;
- nKeysCount--;
-
- // If there are more signatures left than keys left,
- // then too many signatures have failed
- if (nSigsCount > nKeysCount)
- fSuccess = false;
- }
-
- while (i-- > 0)
- stack.pop_back();
- stack.push_back(fSuccess ? vchTrue : vchFalse);
-
- if (opcode == OP_CHECKMULTISIGVERIFY)
- {
- if (fSuccess)
- stack.pop_back();
- else
- pc = pend;
- }
- }
- break;
-
- default:
- return false;
- }
- }
-
-
- if (pvStackRet)
- *pvStackRet = stack;
- return (stack.empty() ? false : CastToBool(stack.back()));
-}
-
-#undef top
-
-
-
-
-
-
-
-
-
-uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType)
-{
- if (nIn >= txTo.vin.size())
- {
- printf("ERROR: SignatureHash() : nIn=%d out of range\n", nIn);
- return 1;
- }
- CTransaction txTmp(txTo);
-
- // In case concatenating two scripts ends up with two codeseparators,
- // or an extra one at the end, this prevents all those possible incompatibilities.
- scriptCode.FindAndDelete(CScript(OP_CODESEPARATOR));
-
- // Blank out other inputs' signatures
- for (int i = 0; i < txTmp.vin.size(); i++)
- txTmp.vin[i].scriptSig = CScript();
- txTmp.vin[nIn].scriptSig = scriptCode;
-
- // Blank out some of the outputs
- if ((nHashType & 0x1f) == SIGHASH_NONE)
- {
- // Wildcard payee
- txTmp.vout.clear();
-
- // Let the others update at will
- for (int i = 0; i < txTmp.vin.size(); i++)
- if (i != nIn)
- txTmp.vin[i].nSequence = 0;
- }
- else if ((nHashType & 0x1f) == SIGHASH_SINGLE)
- {
- // Only lockin the txout payee at same index as txin
- unsigned int nOut = nIn;
- if (nOut >= txTmp.vout.size())
- {
- printf("ERROR: SignatureHash() : nOut=%d out of range\n", nOut);
- return 1;
- }
- txTmp.vout.resize(nOut+1);
- for (int i = 0; i < nOut; i++)
- txTmp.vout[i].SetNull();
-
- // Let the others update at will
- for (int i = 0; i < txTmp.vin.size(); i++)
- if (i != nIn)
- txTmp.vin[i].nSequence = 0;
- }
-
- // Blank out other inputs completely, not recommended for open transactions
- if (nHashType & SIGHASH_ANYONECANPAY)
- {
- txTmp.vin[0] = txTmp.vin[nIn];
- txTmp.vin.resize(1);
- }
-
- // Serialize and hash
- CDataStream ss(SER_GETHASH);
- ss.reserve(10000);
- ss << txTmp << nHashType;
- return Hash(ss.begin(), ss.end());
-}
-
-
-bool CheckSig(vector<unsigned char> vchSig, vector<unsigned char> vchPubKey, CScript scriptCode,
- const CTransaction& txTo, unsigned int nIn, int nHashType)
-{
- CKey key;
- if (!key.SetPubKey(vchPubKey))
- return false;
-
- // 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;
- vchSig.pop_back();
-
- if (key.Verify(SignatureHash(scriptCode, txTo, nIn, nHashType), vchSig))
- return true;
-
- return false;
-}
-
-
-
-
-
-
-
-
-
-
-bool Solver(const CScript& scriptPubKey, vector<pair<opcodetype, valtype> >& vSolutionRet)
-{
- // Templates
- static vector<CScript> vTemplates;
- if (vTemplates.empty())
- {
- // Standard tx, sender provides pubkey, receiver adds signature
- vTemplates.push_back(CScript() << OP_PUBKEY << OP_CHECKSIG);
-
- // Bitcoin address tx, sender provides hash of pubkey, receiver provides signature and pubkey
- vTemplates.push_back(CScript() << OP_DUP << OP_HASH160 << OP_PUBKEYHASH << OP_EQUALVERIFY << OP_CHECKSIG);
- }
-
- // Scan templates
- const CScript& script1 = scriptPubKey;
- foreach(const CScript& script2, vTemplates)
- {
- vSolutionRet.clear();
- opcodetype opcode1, opcode2;
- vector<unsigned char> vch1, vch2;
-
- // Compare
- CScript::const_iterator pc1 = script1.begin();
- CScript::const_iterator pc2 = script2.begin();
- loop
- {
- bool f1 = script1.GetOp(pc1, opcode1, vch1);
- bool f2 = script2.GetOp(pc2, opcode2, vch2);
- if (!f1 && !f2)
- {
- // Success
- reverse(vSolutionRet.begin(), vSolutionRet.end());
- return true;
- }
- else if (f1 != f2)
- {
- break;
- }
- else if (opcode2 == OP_PUBKEY)
- {
- if (vch1.size() <= sizeof(uint256))
- break;
- vSolutionRet.push_back(make_pair(opcode2, vch1));
- }
- else if (opcode2 == OP_PUBKEYHASH)
- {
- if (vch1.size() != sizeof(uint160))
- break;
- vSolutionRet.push_back(make_pair(opcode2, vch1));
- }
- else if (opcode1 != opcode2)
- {
- break;
- }
- }
- }
-
- vSolutionRet.clear();
- return false;
-}
-
-
-bool Solver(const CScript& scriptPubKey, uint256 hash, int nHashType, CScript& scriptSigRet)
-{
- scriptSigRet.clear();
-
- vector<pair<opcodetype, valtype> > vSolution;
- if (!Solver(scriptPubKey, vSolution))
- return false;
-
- // Compile solution
- CRITICAL_BLOCK(cs_mapKeys)
- {
- foreach(PAIRTYPE(opcodetype, valtype)& item, vSolution)
- {
- if (item.first == OP_PUBKEY)
- {
- // Sign
- const valtype& vchPubKey = item.second;
- if (!mapKeys.count(vchPubKey))
- return false;
- if (hash != 0)
- {
- vector<unsigned char> vchSig;
- if (!CKey::Sign(mapKeys[vchPubKey], hash, vchSig))
- return false;
- vchSig.push_back((unsigned char)nHashType);
- scriptSigRet << vchSig;
- }
- }
- else if (item.first == OP_PUBKEYHASH)
- {
- // Sign and give pubkey
- map<uint160, valtype>::iterator mi = mapPubKeys.find(uint160(item.second));
- if (mi == mapPubKeys.end())
- return false;
- const vector<unsigned char>& vchPubKey = (*mi).second;
- if (!mapKeys.count(vchPubKey))
- return false;
- if (hash != 0)
- {
- vector<unsigned char> vchSig;
- if (!CKey::Sign(mapKeys[vchPubKey], hash, vchSig))
- return false;
- vchSig.push_back((unsigned char)nHashType);
- scriptSigRet << vchSig << vchPubKey;
- }
- }
- }
- }
-
- return true;
-}
-
-
-bool IsMine(const CScript& scriptPubKey)
-{
- CScript scriptSig;
- return Solver(scriptPubKey, 0, 0, scriptSig);
-}
-
-
-bool ExtractPubKey(const CScript& scriptPubKey, bool fMineOnly, vector<unsigned char>& vchPubKeyRet)
-{
- vchPubKeyRet.clear();
-
- vector<pair<opcodetype, valtype> > vSolution;
- if (!Solver(scriptPubKey, vSolution))
- return false;
-
- CRITICAL_BLOCK(cs_mapKeys)
- {
- foreach(PAIRTYPE(opcodetype, valtype)& item, vSolution)
- {
- valtype vchPubKey;
- if (item.first == OP_PUBKEY)
- {
- vchPubKey = item.second;
- }
- else if (item.first == OP_PUBKEYHASH)
- {
- map<uint160, valtype>::iterator mi = mapPubKeys.find(uint160(item.second));
- if (mi == mapPubKeys.end())
- continue;
- vchPubKey = (*mi).second;
- }
- if (!fMineOnly || mapKeys.count(vchPubKey))
- {
- vchPubKeyRet = vchPubKey;
- return true;
- }
- }
- }
- return false;
-}
-
-
-bool ExtractHash160(const CScript& scriptPubKey, uint160& hash160Ret)
-{
- hash160Ret = 0;
-
- vector<pair<opcodetype, valtype> > vSolution;
- if (!Solver(scriptPubKey, vSolution))
- return false;
-
- foreach(PAIRTYPE(opcodetype, valtype)& item, vSolution)
- {
- if (item.first == OP_PUBKEYHASH)
- {
- hash160Ret = uint160(item.second);
- return true;
- }
- }
- return false;
-}
-
-
-bool SignSignature(const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType, CScript scriptPrereq)
-{
- assert(nIn < txTo.vin.size());
- CTxIn& txin = txTo.vin[nIn];
- assert(txin.prevout.n < txFrom.vout.size());
- const CTxOut& txout = txFrom.vout[txin.prevout.n];
-
- // Leave out the signature from the hash, since a signature can't sign itself.
- // The checksig op will also drop the signatures from its hash.
- uint256 hash = SignatureHash(scriptPrereq + txout.scriptPubKey, txTo, nIn, nHashType);
-
- if (!Solver(txout.scriptPubKey, hash, nHashType, txin.scriptSig))
- return false;
-
- txin.scriptSig = scriptPrereq + txin.scriptSig;
-
- // Test solution
- if (scriptPrereq.empty())
- if (!EvalScript(txin.scriptSig + CScript(OP_CODESEPARATOR) + txout.scriptPubKey, txTo, nIn))
- return false;
-
- return true;
-}
-
-
-bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, int nHashType)
-{
- assert(nIn < txTo.vin.size());
- const CTxIn& txin = txTo.vin[nIn];
- if (txin.prevout.n >= txFrom.vout.size())
- return false;
- const CTxOut& txout = txFrom.vout[txin.prevout.n];
-
- if (txin.prevout.hash != txFrom.GetHash())
- return false;
-
- if (!EvalScript(txin.scriptSig + CScript(OP_CODESEPARATOR) + txout.scriptPubKey, txTo, nIn, nHashType))
- return false;
-
- // Anytime a signature is successfully verified, it's proof the outpoint is spent,
- // so lets update the wallet spent flag if it doesn't know due to wallet.dat being
- // restored from backup or the user making copies of wallet.dat.
- WalletUpdateSpent(txin.prevout);
-
- return true;
-}
+// Copyright (c) 2009-2010 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +#include "headers.h" + +bool CheckSig(vector<unsigned char> vchSig, vector<unsigned char> vchPubKey, CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); + + + +typedef vector<unsigned char> valtype; +static const valtype vchFalse(0); +static const valtype vchZero(0); +static const valtype vchTrue(1, 1); +static const CBigNum bnZero(0); +static const CBigNum bnOne(1); +static const CBigNum bnFalse(0); +static const CBigNum bnTrue(1); + + +bool CastToBool(const valtype& vch) +{ + return (CBigNum(vch) != bnZero); +} + +void MakeSameSize(valtype& vch1, valtype& vch2) +{ + // Lengthen the shorter one + if (vch1.size() < vch2.size()) + vch1.resize(vch2.size(), 0); + if (vch2.size() < vch1.size()) + vch2.resize(vch1.size(), 0); +} + + + +// +// Script is a stack machine (like Forth) that evaluates a predicate +// returning a bool indicating valid or not. There are no loops. +// +#define stacktop(i) (stack.at(stack.size()+(i))) +#define altstacktop(i) (altstack.at(altstack.size()+(i))) + +bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType, + vector<vector<unsigned char> >* pvStackRet) +{ + CAutoBN_CTX pctx; + CScript::const_iterator pc = script.begin(); + CScript::const_iterator pend = script.end(); + CScript::const_iterator pbegincodehash = script.begin(); + vector<bool> vfExec; + vector<valtype> stack; + vector<valtype> altstack; + if (pvStackRet) + pvStackRet->clear(); + + + while (pc < pend) + { + bool fExec = !count(vfExec.begin(), vfExec.end(), false); + + // + // Read instruction + // + opcodetype opcode; + valtype vchPushValue; + if (!script.GetOp(pc, opcode, vchPushValue)) + return false; + + if (fExec && opcode <= OP_PUSHDATA4) + stack.push_back(vchPushValue); + else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF)) + switch (opcode) + { + // + // Push value + // + case OP_1NEGATE: + case OP_1: + case OP_2: + case OP_3: + case OP_4: + case OP_5: + case OP_6: + case OP_7: + case OP_8: + case OP_9: + case OP_10: + case OP_11: + case OP_12: + case OP_13: + case OP_14: + case OP_15: + case OP_16: + { + // ( -- value) + CBigNum bn((int)opcode - (int)(OP_1 - 1)); + stack.push_back(bn.getvch()); + } + break; + + + // + // Control + // + case OP_NOP: + break; + + case OP_VER: + { + CBigNum bn(VERSION); + stack.push_back(bn.getvch()); + } + break; + + case OP_IF: + case OP_NOTIF: + case OP_VERIF: + case OP_VERNOTIF: + { + // <expression> if [statements] [else [statements]] endif + bool fValue = false; + if (fExec) + { + if (stack.size() < 1) + return false; + valtype& vch = stacktop(-1); + if (opcode == OP_VERIF || opcode == OP_VERNOTIF) + fValue = (CBigNum(VERSION) >= CBigNum(vch)); + else + fValue = CastToBool(vch); + if (opcode == OP_NOTIF || opcode == OP_VERNOTIF) + fValue = !fValue; + stack.pop_back(); + } + vfExec.push_back(fValue); + } + break; + + case OP_ELSE: + { + if (vfExec.empty()) + return false; + vfExec.back() = !vfExec.back(); + } + break; + + case OP_ENDIF: + { + if (vfExec.empty()) + return false; + vfExec.pop_back(); + } + break; + + case OP_VERIFY: + { + // (true -- ) or + // (false -- false) and return + if (stack.size() < 1) + return false; + bool fValue = CastToBool(stacktop(-1)); + if (fValue) + stack.pop_back(); + else + pc = pend; + } + break; + + case OP_RETURN: + { + pc = pend; + } + break; + + + // + // Stack ops + // + case OP_TOALTSTACK: + { + if (stack.size() < 1) + return false; + altstack.push_back(stacktop(-1)); + stack.pop_back(); + } + break; + + case OP_FROMALTSTACK: + { + if (altstack.size() < 1) + return false; + stack.push_back(altstacktop(-1)); + altstack.pop_back(); + } + break; + + case OP_2DROP: + { + // (x1 x2 -- ) + stack.pop_back(); + stack.pop_back(); + } + break; + + case OP_2DUP: + { + // (x1 x2 -- x1 x2 x1 x2) + if (stack.size() < 2) + return false; + valtype vch1 = stacktop(-2); + valtype vch2 = stacktop(-1); + stack.push_back(vch1); + stack.push_back(vch2); + } + break; + + case OP_3DUP: + { + // (x1 x2 x3 -- x1 x2 x3 x1 x2 x3) + if (stack.size() < 3) + return false; + valtype vch1 = stacktop(-3); + valtype vch2 = stacktop(-2); + valtype vch3 = stacktop(-1); + stack.push_back(vch1); + stack.push_back(vch2); + stack.push_back(vch3); + } + break; + + case OP_2OVER: + { + // (x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2) + if (stack.size() < 4) + return false; + valtype vch1 = stacktop(-4); + valtype vch2 = stacktop(-3); + stack.push_back(vch1); + stack.push_back(vch2); + } + break; + + case OP_2ROT: + { + // (x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2) + if (stack.size() < 6) + return false; + valtype vch1 = stacktop(-6); + valtype vch2 = stacktop(-5); + stack.erase(stack.end()-6, stack.end()-4); + stack.push_back(vch1); + stack.push_back(vch2); + } + break; + + case OP_2SWAP: + { + // (x1 x2 x3 x4 -- x3 x4 x1 x2) + if (stack.size() < 4) + return false; + swap(stacktop(-4), stacktop(-2)); + swap(stacktop(-3), stacktop(-1)); + } + break; + + case OP_IFDUP: + { + // (x - 0 | x x) + if (stack.size() < 1) + return false; + valtype vch = stacktop(-1); + if (CastToBool(vch)) + stack.push_back(vch); + } + break; + + case OP_DEPTH: + { + // -- stacksize + CBigNum bn(stack.size()); + stack.push_back(bn.getvch()); + } + break; + + case OP_DROP: + { + // (x -- ) + if (stack.size() < 1) + return false; + stack.pop_back(); + } + break; + + case OP_DUP: + { + // (x -- x x) + if (stack.size() < 1) + return false; + valtype vch = stacktop(-1); + stack.push_back(vch); + } + break; + + case OP_NIP: + { + // (x1 x2 -- x2) + if (stack.size() < 2) + return false; + stack.erase(stack.end() - 2); + } + break; + + case OP_OVER: + { + // (x1 x2 -- x1 x2 x1) + if (stack.size() < 2) + return false; + valtype vch = stacktop(-2); + stack.push_back(vch); + } + break; + + case OP_PICK: + case OP_ROLL: + { + // (xn ... x2 x1 x0 n - xn ... x2 x1 x0 xn) + // (xn ... x2 x1 x0 n - ... x2 x1 x0 xn) + if (stack.size() < 2) + return false; + int n = CBigNum(stacktop(-1)).getint(); + stack.pop_back(); + if (n < 0 || n >= stack.size()) + return false; + valtype vch = stacktop(-n-1); + if (opcode == OP_ROLL) + stack.erase(stack.end()-n-1); + stack.push_back(vch); + } + break; + + case OP_ROT: + { + // (x1 x2 x3 -- x2 x3 x1) + // x2 x1 x3 after first swap + // x2 x3 x1 after second swap + if (stack.size() < 3) + return false; + swap(stacktop(-3), stacktop(-2)); + swap(stacktop(-2), stacktop(-1)); + } + break; + + case OP_SWAP: + { + // (x1 x2 -- x2 x1) + if (stack.size() < 2) + return false; + swap(stacktop(-2), stacktop(-1)); + } + break; + + case OP_TUCK: + { + // (x1 x2 -- x2 x1 x2) + if (stack.size() < 2) + return false; + valtype vch = stacktop(-1); + stack.insert(stack.end()-2, vch); + } + break; + + + // + // Splice ops + // + case OP_CAT: + { + // (x1 x2 -- out) + if (stack.size() < 2) + return false; + valtype& vch1 = stacktop(-2); + valtype& vch2 = stacktop(-1); + vch1.insert(vch1.end(), vch2.begin(), vch2.end()); + stack.pop_back(); + } + break; + + case OP_SUBSTR: + { + // (in begin size -- out) + if (stack.size() < 3) + return false; + valtype& vch = stacktop(-3); + int nBegin = CBigNum(stacktop(-2)).getint(); + int nEnd = nBegin + CBigNum(stacktop(-1)).getint(); + if (nBegin < 0 || nEnd < nBegin) + return false; + if (nBegin > vch.size()) + nBegin = vch.size(); + if (nEnd > vch.size()) + nEnd = vch.size(); + vch.erase(vch.begin() + nEnd, vch.end()); + vch.erase(vch.begin(), vch.begin() + nBegin); + stack.pop_back(); + stack.pop_back(); + } + break; + + case OP_LEFT: + case OP_RIGHT: + { + // (in size -- out) + if (stack.size() < 2) + return false; + valtype& vch = stacktop(-2); + int nSize = CBigNum(stacktop(-1)).getint(); + if (nSize < 0) + return false; + if (nSize > vch.size()) + nSize = vch.size(); + if (opcode == OP_LEFT) + vch.erase(vch.begin() + nSize, vch.end()); + else + vch.erase(vch.begin(), vch.end() - nSize); + stack.pop_back(); + } + break; + + case OP_SIZE: + { + // (in -- in size) + if (stack.size() < 1) + return false; + CBigNum bn(stacktop(-1).size()); + stack.push_back(bn.getvch()); + } + break; + + + // + // Bitwise logic + // + case OP_INVERT: + { + // (in - out) + if (stack.size() < 1) + return false; + valtype& vch = stacktop(-1); + for (int i = 0; i < vch.size(); i++) + vch[i] = ~vch[i]; + } + break; + + case OP_AND: + case OP_OR: + case OP_XOR: + { + // (x1 x2 - out) + if (stack.size() < 2) + return false; + valtype& vch1 = stacktop(-2); + valtype& vch2 = stacktop(-1); + MakeSameSize(vch1, vch2); + if (opcode == OP_AND) + { + for (int i = 0; i < vch1.size(); i++) + vch1[i] &= vch2[i]; + } + else if (opcode == OP_OR) + { + for (int i = 0; i < vch1.size(); i++) + vch1[i] |= vch2[i]; + } + else if (opcode == OP_XOR) + { + for (int i = 0; i < vch1.size(); i++) + vch1[i] ^= vch2[i]; + } + stack.pop_back(); + } + break; + + case OP_EQUAL: + case OP_EQUALVERIFY: + //case OP_NOTEQUAL: // use OP_NUMNOTEQUAL + { + // (x1 x2 - bool) + if (stack.size() < 2) + return false; + valtype& vch1 = stacktop(-2); + valtype& vch2 = stacktop(-1); + bool fEqual = (vch1 == vch2); + // OP_NOTEQUAL is disabled because it would be too easy to say + // something like n != 1 and have some wiseguy pass in 1 with extra + // zero bytes after it (numerically, 0x01 == 0x0001 == 0x000001) + //if (opcode == OP_NOTEQUAL) + // fEqual = !fEqual; + stack.pop_back(); + stack.pop_back(); + stack.push_back(fEqual ? vchTrue : vchFalse); + if (opcode == OP_EQUALVERIFY) + { + if (fEqual) + stack.pop_back(); + else + pc = pend; + } + } + break; + + + // + // Numeric + // + case OP_1ADD: + case OP_1SUB: + case OP_2MUL: + case OP_2DIV: + case OP_NEGATE: + case OP_ABS: + case OP_NOT: + case OP_0NOTEQUAL: + { + // (in -- out) + if (stack.size() < 1) + return false; + CBigNum bn(stacktop(-1)); + switch (opcode) + { + case OP_1ADD: bn += bnOne; break; + case OP_1SUB: bn -= bnOne; break; + case OP_2MUL: bn <<= 1; break; + case OP_2DIV: bn >>= 1; break; + case OP_NEGATE: bn = -bn; break; + case OP_ABS: if (bn < bnZero) bn = -bn; break; + case OP_NOT: bn = (bn == bnZero); break; + case OP_0NOTEQUAL: bn = (bn != bnZero); break; + } + stack.pop_back(); + stack.push_back(bn.getvch()); + } + break; + + case OP_ADD: + case OP_SUB: + case OP_MUL: + case OP_DIV: + case OP_MOD: + case OP_LSHIFT: + case OP_RSHIFT: + case OP_BOOLAND: + case OP_BOOLOR: + case OP_NUMEQUAL: + case OP_NUMEQUALVERIFY: + case OP_NUMNOTEQUAL: + case OP_LESSTHAN: + case OP_GREATERTHAN: + case OP_LESSTHANOREQUAL: + case OP_GREATERTHANOREQUAL: + case OP_MIN: + case OP_MAX: + { + // (x1 x2 -- out) + if (stack.size() < 2) + return false; + CBigNum bn1(stacktop(-2)); + CBigNum bn2(stacktop(-1)); + CBigNum bn; + switch (opcode) + { + case OP_ADD: + bn = bn1 + bn2; + break; + + case OP_SUB: + bn = bn1 - bn2; + break; + + case OP_MUL: + if (!BN_mul(&bn, &bn1, &bn2, pctx)) + return false; + break; + + case OP_DIV: + if (!BN_div(&bn, NULL, &bn1, &bn2, pctx)) + return false; + break; + + case OP_MOD: + if (!BN_mod(&bn, &bn1, &bn2, pctx)) + return false; + break; + + case OP_LSHIFT: + if (bn2 < bnZero) + return false; + bn = bn1 << bn2.getulong(); + break; + + case OP_RSHIFT: + if (bn2 < bnZero) + return false; + bn = bn1 >> bn2.getulong(); + break; + + case OP_BOOLAND: bn = (bn1 != bnZero && bn2 != bnZero); break; + case OP_BOOLOR: bn = (bn1 != bnZero || bn2 != bnZero); break; + case OP_NUMEQUAL: bn = (bn1 == bn2); break; + case OP_NUMEQUALVERIFY: bn = (bn1 == bn2); break; + case OP_NUMNOTEQUAL: bn = (bn1 != bn2); break; + case OP_LESSTHAN: bn = (bn1 < bn2); break; + case OP_GREATERTHAN: bn = (bn1 > bn2); break; + case OP_LESSTHANOREQUAL: bn = (bn1 <= bn2); break; + case OP_GREATERTHANOREQUAL: bn = (bn1 >= bn2); break; + case OP_MIN: bn = (bn1 < bn2 ? bn1 : bn2); break; + case OP_MAX: bn = (bn1 > bn2 ? bn1 : bn2); break; + } + stack.pop_back(); + stack.pop_back(); + stack.push_back(bn.getvch()); + + if (opcode == OP_NUMEQUALVERIFY) + { + if (CastToBool(stacktop(-1))) + stack.pop_back(); + else + pc = pend; + } + } + break; + + case OP_WITHIN: + { + // (x min max -- out) + if (stack.size() < 3) + return false; + CBigNum bn1(stacktop(-3)); + CBigNum bn2(stacktop(-2)); + CBigNum bn3(stacktop(-1)); + bool fValue = (bn2 <= bn1 && bn1 < bn3); + stack.pop_back(); + stack.pop_back(); + stack.pop_back(); + stack.push_back(fValue ? vchTrue : vchFalse); + } + break; + + + // + // Crypto + // + case OP_RIPEMD160: + case OP_SHA1: + case OP_SHA256: + case OP_HASH160: + case OP_HASH256: + { + // (in -- hash) + if (stack.size() < 1) + return false; + valtype& vch = stacktop(-1); + valtype vchHash((opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160) ? 20 : 32); + if (opcode == OP_RIPEMD160) + RIPEMD160(&vch[0], vch.size(), &vchHash[0]); + else if (opcode == OP_SHA1) + SHA1(&vch[0], vch.size(), &vchHash[0]); + else if (opcode == OP_SHA256) + SHA256(&vch[0], vch.size(), &vchHash[0]); + else if (opcode == OP_HASH160) + { + uint160 hash160 = Hash160(vch); + memcpy(&vchHash[0], &hash160, sizeof(hash160)); + } + else if (opcode == OP_HASH256) + { + uint256 hash = Hash(vch.begin(), vch.end()); + memcpy(&vchHash[0], &hash, sizeof(hash)); + } + stack.pop_back(); + stack.push_back(vchHash); + } + break; + + case OP_CODESEPARATOR: + { + // Hash starts after the code separator + pbegincodehash = pc; + } + break; + + case OP_CHECKSIG: + case OP_CHECKSIGVERIFY: + { + // (sig pubkey -- bool) + if (stack.size() < 2) + return false; + + valtype& vchSig = stacktop(-2); + valtype& vchPubKey = stacktop(-1); + + ////// debug print + //PrintHex(vchSig.begin(), vchSig.end(), "sig: %s\n"); + //PrintHex(vchPubKey.begin(), vchPubKey.end(), "pubkey: %s\n"); + + // Subset of script starting at the most recent codeseparator + CScript scriptCode(pbegincodehash, pend); + + // Drop the signature, since there's no way for a signature to sign itself + scriptCode.FindAndDelete(CScript(vchSig)); + + bool fSuccess = CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType); + + stack.pop_back(); + stack.pop_back(); + stack.push_back(fSuccess ? vchTrue : vchFalse); + if (opcode == OP_CHECKSIGVERIFY) + { + if (fSuccess) + stack.pop_back(); + else + pc = pend; + } + } + break; + + case OP_CHECKMULTISIG: + case OP_CHECKMULTISIGVERIFY: + { + // ([sig ...] num_of_signatures [pubkey ...] num_of_pubkeys -- bool) + + int i = 1; + if (stack.size() < i) + return false; + + int nKeysCount = CBigNum(stacktop(-i)).getint(); + if (nKeysCount < 0) + return false; + int ikey = ++i; + i += nKeysCount; + if (stack.size() < i) + return false; + + int nSigsCount = CBigNum(stacktop(-i)).getint(); + if (nSigsCount < 0 || nSigsCount > nKeysCount) + return false; + int isig = ++i; + i += nSigsCount; + if (stack.size() < i) + return false; + + // Subset of script starting at the most recent codeseparator + CScript scriptCode(pbegincodehash, pend); + + // Drop the signatures, since there's no way for a signature to sign itself + for (int k = 0; k < nSigsCount; k++) + { + valtype& vchSig = stacktop(-isig-k); + scriptCode.FindAndDelete(CScript(vchSig)); + } + + bool fSuccess = true; + while (fSuccess && nSigsCount > 0) + { + valtype& vchSig = stacktop(-isig); + valtype& vchPubKey = stacktop(-ikey); + + // Check signature + if (CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType)) + { + isig++; + nSigsCount--; + } + ikey++; + nKeysCount--; + + // If there are more signatures left than keys left, + // then too many signatures have failed + if (nSigsCount > nKeysCount) + fSuccess = false; + } + + while (i-- > 0) + stack.pop_back(); + stack.push_back(fSuccess ? vchTrue : vchFalse); + + if (opcode == OP_CHECKMULTISIGVERIFY) + { + if (fSuccess) + stack.pop_back(); + else + pc = pend; + } + } + break; + + default: + return false; + } + } + + + if (pvStackRet) + *pvStackRet = stack; + return (stack.empty() ? false : CastToBool(stack.back())); +} + +#undef top + + + + + + + + + +uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType) +{ + if (nIn >= txTo.vin.size()) + { + printf("ERROR: SignatureHash() : nIn=%d out of range\n", nIn); + return 1; + } + CTransaction txTmp(txTo); + + // In case concatenating two scripts ends up with two codeseparators, + // or an extra one at the end, this prevents all those possible incompatibilities. + scriptCode.FindAndDelete(CScript(OP_CODESEPARATOR)); + + // Blank out other inputs' signatures + for (int i = 0; i < txTmp.vin.size(); i++) + txTmp.vin[i].scriptSig = CScript(); + txTmp.vin[nIn].scriptSig = scriptCode; + + // Blank out some of the outputs + if ((nHashType & 0x1f) == SIGHASH_NONE) + { + // Wildcard payee + txTmp.vout.clear(); + + // Let the others update at will + for (int i = 0; i < txTmp.vin.size(); i++) + if (i != nIn) + txTmp.vin[i].nSequence = 0; + } + else if ((nHashType & 0x1f) == SIGHASH_SINGLE) + { + // Only lockin the txout payee at same index as txin + unsigned int nOut = nIn; + if (nOut >= txTmp.vout.size()) + { + printf("ERROR: SignatureHash() : nOut=%d out of range\n", nOut); + return 1; + } + txTmp.vout.resize(nOut+1); + for (int i = 0; i < nOut; i++) + txTmp.vout[i].SetNull(); + + // Let the others update at will + for (int i = 0; i < txTmp.vin.size(); i++) + if (i != nIn) + txTmp.vin[i].nSequence = 0; + } + + // Blank out other inputs completely, not recommended for open transactions + if (nHashType & SIGHASH_ANYONECANPAY) + { + txTmp.vin[0] = txTmp.vin[nIn]; + txTmp.vin.resize(1); + } + + // Serialize and hash + CDataStream ss(SER_GETHASH); + ss.reserve(10000); + ss << txTmp << nHashType; + return Hash(ss.begin(), ss.end()); +} + + +bool CheckSig(vector<unsigned char> vchSig, vector<unsigned char> vchPubKey, CScript scriptCode, + const CTransaction& txTo, unsigned int nIn, int nHashType) +{ + CKey key; + if (!key.SetPubKey(vchPubKey)) + return false; + + // 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; + vchSig.pop_back(); + + if (key.Verify(SignatureHash(scriptCode, txTo, nIn, nHashType), vchSig)) + return true; + + return false; +} + + + + + + + + + + +bool Solver(const CScript& scriptPubKey, vector<pair<opcodetype, valtype> >& vSolutionRet) +{ + // Templates + static vector<CScript> vTemplates; + if (vTemplates.empty()) + { + // Standard tx, sender provides pubkey, receiver adds signature + vTemplates.push_back(CScript() << OP_PUBKEY << OP_CHECKSIG); + + // Bitcoin address tx, sender provides hash of pubkey, receiver provides signature and pubkey + vTemplates.push_back(CScript() << OP_DUP << OP_HASH160 << OP_PUBKEYHASH << OP_EQUALVERIFY << OP_CHECKSIG); + } + + // Scan templates + const CScript& script1 = scriptPubKey; + foreach(const CScript& script2, vTemplates) + { + vSolutionRet.clear(); + opcodetype opcode1, opcode2; + vector<unsigned char> vch1, vch2; + + // Compare + CScript::const_iterator pc1 = script1.begin(); + CScript::const_iterator pc2 = script2.begin(); + loop + { + bool f1 = script1.GetOp(pc1, opcode1, vch1); + bool f2 = script2.GetOp(pc2, opcode2, vch2); + if (!f1 && !f2) + { + // Success + reverse(vSolutionRet.begin(), vSolutionRet.end()); + return true; + } + else if (f1 != f2) + { + break; + } + else if (opcode2 == OP_PUBKEY) + { + if (vch1.size() <= sizeof(uint256)) + break; + vSolutionRet.push_back(make_pair(opcode2, vch1)); + } + else if (opcode2 == OP_PUBKEYHASH) + { + if (vch1.size() != sizeof(uint160)) + break; + vSolutionRet.push_back(make_pair(opcode2, vch1)); + } + else if (opcode1 != opcode2) + { + break; + } + } + } + + vSolutionRet.clear(); + return false; +} + + +bool Solver(const CScript& scriptPubKey, uint256 hash, int nHashType, CScript& scriptSigRet) +{ + scriptSigRet.clear(); + + vector<pair<opcodetype, valtype> > vSolution; + if (!Solver(scriptPubKey, vSolution)) + return false; + + // Compile solution + CRITICAL_BLOCK(cs_mapKeys) + { + foreach(PAIRTYPE(opcodetype, valtype)& item, vSolution) + { + if (item.first == OP_PUBKEY) + { + // Sign + const valtype& vchPubKey = item.second; + if (!mapKeys.count(vchPubKey)) + return false; + if (hash != 0) + { + vector<unsigned char> vchSig; + if (!CKey::Sign(mapKeys[vchPubKey], hash, vchSig)) + return false; + vchSig.push_back((unsigned char)nHashType); + scriptSigRet << vchSig; + } + } + else if (item.first == OP_PUBKEYHASH) + { + // Sign and give pubkey + map<uint160, valtype>::iterator mi = mapPubKeys.find(uint160(item.second)); + if (mi == mapPubKeys.end()) + return false; + const vector<unsigned char>& vchPubKey = (*mi).second; + if (!mapKeys.count(vchPubKey)) + return false; + if (hash != 0) + { + vector<unsigned char> vchSig; + if (!CKey::Sign(mapKeys[vchPubKey], hash, vchSig)) + return false; + vchSig.push_back((unsigned char)nHashType); + scriptSigRet << vchSig << vchPubKey; + } + } + } + } + + return true; +} + + +bool IsMine(const CScript& scriptPubKey) +{ + CScript scriptSig; + return Solver(scriptPubKey, 0, 0, scriptSig); +} + + +bool ExtractPubKey(const CScript& scriptPubKey, bool fMineOnly, vector<unsigned char>& vchPubKeyRet) +{ + vchPubKeyRet.clear(); + + vector<pair<opcodetype, valtype> > vSolution; + if (!Solver(scriptPubKey, vSolution)) + return false; + + CRITICAL_BLOCK(cs_mapKeys) + { + foreach(PAIRTYPE(opcodetype, valtype)& item, vSolution) + { + valtype vchPubKey; + if (item.first == OP_PUBKEY) + { + vchPubKey = item.second; + } + else if (item.first == OP_PUBKEYHASH) + { + map<uint160, valtype>::iterator mi = mapPubKeys.find(uint160(item.second)); + if (mi == mapPubKeys.end()) + continue; + vchPubKey = (*mi).second; + } + if (!fMineOnly || mapKeys.count(vchPubKey)) + { + vchPubKeyRet = vchPubKey; + return true; + } + } + } + return false; +} + + +bool ExtractHash160(const CScript& scriptPubKey, uint160& hash160Ret) +{ + hash160Ret = 0; + + vector<pair<opcodetype, valtype> > vSolution; + if (!Solver(scriptPubKey, vSolution)) + return false; + + foreach(PAIRTYPE(opcodetype, valtype)& item, vSolution) + { + if (item.first == OP_PUBKEYHASH) + { + hash160Ret = uint160(item.second); + return true; + } + } + return false; +} + + +bool SignSignature(const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType, CScript scriptPrereq) +{ + assert(nIn < txTo.vin.size()); + CTxIn& txin = txTo.vin[nIn]; + assert(txin.prevout.n < txFrom.vout.size()); + const CTxOut& txout = txFrom.vout[txin.prevout.n]; + + // Leave out the signature from the hash, since a signature can't sign itself. + // The checksig op will also drop the signatures from its hash. + uint256 hash = SignatureHash(scriptPrereq + txout.scriptPubKey, txTo, nIn, nHashType); + + if (!Solver(txout.scriptPubKey, hash, nHashType, txin.scriptSig)) + return false; + + txin.scriptSig = scriptPrereq + txin.scriptSig; + + // Test solution + if (scriptPrereq.empty()) + if (!EvalScript(txin.scriptSig + CScript(OP_CODESEPARATOR) + txout.scriptPubKey, txTo, nIn)) + return false; + + return true; +} + + +bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, int nHashType) +{ + assert(nIn < txTo.vin.size()); + const CTxIn& txin = txTo.vin[nIn]; + if (txin.prevout.n >= txFrom.vout.size()) + return false; + const CTxOut& txout = txFrom.vout[txin.prevout.n]; + + if (txin.prevout.hash != txFrom.GetHash()) + return false; + + if (!EvalScript(txin.scriptSig + CScript(OP_CODESEPARATOR) + txout.scriptPubKey, txTo, nIn, nHashType)) + return false; + + // Anytime a signature is successfully verified, it's proof the outpoint is spent, + // so lets update the wallet spent flag if it doesn't know due to wallet.dat being + // restored from backup or the user making copies of wallet.dat. + WalletUpdateSpent(txin.prevout); + + return true; +} @@ -1,642 +1,642 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
-
-class CTransaction;
-
-enum
-{
- SIGHASH_ALL = 1,
- SIGHASH_NONE = 2,
- SIGHASH_SINGLE = 3,
- SIGHASH_ANYONECANPAY = 0x80,
-};
-
-
-
-enum opcodetype
-{
- // push value
- OP_0=0,
- OP_FALSE=OP_0,
- OP_PUSHDATA1=76,
- OP_PUSHDATA2,
- OP_PUSHDATA4,
- OP_1NEGATE,
- OP_RESERVED,
- OP_1,
- OP_TRUE=OP_1,
- OP_2,
- OP_3,
- OP_4,
- OP_5,
- OP_6,
- OP_7,
- OP_8,
- OP_9,
- OP_10,
- OP_11,
- OP_12,
- OP_13,
- OP_14,
- OP_15,
- OP_16,
-
- // control
- OP_NOP,
- OP_VER,
- OP_IF,
- OP_NOTIF,
- OP_VERIF,
- OP_VERNOTIF,
- OP_ELSE,
- OP_ENDIF,
- OP_VERIFY,
- OP_RETURN,
-
- // stack ops
- OP_TOALTSTACK,
- OP_FROMALTSTACK,
- OP_2DROP,
- OP_2DUP,
- OP_3DUP,
- OP_2OVER,
- OP_2ROT,
- OP_2SWAP,
- OP_IFDUP,
- OP_DEPTH,
- OP_DROP,
- OP_DUP,
- OP_NIP,
- OP_OVER,
- OP_PICK,
- OP_ROLL,
- OP_ROT,
- OP_SWAP,
- OP_TUCK,
-
- // splice ops
- OP_CAT,
- OP_SUBSTR,
- OP_LEFT,
- OP_RIGHT,
- OP_SIZE,
-
- // bit logic
- OP_INVERT,
- OP_AND,
- OP_OR,
- OP_XOR,
- OP_EQUAL,
- OP_EQUALVERIFY,
- OP_RESERVED1,
- OP_RESERVED2,
-
- // numeric
- OP_1ADD,
- OP_1SUB,
- OP_2MUL,
- OP_2DIV,
- OP_NEGATE,
- OP_ABS,
- OP_NOT,
- OP_0NOTEQUAL,
-
- OP_ADD,
- OP_SUB,
- OP_MUL,
- OP_DIV,
- OP_MOD,
- OP_LSHIFT,
- OP_RSHIFT,
-
- OP_BOOLAND,
- OP_BOOLOR,
- OP_NUMEQUAL,
- OP_NUMEQUALVERIFY,
- OP_NUMNOTEQUAL,
- OP_LESSTHAN,
- OP_GREATERTHAN,
- OP_LESSTHANOREQUAL,
- OP_GREATERTHANOREQUAL,
- OP_MIN,
- OP_MAX,
-
- OP_WITHIN,
-
- // crypto
- OP_RIPEMD160,
- OP_SHA1,
- OP_SHA256,
- OP_HASH160,
- OP_HASH256,
- OP_CODESEPARATOR,
- OP_CHECKSIG,
- OP_CHECKSIGVERIFY,
- OP_CHECKMULTISIG,
- OP_CHECKMULTISIGVERIFY,
-
-
- // multi-byte opcodes
- OP_SINGLEBYTE_END = 0xF0,
- OP_DOUBLEBYTE_BEGIN = 0xF000,
-
- // template matching params
- OP_PUBKEY,
- OP_PUBKEYHASH,
-
-
-
- OP_INVALIDOPCODE = 0xFFFF,
-};
-
-
-
-
-
-
-
-
-inline const char* GetOpName(opcodetype opcode)
-{
- switch (opcode)
- {
- // push value
- case OP_0 : return "0";
- case OP_PUSHDATA1 : return "OP_PUSHDATA1";
- case OP_PUSHDATA2 : return "OP_PUSHDATA2";
- case OP_PUSHDATA4 : return "OP_PUSHDATA4";
- case OP_1NEGATE : return "-1";
- case OP_RESERVED : return "OP_RESERVED";
- case OP_1 : return "1";
- case OP_2 : return "2";
- case OP_3 : return "3";
- case OP_4 : return "4";
- case OP_5 : return "5";
- case OP_6 : return "6";
- case OP_7 : return "7";
- case OP_8 : return "8";
- case OP_9 : return "9";
- case OP_10 : return "10";
- case OP_11 : return "11";
- case OP_12 : return "12";
- case OP_13 : return "13";
- case OP_14 : return "14";
- case OP_15 : return "15";
- case OP_16 : return "16";
-
- // control
- case OP_NOP : return "OP_NOP";
- case OP_VER : return "OP_VER";
- case OP_IF : return "OP_IF";
- case OP_NOTIF : return "OP_NOTIF";
- case OP_VERIF : return "OP_VERIF";
- case OP_VERNOTIF : return "OP_VERNOTIF";
- case OP_ELSE : return "OP_ELSE";
- case OP_ENDIF : return "OP_ENDIF";
- case OP_VERIFY : return "OP_VERIFY";
- case OP_RETURN : return "OP_RETURN";
-
- // stack ops
- case OP_TOALTSTACK : return "OP_TOALTSTACK";
- case OP_FROMALTSTACK : return "OP_FROMALTSTACK";
- case OP_2DROP : return "OP_2DROP";
- case OP_2DUP : return "OP_2DUP";
- case OP_3DUP : return "OP_3DUP";
- case OP_2OVER : return "OP_2OVER";
- case OP_2ROT : return "OP_2ROT";
- case OP_2SWAP : return "OP_2SWAP";
- case OP_IFDUP : return "OP_IFDUP";
- case OP_DEPTH : return "OP_DEPTH";
- case OP_DROP : return "OP_DROP";
- case OP_DUP : return "OP_DUP";
- case OP_NIP : return "OP_NIP";
- case OP_OVER : return "OP_OVER";
- case OP_PICK : return "OP_PICK";
- case OP_ROLL : return "OP_ROLL";
- case OP_ROT : return "OP_ROT";
- case OP_SWAP : return "OP_SWAP";
- case OP_TUCK : return "OP_TUCK";
-
- // splice ops
- case OP_CAT : return "OP_CAT";
- case OP_SUBSTR : return "OP_SUBSTR";
- case OP_LEFT : return "OP_LEFT";
- case OP_RIGHT : return "OP_RIGHT";
- case OP_SIZE : return "OP_SIZE";
-
- // bit logic
- case OP_INVERT : return "OP_INVERT";
- case OP_AND : return "OP_AND";
- case OP_OR : return "OP_OR";
- case OP_XOR : return "OP_XOR";
- case OP_EQUAL : return "OP_EQUAL";
- case OP_EQUALVERIFY : return "OP_EQUALVERIFY";
- case OP_RESERVED1 : return "OP_RESERVED1";
- case OP_RESERVED2 : return "OP_RESERVED2";
-
- // numeric
- case OP_1ADD : return "OP_1ADD";
- case OP_1SUB : return "OP_1SUB";
- case OP_2MUL : return "OP_2MUL";
- case OP_2DIV : return "OP_2DIV";
- case OP_NEGATE : return "OP_NEGATE";
- case OP_ABS : return "OP_ABS";
- case OP_NOT : return "OP_NOT";
- case OP_0NOTEQUAL : return "OP_0NOTEQUAL";
- case OP_ADD : return "OP_ADD";
- case OP_SUB : return "OP_SUB";
- case OP_MUL : return "OP_MUL";
- case OP_DIV : return "OP_DIV";
- case OP_MOD : return "OP_MOD";
- case OP_LSHIFT : return "OP_LSHIFT";
- case OP_RSHIFT : return "OP_RSHIFT";
- case OP_BOOLAND : return "OP_BOOLAND";
- case OP_BOOLOR : return "OP_BOOLOR";
- case OP_NUMEQUAL : return "OP_NUMEQUAL";
- case OP_NUMEQUALVERIFY : return "OP_NUMEQUALVERIFY";
- case OP_NUMNOTEQUAL : return "OP_NUMNOTEQUAL";
- case OP_LESSTHAN : return "OP_LESSTHAN";
- case OP_GREATERTHAN : return "OP_GREATERTHAN";
- case OP_LESSTHANOREQUAL : return "OP_LESSTHANOREQUAL";
- case OP_GREATERTHANOREQUAL : return "OP_GREATERTHANOREQUAL";
- case OP_MIN : return "OP_MIN";
- case OP_MAX : return "OP_MAX";
- case OP_WITHIN : return "OP_WITHIN";
-
- // crypto
- case OP_RIPEMD160 : return "OP_RIPEMD160";
- case OP_SHA1 : return "OP_SHA1";
- case OP_SHA256 : return "OP_SHA256";
- case OP_HASH160 : return "OP_HASH160";
- case OP_HASH256 : return "OP_HASH256";
- case OP_CODESEPARATOR : return "OP_CODESEPARATOR";
- case OP_CHECKSIG : return "OP_CHECKSIG";
- case OP_CHECKSIGVERIFY : return "OP_CHECKSIGVERIFY";
- case OP_CHECKMULTISIG : return "OP_CHECKMULTISIG";
- case OP_CHECKMULTISIGVERIFY : return "OP_CHECKMULTISIGVERIFY";
-
-
-
- // multi-byte opcodes
- case OP_SINGLEBYTE_END : return "OP_SINGLEBYTE_END";
- case OP_DOUBLEBYTE_BEGIN : return "OP_DOUBLEBYTE_BEGIN";
- case OP_PUBKEY : return "OP_PUBKEY";
- case OP_PUBKEYHASH : return "OP_PUBKEYHASH";
-
-
-
- case OP_INVALIDOPCODE : return "OP_INVALIDOPCODE";
- default:
- return "UNKNOWN_OPCODE";
- }
-};
-
-
-
-
-inline string ValueString(const vector<unsigned char>& vch)
-{
- if (vch.size() <= 4)
- return strprintf("%d", CBigNum(vch).getint());
- else
- return HexNumStr(vch.begin(), vch.end());
- //return string("(") + HexStr(vch.begin(), vch.end()) + string(")");
-}
-
-inline string StackString(const vector<vector<unsigned char> >& vStack)
-{
- string str;
- foreach(const vector<unsigned char>& vch, vStack)
- {
- if (!str.empty())
- str += " ";
- str += ValueString(vch);
- }
- return str;
-}
-
-
-
-
-
-
-
-
-
-class CScript : public vector<unsigned char>
-{
-protected:
- CScript& push_int64(int64 n)
- {
- if (n == -1 || (n >= 1 && n <= 16))
- {
- push_back(n + (OP_1 - 1));
- }
- else
- {
- CBigNum bn(n);
- *this << bn.getvch();
- }
- return (*this);
- }
-
- CScript& push_uint64(uint64 n)
- {
- if (n == -1 || (n >= 1 && n <= 16))
- {
- push_back(n + (OP_1 - 1));
- }
- else
- {
- CBigNum bn(n);
- *this << bn.getvch();
- }
- return (*this);
- }
-
-public:
- CScript() { }
- CScript(const CScript& b) : vector<unsigned char>(b.begin(), b.end()) { }
- CScript(const_iterator pbegin, const_iterator pend) : vector<unsigned char>(pbegin, pend) { }
-#ifndef _MSC_VER
- CScript(const unsigned char* pbegin, const unsigned char* pend) : vector<unsigned char>(pbegin, pend) { }
-#endif
-
- CScript& operator+=(const CScript& b)
- {
- insert(end(), b.begin(), b.end());
- return *this;
- }
-
- friend CScript operator+(const CScript& a, const CScript& b)
- {
- CScript ret = a;
- ret += b;
- return (ret);
- }
-
-
- explicit CScript(char b) { operator<<(b); }
- explicit CScript(short b) { operator<<(b); }
- explicit CScript(int b) { operator<<(b); }
- explicit CScript(long b) { operator<<(b); }
- explicit CScript(int64 b) { operator<<(b); }
- explicit CScript(unsigned char b) { operator<<(b); }
- explicit CScript(unsigned int b) { operator<<(b); }
- explicit CScript(unsigned short b) { operator<<(b); }
- explicit CScript(unsigned long b) { operator<<(b); }
- explicit CScript(uint64 b) { operator<<(b); }
-
- explicit CScript(opcodetype b) { operator<<(b); }
- explicit CScript(const uint256& b) { operator<<(b); }
- explicit CScript(const CBigNum& b) { operator<<(b); }
- explicit CScript(const vector<unsigned char>& b) { operator<<(b); }
-
-
- CScript& operator<<(char b) { return (push_int64(b)); }
- CScript& operator<<(short b) { return (push_int64(b)); }
- CScript& operator<<(int b) { return (push_int64(b)); }
- CScript& operator<<(long b) { return (push_int64(b)); }
- CScript& operator<<(int64 b) { return (push_int64(b)); }
- CScript& operator<<(unsigned char b) { return (push_uint64(b)); }
- CScript& operator<<(unsigned int b) { return (push_uint64(b)); }
- CScript& operator<<(unsigned short b) { return (push_uint64(b)); }
- CScript& operator<<(unsigned long b) { return (push_uint64(b)); }
- CScript& operator<<(uint64 b) { return (push_uint64(b)); }
-
- CScript& operator<<(opcodetype opcode)
- {
- if (opcode <= OP_SINGLEBYTE_END)
- {
- insert(end(), (unsigned char)opcode);
- }
- else
- {
- assert(opcode >= OP_DOUBLEBYTE_BEGIN);
- insert(end(), (unsigned char)(opcode >> 8));
- insert(end(), (unsigned char)(opcode & 0xFF));
- }
- return (*this);
- }
-
- CScript& operator<<(const uint160& b)
- {
- insert(end(), sizeof(b));
- insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b));
- return (*this);
- }
-
- CScript& operator<<(const uint256& b)
- {
- insert(end(), sizeof(b));
- insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b));
- return (*this);
- }
-
- CScript& operator<<(const CBigNum& b)
- {
- *this << b.getvch();
- return (*this);
- }
-
- CScript& operator<<(const vector<unsigned char>& b)
- {
- if (b.size() < OP_PUSHDATA1)
- {
- insert(end(), (unsigned char)b.size());
- }
- else if (b.size() <= 0xff)
- {
- insert(end(), OP_PUSHDATA1);
- insert(end(), (unsigned char)b.size());
- }
- else
- {
- insert(end(), OP_PUSHDATA2);
- unsigned short nSize = b.size();
- insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize));
- }
- insert(end(), b.begin(), b.end());
- return (*this);
- }
-
- CScript& operator<<(const CScript& b)
- {
- // I'm not sure if this should push the script or concatenate scripts.
- // If there's ever a use for pushing a script onto a script, delete this member fn
- assert(("warning: pushing a CScript onto a CScript with << is probably not intended, use + to concatenate", false));
- return (*this);
- }
-
-
- bool GetOp(iterator& pc, opcodetype& opcodeRet, vector<unsigned char>& vchRet)
- {
- // Wrapper so it can be called with either iterator or const_iterator
- const_iterator pc2 = pc;
- bool fRet = GetOp(pc2, opcodeRet, vchRet);
- pc = begin() + (pc2 - begin());
- return fRet;
- }
-
- bool GetOp(const_iterator& pc, opcodetype& opcodeRet, vector<unsigned char>& vchRet) const
- {
- opcodeRet = OP_INVALIDOPCODE;
- vchRet.clear();
- if (pc >= end())
- return false;
-
- // Read instruction
- unsigned int opcode = *pc++;
- if (opcode >= OP_SINGLEBYTE_END)
- {
- if (pc + 1 > end())
- return false;
- opcode <<= 8;
- opcode |= *pc++;
- }
-
- // Immediate operand
- if (opcode <= OP_PUSHDATA4)
- {
- unsigned int nSize = opcode;
- if (opcode == OP_PUSHDATA1)
- {
- if (pc + 1 > end())
- return false;
- nSize = *pc++;
- }
- else if (opcode == OP_PUSHDATA2)
- {
- if (pc + 2 > end())
- return false;
- nSize = 0;
- memcpy(&nSize, &pc[0], 2);
- pc += 2;
- }
- else if (opcode == OP_PUSHDATA4)
- {
- if (pc + 4 > end())
- return false;
- memcpy(&nSize, &pc[0], 4);
- pc += 4;
- }
- if (pc + nSize > end())
- return false;
- vchRet.assign(pc, pc + nSize);
- pc += nSize;
- }
-
- opcodeRet = (opcodetype)opcode;
- return true;
- }
-
-
- void FindAndDelete(const CScript& b)
- {
- iterator pc = begin();
- opcodetype opcode;
- vector<unsigned char> vchPushValue;
- int count = 0;
- do
- {
- while (end() - pc >= b.size() && memcmp(&pc[0], &b[0], b.size()) == 0)
- {
- erase(pc, pc + b.size());
- count++;
- }
- }
- while (GetOp(pc, opcode, vchPushValue));
- //printf("FindAndDeleted deleted %d items\n", count); /// debug
- }
-
-
- uint160 GetBitcoinAddressHash160() const
- {
- opcodetype opcode;
- vector<unsigned char> vch;
- CScript::const_iterator pc = begin();
- if (!GetOp(pc, opcode, vch) || opcode != OP_DUP) return 0;
- if (!GetOp(pc, opcode, vch) || opcode != OP_HASH160) return 0;
- if (!GetOp(pc, opcode, vch) || vch.size() != sizeof(uint160)) return 0;
- uint160 hash160 = uint160(vch);
- if (!GetOp(pc, opcode, vch) || opcode != OP_EQUALVERIFY) return 0;
- if (!GetOp(pc, opcode, vch) || opcode != OP_CHECKSIG) return 0;
- if (pc != end()) return 0;
- return hash160;
- }
-
- string GetBitcoinAddress() const
- {
- uint160 hash160 = GetBitcoinAddressHash160();
- if (hash160 == 0)
- return "";
- return Hash160ToAddress(hash160);
- }
-
- void SetBitcoinAddress(const uint160& hash160)
- {
- this->clear();
- *this << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG;
- }
-
- void SetBitcoinAddress(const vector<unsigned char>& vchPubKey)
- {
- SetBitcoinAddress(Hash160(vchPubKey));
- }
-
- bool SetBitcoinAddress(const string& strAddress)
- {
- this->clear();
- uint160 hash160;
- if (!AddressToHash160(strAddress, hash160))
- return false;
- SetBitcoinAddress(hash160);
- return true;
- }
-
-
- void PrintHex() const
- {
- printf("CScript(%s)\n", HexStr(begin(), end()).c_str());
- }
-
- string ToString() const
- {
- string str;
- opcodetype opcode;
- vector<unsigned char> vch;
- const_iterator it = begin();
- while (GetOp(it, opcode, vch))
- {
- if (!str.empty())
- str += " ";
- if (opcode <= OP_PUSHDATA4)
- str += ValueString(vch);
- else
- str += GetOpName(opcode);
- }
- return str;
- }
-
- void print() const
- {
- printf("%s\n", ToString().c_str());
- }
-};
-
-
-
-
-
-
-
-
-bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType=0,
- vector<vector<unsigned char> >* pvStackRet=NULL);
-uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType);
-bool IsMine(const CScript& scriptPubKey);
-bool ExtractPubKey(const CScript& scriptPubKey, bool fMineOnly, vector<unsigned char>& vchPubKeyRet);
-bool ExtractHash160(const CScript& scriptPubKey, uint160& hash160Ret);
-bool SignSignature(const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL, CScript scriptPrereq=CScript());
-bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, int nHashType=0);
+// Copyright (c) 2009-2010 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +class CTransaction; + +enum +{ + SIGHASH_ALL = 1, + SIGHASH_NONE = 2, + SIGHASH_SINGLE = 3, + SIGHASH_ANYONECANPAY = 0x80, +}; + + + +enum opcodetype +{ + // push value + OP_0=0, + OP_FALSE=OP_0, + OP_PUSHDATA1=76, + OP_PUSHDATA2, + OP_PUSHDATA4, + OP_1NEGATE, + OP_RESERVED, + OP_1, + OP_TRUE=OP_1, + OP_2, + OP_3, + OP_4, + OP_5, + OP_6, + OP_7, + OP_8, + OP_9, + OP_10, + OP_11, + OP_12, + OP_13, + OP_14, + OP_15, + OP_16, + + // control + OP_NOP, + OP_VER, + OP_IF, + OP_NOTIF, + OP_VERIF, + OP_VERNOTIF, + OP_ELSE, + OP_ENDIF, + OP_VERIFY, + OP_RETURN, + + // stack ops + OP_TOALTSTACK, + OP_FROMALTSTACK, + OP_2DROP, + OP_2DUP, + OP_3DUP, + OP_2OVER, + OP_2ROT, + OP_2SWAP, + OP_IFDUP, + OP_DEPTH, + OP_DROP, + OP_DUP, + OP_NIP, + OP_OVER, + OP_PICK, + OP_ROLL, + OP_ROT, + OP_SWAP, + OP_TUCK, + + // splice ops + OP_CAT, + OP_SUBSTR, + OP_LEFT, + OP_RIGHT, + OP_SIZE, + + // bit logic + OP_INVERT, + OP_AND, + OP_OR, + OP_XOR, + OP_EQUAL, + OP_EQUALVERIFY, + OP_RESERVED1, + OP_RESERVED2, + + // numeric + OP_1ADD, + OP_1SUB, + OP_2MUL, + OP_2DIV, + OP_NEGATE, + OP_ABS, + OP_NOT, + OP_0NOTEQUAL, + + OP_ADD, + OP_SUB, + OP_MUL, + OP_DIV, + OP_MOD, + OP_LSHIFT, + OP_RSHIFT, + + OP_BOOLAND, + OP_BOOLOR, + OP_NUMEQUAL, + OP_NUMEQUALVERIFY, + OP_NUMNOTEQUAL, + OP_LESSTHAN, + OP_GREATERTHAN, + OP_LESSTHANOREQUAL, + OP_GREATERTHANOREQUAL, + OP_MIN, + OP_MAX, + + OP_WITHIN, + + // crypto + OP_RIPEMD160, + OP_SHA1, + OP_SHA256, + OP_HASH160, + OP_HASH256, + OP_CODESEPARATOR, + OP_CHECKSIG, + OP_CHECKSIGVERIFY, + OP_CHECKMULTISIG, + OP_CHECKMULTISIGVERIFY, + + + // multi-byte opcodes + OP_SINGLEBYTE_END = 0xF0, + OP_DOUBLEBYTE_BEGIN = 0xF000, + + // template matching params + OP_PUBKEY, + OP_PUBKEYHASH, + + + + OP_INVALIDOPCODE = 0xFFFF, +}; + + + + + + + + +inline const char* GetOpName(opcodetype opcode) +{ + switch (opcode) + { + // push value + case OP_0 : return "0"; + case OP_PUSHDATA1 : return "OP_PUSHDATA1"; + case OP_PUSHDATA2 : return "OP_PUSHDATA2"; + case OP_PUSHDATA4 : return "OP_PUSHDATA4"; + case OP_1NEGATE : return "-1"; + case OP_RESERVED : return "OP_RESERVED"; + case OP_1 : return "1"; + case OP_2 : return "2"; + case OP_3 : return "3"; + case OP_4 : return "4"; + case OP_5 : return "5"; + case OP_6 : return "6"; + case OP_7 : return "7"; + case OP_8 : return "8"; + case OP_9 : return "9"; + case OP_10 : return "10"; + case OP_11 : return "11"; + case OP_12 : return "12"; + case OP_13 : return "13"; + case OP_14 : return "14"; + case OP_15 : return "15"; + case OP_16 : return "16"; + + // control + case OP_NOP : return "OP_NOP"; + case OP_VER : return "OP_VER"; + case OP_IF : return "OP_IF"; + case OP_NOTIF : return "OP_NOTIF"; + case OP_VERIF : return "OP_VERIF"; + case OP_VERNOTIF : return "OP_VERNOTIF"; + case OP_ELSE : return "OP_ELSE"; + case OP_ENDIF : return "OP_ENDIF"; + case OP_VERIFY : return "OP_VERIFY"; + case OP_RETURN : return "OP_RETURN"; + + // stack ops + case OP_TOALTSTACK : return "OP_TOALTSTACK"; + case OP_FROMALTSTACK : return "OP_FROMALTSTACK"; + case OP_2DROP : return "OP_2DROP"; + case OP_2DUP : return "OP_2DUP"; + case OP_3DUP : return "OP_3DUP"; + case OP_2OVER : return "OP_2OVER"; + case OP_2ROT : return "OP_2ROT"; + case OP_2SWAP : return "OP_2SWAP"; + case OP_IFDUP : return "OP_IFDUP"; + case OP_DEPTH : return "OP_DEPTH"; + case OP_DROP : return "OP_DROP"; + case OP_DUP : return "OP_DUP"; + case OP_NIP : return "OP_NIP"; + case OP_OVER : return "OP_OVER"; + case OP_PICK : return "OP_PICK"; + case OP_ROLL : return "OP_ROLL"; + case OP_ROT : return "OP_ROT"; + case OP_SWAP : return "OP_SWAP"; + case OP_TUCK : return "OP_TUCK"; + + // splice ops + case OP_CAT : return "OP_CAT"; + case OP_SUBSTR : return "OP_SUBSTR"; + case OP_LEFT : return "OP_LEFT"; + case OP_RIGHT : return "OP_RIGHT"; + case OP_SIZE : return "OP_SIZE"; + + // bit logic + case OP_INVERT : return "OP_INVERT"; + case OP_AND : return "OP_AND"; + case OP_OR : return "OP_OR"; + case OP_XOR : return "OP_XOR"; + case OP_EQUAL : return "OP_EQUAL"; + case OP_EQUALVERIFY : return "OP_EQUALVERIFY"; + case OP_RESERVED1 : return "OP_RESERVED1"; + case OP_RESERVED2 : return "OP_RESERVED2"; + + // numeric + case OP_1ADD : return "OP_1ADD"; + case OP_1SUB : return "OP_1SUB"; + case OP_2MUL : return "OP_2MUL"; + case OP_2DIV : return "OP_2DIV"; + case OP_NEGATE : return "OP_NEGATE"; + case OP_ABS : return "OP_ABS"; + case OP_NOT : return "OP_NOT"; + case OP_0NOTEQUAL : return "OP_0NOTEQUAL"; + case OP_ADD : return "OP_ADD"; + case OP_SUB : return "OP_SUB"; + case OP_MUL : return "OP_MUL"; + case OP_DIV : return "OP_DIV"; + case OP_MOD : return "OP_MOD"; + case OP_LSHIFT : return "OP_LSHIFT"; + case OP_RSHIFT : return "OP_RSHIFT"; + case OP_BOOLAND : return "OP_BOOLAND"; + case OP_BOOLOR : return "OP_BOOLOR"; + case OP_NUMEQUAL : return "OP_NUMEQUAL"; + case OP_NUMEQUALVERIFY : return "OP_NUMEQUALVERIFY"; + case OP_NUMNOTEQUAL : return "OP_NUMNOTEQUAL"; + case OP_LESSTHAN : return "OP_LESSTHAN"; + case OP_GREATERTHAN : return "OP_GREATERTHAN"; + case OP_LESSTHANOREQUAL : return "OP_LESSTHANOREQUAL"; + case OP_GREATERTHANOREQUAL : return "OP_GREATERTHANOREQUAL"; + case OP_MIN : return "OP_MIN"; + case OP_MAX : return "OP_MAX"; + case OP_WITHIN : return "OP_WITHIN"; + + // crypto + case OP_RIPEMD160 : return "OP_RIPEMD160"; + case OP_SHA1 : return "OP_SHA1"; + case OP_SHA256 : return "OP_SHA256"; + case OP_HASH160 : return "OP_HASH160"; + case OP_HASH256 : return "OP_HASH256"; + case OP_CODESEPARATOR : return "OP_CODESEPARATOR"; + case OP_CHECKSIG : return "OP_CHECKSIG"; + case OP_CHECKSIGVERIFY : return "OP_CHECKSIGVERIFY"; + case OP_CHECKMULTISIG : return "OP_CHECKMULTISIG"; + case OP_CHECKMULTISIGVERIFY : return "OP_CHECKMULTISIGVERIFY"; + + + + // multi-byte opcodes + case OP_SINGLEBYTE_END : return "OP_SINGLEBYTE_END"; + case OP_DOUBLEBYTE_BEGIN : return "OP_DOUBLEBYTE_BEGIN"; + case OP_PUBKEY : return "OP_PUBKEY"; + case OP_PUBKEYHASH : return "OP_PUBKEYHASH"; + + + + case OP_INVALIDOPCODE : return "OP_INVALIDOPCODE"; + default: + return "UNKNOWN_OPCODE"; + } +}; + + + + +inline string ValueString(const vector<unsigned char>& vch) +{ + if (vch.size() <= 4) + return strprintf("%d", CBigNum(vch).getint()); + else + return HexNumStr(vch.begin(), vch.end()); + //return string("(") + HexStr(vch.begin(), vch.end()) + string(")"); +} + +inline string StackString(const vector<vector<unsigned char> >& vStack) +{ + string str; + foreach(const vector<unsigned char>& vch, vStack) + { + if (!str.empty()) + str += " "; + str += ValueString(vch); + } + return str; +} + + + + + + + + + +class CScript : public vector<unsigned char> +{ +protected: + CScript& push_int64(int64 n) + { + if (n == -1 || (n >= 1 && n <= 16)) + { + push_back(n + (OP_1 - 1)); + } + else + { + CBigNum bn(n); + *this << bn.getvch(); + } + return (*this); + } + + CScript& push_uint64(uint64 n) + { + if (n == -1 || (n >= 1 && n <= 16)) + { + push_back(n + (OP_1 - 1)); + } + else + { + CBigNum bn(n); + *this << bn.getvch(); + } + return (*this); + } + +public: + CScript() { } + CScript(const CScript& b) : vector<unsigned char>(b.begin(), b.end()) { } + CScript(const_iterator pbegin, const_iterator pend) : vector<unsigned char>(pbegin, pend) { } +#ifndef _MSC_VER + CScript(const unsigned char* pbegin, const unsigned char* pend) : vector<unsigned char>(pbegin, pend) { } +#endif + + CScript& operator+=(const CScript& b) + { + insert(end(), b.begin(), b.end()); + return *this; + } + + friend CScript operator+(const CScript& a, const CScript& b) + { + CScript ret = a; + ret += b; + return (ret); + } + + + explicit CScript(char b) { operator<<(b); } + explicit CScript(short b) { operator<<(b); } + explicit CScript(int b) { operator<<(b); } + explicit CScript(long b) { operator<<(b); } + explicit CScript(int64 b) { operator<<(b); } + explicit CScript(unsigned char b) { operator<<(b); } + explicit CScript(unsigned int b) { operator<<(b); } + explicit CScript(unsigned short b) { operator<<(b); } + explicit CScript(unsigned long b) { operator<<(b); } + explicit CScript(uint64 b) { operator<<(b); } + + explicit CScript(opcodetype b) { operator<<(b); } + explicit CScript(const uint256& b) { operator<<(b); } + explicit CScript(const CBigNum& b) { operator<<(b); } + explicit CScript(const vector<unsigned char>& b) { operator<<(b); } + + + CScript& operator<<(char b) { return (push_int64(b)); } + CScript& operator<<(short b) { return (push_int64(b)); } + CScript& operator<<(int b) { return (push_int64(b)); } + CScript& operator<<(long b) { return (push_int64(b)); } + CScript& operator<<(int64 b) { return (push_int64(b)); } + CScript& operator<<(unsigned char b) { return (push_uint64(b)); } + CScript& operator<<(unsigned int b) { return (push_uint64(b)); } + CScript& operator<<(unsigned short b) { return (push_uint64(b)); } + CScript& operator<<(unsigned long b) { return (push_uint64(b)); } + CScript& operator<<(uint64 b) { return (push_uint64(b)); } + + CScript& operator<<(opcodetype opcode) + { + if (opcode <= OP_SINGLEBYTE_END) + { + insert(end(), (unsigned char)opcode); + } + else + { + assert(opcode >= OP_DOUBLEBYTE_BEGIN); + insert(end(), (unsigned char)(opcode >> 8)); + insert(end(), (unsigned char)(opcode & 0xFF)); + } + return (*this); + } + + CScript& operator<<(const uint160& b) + { + insert(end(), sizeof(b)); + insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b)); + return (*this); + } + + CScript& operator<<(const uint256& b) + { + insert(end(), sizeof(b)); + insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b)); + return (*this); + } + + CScript& operator<<(const CBigNum& b) + { + *this << b.getvch(); + return (*this); + } + + CScript& operator<<(const vector<unsigned char>& b) + { + if (b.size() < OP_PUSHDATA1) + { + insert(end(), (unsigned char)b.size()); + } + else if (b.size() <= 0xff) + { + insert(end(), OP_PUSHDATA1); + insert(end(), (unsigned char)b.size()); + } + else + { + insert(end(), OP_PUSHDATA2); + unsigned short nSize = b.size(); + insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize)); + } + insert(end(), b.begin(), b.end()); + return (*this); + } + + CScript& operator<<(const CScript& b) + { + // I'm not sure if this should push the script or concatenate scripts. + // If there's ever a use for pushing a script onto a script, delete this member fn + assert(("warning: pushing a CScript onto a CScript with << is probably not intended, use + to concatenate", false)); + return (*this); + } + + + bool GetOp(iterator& pc, opcodetype& opcodeRet, vector<unsigned char>& vchRet) + { + // Wrapper so it can be called with either iterator or const_iterator + const_iterator pc2 = pc; + bool fRet = GetOp(pc2, opcodeRet, vchRet); + pc = begin() + (pc2 - begin()); + return fRet; + } + + bool GetOp(const_iterator& pc, opcodetype& opcodeRet, vector<unsigned char>& vchRet) const + { + opcodeRet = OP_INVALIDOPCODE; + vchRet.clear(); + if (pc >= end()) + return false; + + // Read instruction + unsigned int opcode = *pc++; + if (opcode >= OP_SINGLEBYTE_END) + { + if (pc + 1 > end()) + return false; + opcode <<= 8; + opcode |= *pc++; + } + + // Immediate operand + if (opcode <= OP_PUSHDATA4) + { + unsigned int nSize = opcode; + if (opcode == OP_PUSHDATA1) + { + if (pc + 1 > end()) + return false; + nSize = *pc++; + } + else if (opcode == OP_PUSHDATA2) + { + if (pc + 2 > end()) + return false; + nSize = 0; + memcpy(&nSize, &pc[0], 2); + pc += 2; + } + else if (opcode == OP_PUSHDATA4) + { + if (pc + 4 > end()) + return false; + memcpy(&nSize, &pc[0], 4); + pc += 4; + } + if (pc + nSize > end()) + return false; + vchRet.assign(pc, pc + nSize); + pc += nSize; + } + + opcodeRet = (opcodetype)opcode; + return true; + } + + + void FindAndDelete(const CScript& b) + { + iterator pc = begin(); + opcodetype opcode; + vector<unsigned char> vchPushValue; + int count = 0; + do + { + while (end() - pc >= b.size() && memcmp(&pc[0], &b[0], b.size()) == 0) + { + erase(pc, pc + b.size()); + count++; + } + } + while (GetOp(pc, opcode, vchPushValue)); + //printf("FindAndDeleted deleted %d items\n", count); /// debug + } + + + uint160 GetBitcoinAddressHash160() const + { + opcodetype opcode; + vector<unsigned char> vch; + CScript::const_iterator pc = begin(); + if (!GetOp(pc, opcode, vch) || opcode != OP_DUP) return 0; + if (!GetOp(pc, opcode, vch) || opcode != OP_HASH160) return 0; + if (!GetOp(pc, opcode, vch) || vch.size() != sizeof(uint160)) return 0; + uint160 hash160 = uint160(vch); + if (!GetOp(pc, opcode, vch) || opcode != OP_EQUALVERIFY) return 0; + if (!GetOp(pc, opcode, vch) || opcode != OP_CHECKSIG) return 0; + if (pc != end()) return 0; + return hash160; + } + + string GetBitcoinAddress() const + { + uint160 hash160 = GetBitcoinAddressHash160(); + if (hash160 == 0) + return ""; + return Hash160ToAddress(hash160); + } + + void SetBitcoinAddress(const uint160& hash160) + { + this->clear(); + *this << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG; + } + + void SetBitcoinAddress(const vector<unsigned char>& vchPubKey) + { + SetBitcoinAddress(Hash160(vchPubKey)); + } + + bool SetBitcoinAddress(const string& strAddress) + { + this->clear(); + uint160 hash160; + if (!AddressToHash160(strAddress, hash160)) + return false; + SetBitcoinAddress(hash160); + return true; + } + + + void PrintHex() const + { + printf("CScript(%s)\n", HexStr(begin(), end()).c_str()); + } + + string ToString() const + { + string str; + opcodetype opcode; + vector<unsigned char> vch; + const_iterator it = begin(); + while (GetOp(it, opcode, vch)) + { + if (!str.empty()) + str += " "; + if (opcode <= OP_PUSHDATA4) + str += ValueString(vch); + else + str += GetOpName(opcode); + } + return str; + } + + void print() const + { + printf("%s\n", ToString().c_str()); + } +}; + + + + + + + + +bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType=0, + vector<vector<unsigned char> >* pvStackRet=NULL); +uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); +bool IsMine(const CScript& scriptPubKey); +bool ExtractPubKey(const CScript& scriptPubKey, bool fMineOnly, vector<unsigned char>& vchPubKeyRet); +bool ExtractHash160(const CScript& scriptPubKey, uint160& hash160Ret); +bool SignSignature(const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL, CScript scriptPrereq=CScript()); +bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, int nHashType=0); diff --git a/serialize.h b/serialize.h index a32d106a32..7ebc047f76 100644 --- a/serialize.h +++ b/serialize.h @@ -1,1175 +1,1175 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
-
-#include <vector>
-#include <map>
-#include <boost/type_traits/is_fundamental.hpp>
-#if defined(_MSC_VER) || defined(__BORLANDC__)
-typedef __int64 int64;
-typedef unsigned __int64 uint64;
-#else
-typedef long long int64;
-typedef unsigned long long uint64;
-#endif
-#if defined(_MSC_VER) && _MSC_VER < 1300
-#define for if (false) ; else for
-#endif
-class CScript;
-class CDataStream;
-class CAutoFile;
-
-static const int VERSION = 301;
-static const char* pszSubVer = ".0";
-
-
-
-
-
-/////////////////////////////////////////////////////////////////
-//
-// Templates for serializing to anything that looks like a stream,
-// i.e. anything that supports .read(char*, int) and .write(char*, int)
-//
-
-enum
-{
- // primary actions
- SER_NETWORK = (1 << 0),
- SER_DISK = (1 << 1),
- SER_GETHASH = (1 << 2),
-
- // modifiers
- SER_SKIPSIG = (1 << 16),
- SER_BLOCKHEADERONLY = (1 << 17),
-};
-
-#define IMPLEMENT_SERIALIZE(statements) \
- unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const \
- { \
- CSerActionGetSerializeSize ser_action; \
- const bool fGetSize = true; \
- const bool fWrite = false; \
- const bool fRead = false; \
- unsigned int nSerSize = 0; \
- ser_streamplaceholder s; \
- s.nType = nType; \
- s.nVersion = nVersion; \
- {statements} \
- return nSerSize; \
- } \
- template<typename Stream> \
- void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const \
- { \
- CSerActionSerialize ser_action; \
- const bool fGetSize = false; \
- const bool fWrite = true; \
- const bool fRead = false; \
- unsigned int nSerSize = 0; \
- {statements} \
- } \
- template<typename Stream> \
- void Unserialize(Stream& s, int nType=0, int nVersion=VERSION) \
- { \
- CSerActionUnserialize ser_action; \
- const bool fGetSize = false; \
- const bool fWrite = false; \
- const bool fRead = true; \
- unsigned int nSerSize = 0; \
- {statements} \
- }
-
-#define READWRITE(obj) (nSerSize += ::SerReadWrite(s, (obj), nType, nVersion, ser_action))
-
-
-
-
-
-
-//
-// Basic types
-//
-#define WRITEDATA(s, obj) s.write((char*)&(obj), sizeof(obj))
-#define READDATA(s, obj) s.read((char*)&(obj), sizeof(obj))
-
-inline unsigned int GetSerializeSize(char a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(signed char a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(unsigned char a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(signed short a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(unsigned short a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(signed int a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(unsigned int a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(signed long a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(unsigned long a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(int64 a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(uint64 a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(float a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(double a, int, int=0) { return sizeof(a); }
-
-template<typename Stream> inline void Serialize(Stream& s, char a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, signed char a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, unsigned char a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, signed short a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, unsigned short a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, signed int a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, unsigned int a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, signed long a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, unsigned long a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, int64 a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, uint64 a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, float a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, double a, int, int=0) { WRITEDATA(s, a); }
-
-template<typename Stream> inline void Unserialize(Stream& s, char& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, signed char& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, unsigned char& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, signed short& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, unsigned short& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, signed int& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, unsigned int& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, signed long& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, unsigned long& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, int64& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, uint64& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, float& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, double& a, int, int=0) { READDATA(s, a); }
-
-inline unsigned int GetSerializeSize(bool a, int, int=0) { return sizeof(char); }
-template<typename Stream> inline void Serialize(Stream& s, bool a, int, int=0) { char f=a; WRITEDATA(s, f); }
-template<typename Stream> inline void Unserialize(Stream& s, bool& a, int, int=0) { char f; READDATA(s, f); a=f; }
-
-
-
-
-
-
-//
-// Compact size
-// size < 253 -- 1 byte
-// size <= USHRT_MAX -- 3 bytes (253 + 2 bytes)
-// size <= UINT_MAX -- 5 bytes (254 + 4 bytes)
-// size > UINT_MAX -- 9 bytes (255 + 8 bytes)
-//
-inline unsigned int GetSizeOfCompactSize(uint64 nSize)
-{
- if (nSize < UCHAR_MAX-2) return sizeof(unsigned char);
- else if (nSize <= USHRT_MAX) return sizeof(unsigned char) + sizeof(unsigned short);
- else if (nSize <= UINT_MAX) return sizeof(unsigned char) + sizeof(unsigned int);
- else return sizeof(unsigned char) + sizeof(uint64);
-}
-
-template<typename Stream>
-void WriteCompactSize(Stream& os, uint64 nSize)
-{
- if (nSize < UCHAR_MAX-2)
- {
- unsigned char chSize = nSize;
- WRITEDATA(os, chSize);
- }
- else if (nSize <= USHRT_MAX)
- {
- unsigned char chSize = UCHAR_MAX-2;
- unsigned short xSize = nSize;
- WRITEDATA(os, chSize);
- WRITEDATA(os, xSize);
- }
- else if (nSize <= UINT_MAX)
- {
- unsigned char chSize = UCHAR_MAX-1;
- unsigned int xSize = nSize;
- WRITEDATA(os, chSize);
- WRITEDATA(os, xSize);
- }
- else
- {
- unsigned char chSize = UCHAR_MAX;
- WRITEDATA(os, chSize);
- WRITEDATA(os, nSize);
- }
- return;
-}
-
-template<typename Stream>
-uint64 ReadCompactSize(Stream& is)
-{
- unsigned char chSize;
- READDATA(is, chSize);
- uint64 nSizeRet = 0;
- if (chSize < UCHAR_MAX-2)
- {
- nSizeRet = chSize;
- }
- else if (chSize == UCHAR_MAX-2)
- {
- unsigned short nSize;
- READDATA(is, nSize);
- nSizeRet = nSize;
- }
- else if (chSize == UCHAR_MAX-1)
- {
- unsigned int nSize;
- READDATA(is, nSize);
- nSizeRet = nSize;
- }
- else
- {
- uint64 nSize;
- READDATA(is, nSize);
- nSizeRet = nSize;
- }
- if (nSizeRet > (uint64)INT_MAX)
- throw std::ios_base::failure("ReadCompactSize() : size too large");
- return nSizeRet;
-}
-
-
-
-//
-// Wrapper for serializing arrays and POD
-// There's a clever template way to make arrays serialize normally, but MSVC6 doesn't support it
-//
-#define FLATDATA(obj) REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj)))
-class CFlatData
-{
-protected:
- char* pbegin;
- char* pend;
-public:
- CFlatData(void* pbeginIn, void* pendIn) : pbegin((char*)pbeginIn), pend((char*)pendIn) { }
- char* begin() { return pbegin; }
- const char* begin() const { return pbegin; }
- char* end() { return pend; }
- const char* end() const { return pend; }
-
- unsigned int GetSerializeSize(int, int=0) const
- {
- return pend - pbegin;
- }
-
- template<typename Stream>
- void Serialize(Stream& s, int, int=0) const
- {
- s.write(pbegin, pend - pbegin);
- }
-
- template<typename Stream>
- void Unserialize(Stream& s, int, int=0)
- {
- s.read(pbegin, pend - pbegin);
- }
-};
-
-
-
-//
-// string stored as a fixed length field
-//
-template<std::size_t LEN>
-class CFixedFieldString
-{
-protected:
- const string* pcstr;
- string* pstr;
-public:
- explicit CFixedFieldString(const string& str) : pcstr(&str), pstr(NULL) { }
- explicit CFixedFieldString(string& str) : pcstr(&str), pstr(&str) { }
-
- unsigned int GetSerializeSize(int, int=0) const
- {
- return LEN;
- }
-
- template<typename Stream>
- void Serialize(Stream& s, int, int=0) const
- {
- char pszBuf[LEN];
- strncpy(pszBuf, pcstr->c_str(), LEN);
- s.write(pszBuf, LEN);
- }
-
- template<typename Stream>
- void Unserialize(Stream& s, int, int=0)
- {
- if (pstr == NULL)
- throw std::ios_base::failure("CFixedFieldString::Unserialize : trying to unserialize to const string");
- char pszBuf[LEN+1];
- s.read(pszBuf, LEN);
- pszBuf[LEN] = '\0';
- *pstr = pszBuf;
- }
-};
-
-
-
-
-
-//
-// Forward declarations
-//
-
-// string
-template<typename C> unsigned int GetSerializeSize(const basic_string<C>& str, int, int=0);
-template<typename Stream, typename C> void Serialize(Stream& os, const basic_string<C>& str, int, int=0);
-template<typename Stream, typename C> void Unserialize(Stream& is, basic_string<C>& str, int, int=0);
-
-// vector
-template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&);
-template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&);
-template<typename T, typename A> inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion=VERSION);
-template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&);
-template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&);
-template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion=VERSION);
-template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&);
-template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&);
-template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion=VERSION);
-
-// others derived from vector
-extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion=VERSION);
-template<typename Stream> void Serialize(Stream& os, const CScript& v, int nType, int nVersion=VERSION);
-template<typename Stream> void Unserialize(Stream& is, CScript& v, int nType, int nVersion=VERSION);
-
-// pair
-template<typename K, typename T> unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion=VERSION);
-template<typename Stream, typename K, typename T> void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion=VERSION);
-template<typename Stream, typename K, typename T> void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion=VERSION);
-
-// map
-template<typename K, typename T, typename Pred, typename A> unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion=VERSION);
-template<typename Stream, typename K, typename T, typename Pred, typename A> void Serialize(Stream& os, const std::map<K, T, Pred, A>& m, int nType, int nVersion=VERSION);
-template<typename Stream, typename K, typename T, typename Pred, typename A> void Unserialize(Stream& is, std::map<K, T, Pred, A>& m, int nType, int nVersion=VERSION);
-
-// set
-template<typename K, typename Pred, typename A> unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion=VERSION);
-template<typename Stream, typename K, typename Pred, typename A> void Serialize(Stream& os, const std::set<K, Pred, A>& m, int nType, int nVersion=VERSION);
-template<typename Stream, typename K, typename Pred, typename A> void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion=VERSION);
-
-
-
-
-
-//
-// If none of the specialized versions above matched, default to calling member function.
-// "int nType" is changed to "long nType" to keep from getting an ambiguous overload error.
-// The compiler will only cast int to long if none of the other templates matched.
-// Thanks to Boost serialization for this idea.
-//
-template<typename T>
-inline unsigned int GetSerializeSize(const T& a, long nType, int nVersion=VERSION)
-{
- return a.GetSerializeSize((int)nType, nVersion);
-}
-
-template<typename Stream, typename T>
-inline void Serialize(Stream& os, const T& a, long nType, int nVersion=VERSION)
-{
- a.Serialize(os, (int)nType, nVersion);
-}
-
-template<typename Stream, typename T>
-inline void Unserialize(Stream& is, T& a, long nType, int nVersion=VERSION)
-{
- a.Unserialize(is, (int)nType, nVersion);
-}
-
-
-
-
-
-//
-// string
-//
-template<typename C>
-unsigned int GetSerializeSize(const basic_string<C>& str, int, int)
-{
- return GetSizeOfCompactSize(str.size()) + str.size() * sizeof(str[0]);
-}
-
-template<typename Stream, typename C>
-void Serialize(Stream& os, const basic_string<C>& str, int, int)
-{
- WriteCompactSize(os, str.size());
- if (!str.empty())
- os.write((char*)&str[0], str.size() * sizeof(str[0]));
-}
-
-template<typename Stream, typename C>
-void Unserialize(Stream& is, basic_string<C>& str, int, int)
-{
- unsigned int nSize = ReadCompactSize(is);
- str.resize(nSize);
- if (nSize != 0)
- is.read((char*)&str[0], nSize * sizeof(str[0]));
-}
-
-
-
-//
-// vector
-//
-template<typename T, typename A>
-unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&)
-{
- return (GetSizeOfCompactSize(v.size()) + v.size() * sizeof(T));
-}
-
-template<typename T, typename A>
-unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&)
-{
- unsigned int nSize = GetSizeOfCompactSize(v.size());
- for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
- nSize += GetSerializeSize((*vi), nType, nVersion);
- return nSize;
-}
-
-template<typename T, typename A>
-inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion)
-{
- return GetSerializeSize_impl(v, nType, nVersion, boost::is_fundamental<T>());
-}
-
-
-template<typename Stream, typename T, typename A>
-void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&)
-{
- WriteCompactSize(os, v.size());
- if (!v.empty())
- os.write((char*)&v[0], v.size() * sizeof(T));
-}
-
-template<typename Stream, typename T, typename A>
-void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&)
-{
- WriteCompactSize(os, v.size());
- for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
- ::Serialize(os, (*vi), nType, nVersion);
-}
-
-template<typename Stream, typename T, typename A>
-inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion)
-{
- Serialize_impl(os, v, nType, nVersion, boost::is_fundamental<T>());
-}
-
-
-template<typename Stream, typename T, typename A>
-void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&)
-{
- //unsigned int nSize = ReadCompactSize(is);
- //v.resize(nSize);
- //is.read((char*)&v[0], nSize * sizeof(T));
-
- // Limit size per read so bogus size value won't cause out of memory
- v.clear();
- unsigned int nSize = ReadCompactSize(is);
- unsigned int i = 0;
- while (i < nSize)
- {
- unsigned int blk = min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
- v.resize(i + blk);
- is.read((char*)&v[i], blk * sizeof(T));
- i += blk;
- }
-}
-
-template<typename Stream, typename T, typename A>
-void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&)
-{
- //unsigned int nSize = ReadCompactSize(is);
- //v.resize(nSize);
- //for (std::vector<T, A>::iterator vi = v.begin(); vi != v.end(); ++vi)
- // Unserialize(is, (*vi), nType, nVersion);
-
- v.clear();
- unsigned int nSize = ReadCompactSize(is);
- unsigned int i = 0;
- unsigned int nMid = 0;
- while (nMid < nSize)
- {
- nMid += 5000000 / sizeof(T);
- if (nMid > nSize)
- nMid = nSize;
- v.resize(nMid);
- for (; i < nMid; i++)
- Unserialize(is, v[i], nType, nVersion);
- }
-}
-
-template<typename Stream, typename T, typename A>
-inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion)
-{
- Unserialize_impl(is, v, nType, nVersion, boost::is_fundamental<T>());
-}
-
-
-
-//
-// others derived from vector
-//
-inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion)
-{
- return GetSerializeSize((const vector<unsigned char>&)v, nType, nVersion);
-}
-
-template<typename Stream>
-void Serialize(Stream& os, const CScript& v, int nType, int nVersion)
-{
- Serialize(os, (const vector<unsigned char>&)v, nType, nVersion);
-}
-
-template<typename Stream>
-void Unserialize(Stream& is, CScript& v, int nType, int nVersion)
-{
- Unserialize(is, (vector<unsigned char>&)v, nType, nVersion);
-}
-
-
-
-//
-// pair
-//
-template<typename K, typename T>
-unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion)
-{
- return GetSerializeSize(item.first, nType, nVersion) + GetSerializeSize(item.second, nType, nVersion);
-}
-
-template<typename Stream, typename K, typename T>
-void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion)
-{
- Serialize(os, item.first, nType, nVersion);
- Serialize(os, item.second, nType, nVersion);
-}
-
-template<typename Stream, typename K, typename T>
-void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion)
-{
- Unserialize(is, item.first, nType, nVersion);
- Unserialize(is, item.second, nType, nVersion);
-}
-
-
-
-//
-// map
-//
-template<typename K, typename T, typename Pred, typename A>
-unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion)
-{
- unsigned int nSize = GetSizeOfCompactSize(m.size());
- for (typename std::map<K, T, Pred, A>::const_iterator mi = m.begin(); mi != m.end(); ++mi)
- nSize += GetSerializeSize((*mi), nType, nVersion);
- return nSize;
-}
-
-template<typename Stream, typename K, typename T, typename Pred, typename A>
-void Serialize(Stream& os, const std::map<K, T, Pred, A>& m, int nType, int nVersion)
-{
- WriteCompactSize(os, m.size());
- for (typename std::map<K, T, Pred, A>::const_iterator mi = m.begin(); mi != m.end(); ++mi)
- Serialize(os, (*mi), nType, nVersion);
-}
-
-template<typename Stream, typename K, typename T, typename Pred, typename A>
-void Unserialize(Stream& is, std::map<K, T, Pred, A>& m, int nType, int nVersion)
-{
- m.clear();
- unsigned int nSize = ReadCompactSize(is);
- typename std::map<K, T, Pred, A>::iterator mi = m.begin();
- for (unsigned int i = 0; i < nSize; i++)
- {
- pair<K, T> item;
- Unserialize(is, item, nType, nVersion);
- mi = m.insert(mi, item);
- }
-}
-
-
-
-//
-// set
-//
-template<typename K, typename Pred, typename A>
-unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion)
-{
- unsigned int nSize = GetSizeOfCompactSize(m.size());
- for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it)
- nSize += GetSerializeSize((*it), nType, nVersion);
- return nSize;
-}
-
-template<typename Stream, typename K, typename Pred, typename A>
-void Serialize(Stream& os, const std::set<K, Pred, A>& m, int nType, int nVersion)
-{
- WriteCompactSize(os, m.size());
- for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it)
- Serialize(os, (*it), nType, nVersion);
-}
-
-template<typename Stream, typename K, typename Pred, typename A>
-void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion)
-{
- m.clear();
- unsigned int nSize = ReadCompactSize(is);
- typename std::set<K, Pred, A>::iterator it = m.begin();
- for (unsigned int i = 0; i < nSize; i++)
- {
- K key;
- Unserialize(is, key, nType, nVersion);
- it = m.insert(it, key);
- }
-}
-
-
-
-//
-// Support for IMPLEMENT_SERIALIZE and READWRITE macro
-//
-class CSerActionGetSerializeSize { };
-class CSerActionSerialize { };
-class CSerActionUnserialize { };
-
-template<typename Stream, typename T>
-inline unsigned int SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionGetSerializeSize ser_action)
-{
- return ::GetSerializeSize(obj, nType, nVersion);
-}
-
-template<typename Stream, typename T>
-inline unsigned int SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionSerialize ser_action)
-{
- ::Serialize(s, obj, nType, nVersion);
- return 0;
-}
-
-template<typename Stream, typename T>
-inline unsigned int SerReadWrite(Stream& s, T& obj, int nType, int nVersion, CSerActionUnserialize ser_action)
-{
- ::Unserialize(s, obj, nType, nVersion);
- return 0;
-}
-
-struct ser_streamplaceholder
-{
- int nType;
- int nVersion;
-};
-
-
-
-
-
-
-
-
-
-//
-// Allocator that clears its contents before deletion
-//
-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::pointer pointer;
- typedef typename base::const_pointer const_pointer;
- typedef typename base::reference reference;
- typedef typename base::const_reference const_reference;
- typedef typename base::value_type value_type;
- secure_allocator() throw() {}
- secure_allocator(const secure_allocator& a) throw() : base(a) {}
- ~secure_allocator() throw() {}
- template<typename _Other> struct rebind
- { typedef secure_allocator<_Other> other; };
-
- void deallocate(T* p, std::size_t n)
- {
- if (p != NULL)
- memset(p, 0, sizeof(T) * n);
- allocator<T>::deallocate(p, n);
- }
-};
-
-
-
-//
-// Double ended buffer combining vector and stream-like interfaces.
-// >> and << read and write unformatted data using the above serialization templates.
-// Fills with data in linear time; some stringstream implementations take N^2 time.
-//
-class CDataStream
-{
-protected:
- typedef vector<char, secure_allocator<char> > vector_type;
- vector_type vch;
- unsigned int nReadPos;
- short state;
- short exceptmask;
-public:
- int nType;
- int nVersion;
-
- typedef vector_type::allocator_type allocator_type;
- typedef vector_type::size_type size_type;
- typedef vector_type::difference_type difference_type;
- typedef vector_type::reference reference;
- typedef vector_type::const_reference const_reference;
- typedef vector_type::value_type value_type;
- typedef vector_type::iterator iterator;
- typedef vector_type::const_iterator const_iterator;
- typedef vector_type::reverse_iterator reverse_iterator;
-
- explicit CDataStream(int nTypeIn=0, int nVersionIn=VERSION)
- {
- Init(nTypeIn, nVersionIn);
- }
-
- CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn=0, int nVersionIn=VERSION) : vch(pbegin, pend)
- {
- Init(nTypeIn, nVersionIn);
- }
-
-#if !defined(_MSC_VER) || _MSC_VER >= 1300
- CDataStream(const char* pbegin, const char* pend, int nTypeIn=0, int nVersionIn=VERSION) : vch(pbegin, pend)
- {
- Init(nTypeIn, nVersionIn);
- }
-#endif
-
- CDataStream(const vector_type& vchIn, int nTypeIn=0, int nVersionIn=VERSION) : vch(vchIn.begin(), vchIn.end())
- {
- Init(nTypeIn, nVersionIn);
- }
-
- CDataStream(const vector<char>& vchIn, int nTypeIn=0, int nVersionIn=VERSION) : vch(vchIn.begin(), vchIn.end())
- {
- Init(nTypeIn, nVersionIn);
- }
-
- CDataStream(const vector<unsigned char>& vchIn, int nTypeIn=0, int nVersionIn=VERSION) : vch((char*)&vchIn.begin()[0], (char*)&vchIn.end()[0])
- {
- Init(nTypeIn, nVersionIn);
- }
-
- void Init(int nTypeIn=0, int nVersionIn=VERSION)
- {
- nReadPos = 0;
- nType = nTypeIn;
- nVersion = nVersionIn;
- state = 0;
- exceptmask = ios::badbit | ios::failbit;
- }
-
- CDataStream& operator+=(const CDataStream& b)
- {
- vch.insert(vch.end(), b.begin(), b.end());
- return *this;
- }
-
- friend CDataStream operator+(const CDataStream& a, const CDataStream& b)
- {
- CDataStream ret = a;
- ret += b;
- return (ret);
- }
-
- string str() const
- {
- return (string(begin(), end()));
- }
-
-
- //
- // Vector subset
- //
- const_iterator begin() const { return vch.begin() + nReadPos; }
- iterator begin() { return vch.begin() + nReadPos; }
- const_iterator end() const { return vch.end(); }
- iterator end() { return vch.end(); }
- size_type size() const { return vch.size() - nReadPos; }
- bool empty() const { return vch.size() == nReadPos; }
- void resize(size_type n, value_type c=0) { vch.resize(n + nReadPos, c); }
- void reserve(size_type n) { vch.reserve(n + nReadPos); }
- const_reference operator[](size_type pos) const { return vch[pos + nReadPos]; }
- reference operator[](size_type pos) { return vch[pos + nReadPos]; }
- void clear() { vch.clear(); nReadPos = 0; }
- iterator insert(iterator it, const char& x=char()) { return vch.insert(it, x); }
- void insert(iterator it, size_type n, const char& x) { vch.insert(it, n, x); }
-
- void insert(iterator it, const_iterator first, const_iterator last)
- {
- if (it == vch.begin() + nReadPos && last - first <= nReadPos)
- {
- // special case for inserting at the front when there's room
- nReadPos -= (last - first);
- memcpy(&vch[nReadPos], &first[0], last - first);
- }
- else
- vch.insert(it, first, last);
- }
-
- void insert(iterator it, vector<char>::const_iterator first, vector<char>::const_iterator last)
- {
- if (it == vch.begin() + nReadPos && last - first <= nReadPos)
- {
- // special case for inserting at the front when there's room
- nReadPos -= (last - first);
- memcpy(&vch[nReadPos], &first[0], last - first);
- }
- else
- vch.insert(it, first, last);
- }
-
-#if !defined(_MSC_VER) || _MSC_VER >= 1300
- void insert(iterator it, const char* first, const char* last)
- {
- if (it == vch.begin() + nReadPos && last - first <= nReadPos)
- {
- // special case for inserting at the front when there's room
- nReadPos -= (last - first);
- memcpy(&vch[nReadPos], &first[0], last - first);
- }
- else
- vch.insert(it, first, last);
- }
-#endif
-
- iterator erase(iterator it)
- {
- if (it == vch.begin() + nReadPos)
- {
- // special case for erasing from the front
- if (++nReadPos >= vch.size())
- {
- // whenever we reach the end, we take the opportunity to clear the buffer
- nReadPos = 0;
- return vch.erase(vch.begin(), vch.end());
- }
- return vch.begin() + nReadPos;
- }
- else
- return vch.erase(it);
- }
-
- iterator erase(iterator first, iterator last)
- {
- if (first == vch.begin() + nReadPos)
- {
- // special case for erasing from the front
- if (last == vch.end())
- {
- nReadPos = 0;
- return vch.erase(vch.begin(), vch.end());
- }
- else
- {
- nReadPos = (last - vch.begin());
- return last;
- }
- }
- else
- return vch.erase(first, last);
- }
-
- inline void Compact()
- {
- vch.erase(vch.begin(), vch.begin() + nReadPos);
- nReadPos = 0;
- }
-
- bool Rewind(size_type n)
- {
- // Rewind by n characters if the buffer hasn't been compacted yet
- if (n > nReadPos)
- return false;
- nReadPos -= n;
- return true;
- }
-
-
- //
- // Stream subset
- //
- void setstate(short bits, const char* psz)
- {
- state |= bits;
- if (state & exceptmask)
- throw std::ios_base::failure(psz);
- }
-
- bool eof() const { return size() == 0; }
- bool fail() const { return state & (ios::badbit | ios::failbit); }
- bool good() const { return !eof() && (state == 0); }
- void clear(short n) { state = n; } // name conflict with vector clear()
- short exceptions() { return exceptmask; }
- short exceptions(short mask) { short prev = exceptmask; exceptmask = mask; setstate(0, "CDataStream"); return prev; }
- CDataStream* rdbuf() { return this; }
- int in_avail() { return size(); }
-
- void SetType(int n) { nType = n; }
- int GetType() { return nType; }
- void SetVersion(int n) { nVersion = n; }
- int GetVersion() { return nVersion; }
- void ReadVersion() { *this >> nVersion; }
- void WriteVersion() { *this << nVersion; }
-
- CDataStream& read(char* pch, int nSize)
- {
- // Read from the beginning of the buffer
- assert(nSize >= 0);
- unsigned int nReadPosNext = nReadPos + nSize;
- if (nReadPosNext >= vch.size())
- {
- if (nReadPosNext > vch.size())
- {
- setstate(ios::failbit, "CDataStream::read() : end of data");
- memset(pch, 0, nSize);
- nSize = vch.size() - nReadPos;
- }
- memcpy(pch, &vch[nReadPos], nSize);
- nReadPos = 0;
- vch.clear();
- return (*this);
- }
- memcpy(pch, &vch[nReadPos], nSize);
- nReadPos = nReadPosNext;
- return (*this);
- }
-
- CDataStream& ignore(int nSize)
- {
- // Ignore from the beginning of the buffer
- assert(nSize >= 0);
- unsigned int nReadPosNext = nReadPos + nSize;
- if (nReadPosNext >= vch.size())
- {
- if (nReadPosNext > vch.size())
- {
- setstate(ios::failbit, "CDataStream::ignore() : end of data");
- nSize = vch.size() - nReadPos;
- }
- nReadPos = 0;
- vch.clear();
- return (*this);
- }
- nReadPos = nReadPosNext;
- return (*this);
- }
-
- CDataStream& write(const char* pch, int nSize)
- {
- // Write to the end of the buffer
- assert(nSize >= 0);
- vch.insert(vch.end(), pch, pch + nSize);
- return (*this);
- }
-
- template<typename Stream>
- void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const
- {
- // Special case: stream << stream concatenates like stream += stream
- if (!vch.empty())
- s.write((char*)&vch[0], vch.size() * sizeof(vch[0]));
- }
-
- template<typename T>
- unsigned int GetSerializeSize(const T& obj)
- {
- // Tells the size of the object if serialized to this stream
- return ::GetSerializeSize(obj, nType, nVersion);
- }
-
- template<typename T>
- CDataStream& operator<<(const T& obj)
- {
- // Serialize to this stream
- ::Serialize(*this, obj, nType, nVersion);
- return (*this);
- }
-
- template<typename T>
- CDataStream& operator>>(T& obj)
- {
- // Unserialize from this stream
- ::Unserialize(*this, obj, nType, nVersion);
- return (*this);
- }
-};
-
-#ifdef TESTCDATASTREAM
-// VC6sp6
-// CDataStream:
-// n=1000 0 seconds
-// n=2000 0 seconds
-// n=4000 0 seconds
-// n=8000 0 seconds
-// n=16000 0 seconds
-// n=32000 0 seconds
-// n=64000 1 seconds
-// n=128000 1 seconds
-// n=256000 2 seconds
-// n=512000 4 seconds
-// n=1024000 8 seconds
-// n=2048000 16 seconds
-// n=4096000 32 seconds
-// stringstream:
-// n=1000 1 seconds
-// n=2000 1 seconds
-// n=4000 13 seconds
-// n=8000 87 seconds
-// n=16000 400 seconds
-// n=32000 1660 seconds
-// n=64000 6749 seconds
-// n=128000 27241 seconds
-// n=256000 109804 seconds
-#include <iostream>
-int main(int argc, char *argv[])
-{
- vector<unsigned char> vch(0xcc, 250);
- printf("CDataStream:\n");
- for (int n = 1000; n <= 4500000; n *= 2)
- {
- CDataStream ss;
- time_t nStart = time(NULL);
- for (int i = 0; i < n; i++)
- ss.write((char*)&vch[0], vch.size());
- printf("n=%-10d %d seconds\n", n, time(NULL) - nStart);
- }
- printf("stringstream:\n");
- for (int n = 1000; n <= 4500000; n *= 2)
- {
- stringstream ss;
- time_t nStart = time(NULL);
- for (int i = 0; i < n; i++)
- ss.write((char*)&vch[0], vch.size());
- printf("n=%-10d %d seconds\n", n, time(NULL) - nStart);
- }
-}
-#endif
-
-
-
-
-
-
-
-
-
-
-//
-// Automatic closing wrapper for FILE*
-// - Will automatically close the file when it goes out of scope if not null.
-// - If you're returning the file pointer, return file.release().
-// - If you need to close the file early, use file.fclose() instead of fclose(file).
-//
-class CAutoFile
-{
-protected:
- FILE* file;
- short state;
- short exceptmask;
-public:
- int nType;
- int nVersion;
-
- typedef FILE element_type;
-
- CAutoFile(FILE* filenew=NULL, int nTypeIn=SER_DISK, int nVersionIn=VERSION)
- {
- file = filenew;
- nType = nTypeIn;
- nVersion = nVersionIn;
- state = 0;
- exceptmask = ios::badbit | ios::failbit;
- }
-
- ~CAutoFile()
- {
- fclose();
- }
-
- void fclose()
- {
- if (file != NULL && file != stdin && file != stdout && file != stderr)
- ::fclose(file);
- file = NULL;
- }
-
- FILE* release() { FILE* ret = file; file = NULL; return ret; }
- operator FILE*() { return file; }
- FILE* operator->() { return file; }
- FILE& operator*() { return *file; }
- FILE** operator&() { return &file; }
- FILE* operator=(FILE* pnew) { return file = pnew; }
- bool operator!() { return (file == NULL); }
-
-
- //
- // Stream subset
- //
- void setstate(short bits, const char* psz)
- {
- state |= bits;
- if (state & exceptmask)
- throw std::ios_base::failure(psz);
- }
-
- bool fail() const { return state & (ios::badbit | ios::failbit); }
- bool good() const { return state == 0; }
- void clear(short n = 0) { state = n; }
- short exceptions() { return exceptmask; }
- short exceptions(short mask) { short prev = exceptmask; exceptmask = mask; setstate(0, "CAutoFile"); return prev; }
-
- void SetType(int n) { nType = n; }
- int GetType() { return nType; }
- void SetVersion(int n) { nVersion = n; }
- int GetVersion() { return nVersion; }
- void ReadVersion() { *this >> nVersion; }
- void WriteVersion() { *this << nVersion; }
-
- CAutoFile& read(char* pch, int nSize)
- {
- if (!file)
- throw std::ios_base::failure("CAutoFile::read : file handle is NULL");
- if (fread(pch, 1, nSize, file) != nSize)
- setstate(ios::failbit, feof(file) ? "CAutoFile::read : end of file" : "CAutoFile::read : fread failed");
- return (*this);
- }
-
- CAutoFile& write(const char* pch, int nSize)
- {
- if (!file)
- throw std::ios_base::failure("CAutoFile::write : file handle is NULL");
- if (fwrite(pch, 1, nSize, file) != nSize)
- setstate(ios::failbit, "CAutoFile::write : write failed");
- return (*this);
- }
-
- template<typename T>
- unsigned int GetSerializeSize(const T& obj)
- {
- // Tells the size of the object if serialized to this stream
- return ::GetSerializeSize(obj, nType, nVersion);
- }
-
- template<typename T>
- CAutoFile& operator<<(const T& obj)
- {
- // Serialize to this stream
- if (!file)
- throw std::ios_base::failure("CAutoFile::operator<< : file handle is NULL");
- ::Serialize(*this, obj, nType, nVersion);
- return (*this);
- }
-
- template<typename T>
- CAutoFile& operator>>(T& obj)
- {
- // Unserialize from this stream
- if (!file)
- throw std::ios_base::failure("CAutoFile::operator>> : file handle is NULL");
- ::Unserialize(*this, obj, nType, nVersion);
- return (*this);
- }
-};
+// Copyright (c) 2009-2010 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +#include <vector> +#include <map> +#include <boost/type_traits/is_fundamental.hpp> +#if defined(_MSC_VER) || defined(__BORLANDC__) +typedef __int64 int64; +typedef unsigned __int64 uint64; +#else +typedef long long int64; +typedef unsigned long long uint64; +#endif +#if defined(_MSC_VER) && _MSC_VER < 1300 +#define for if (false) ; else for +#endif +class CScript; +class CDataStream; +class CAutoFile; + +static const int VERSION = 301; +static const char* pszSubVer = ".0"; + + + + + +///////////////////////////////////////////////////////////////// +// +// Templates for serializing to anything that looks like a stream, +// i.e. anything that supports .read(char*, int) and .write(char*, int) +// + +enum +{ + // primary actions + SER_NETWORK = (1 << 0), + SER_DISK = (1 << 1), + SER_GETHASH = (1 << 2), + + // modifiers + SER_SKIPSIG = (1 << 16), + SER_BLOCKHEADERONLY = (1 << 17), +}; + +#define IMPLEMENT_SERIALIZE(statements) \ + unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const \ + { \ + CSerActionGetSerializeSize ser_action; \ + const bool fGetSize = true; \ + const bool fWrite = false; \ + const bool fRead = false; \ + unsigned int nSerSize = 0; \ + ser_streamplaceholder s; \ + s.nType = nType; \ + s.nVersion = nVersion; \ + {statements} \ + return nSerSize; \ + } \ + template<typename Stream> \ + void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const \ + { \ + CSerActionSerialize ser_action; \ + const bool fGetSize = false; \ + const bool fWrite = true; \ + const bool fRead = false; \ + unsigned int nSerSize = 0; \ + {statements} \ + } \ + template<typename Stream> \ + void Unserialize(Stream& s, int nType=0, int nVersion=VERSION) \ + { \ + CSerActionUnserialize ser_action; \ + const bool fGetSize = false; \ + const bool fWrite = false; \ + const bool fRead = true; \ + unsigned int nSerSize = 0; \ + {statements} \ + } + +#define READWRITE(obj) (nSerSize += ::SerReadWrite(s, (obj), nType, nVersion, ser_action)) + + + + + + +// +// Basic types +// +#define WRITEDATA(s, obj) s.write((char*)&(obj), sizeof(obj)) +#define READDATA(s, obj) s.read((char*)&(obj), sizeof(obj)) + +inline unsigned int GetSerializeSize(char a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(signed char a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(unsigned char a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(signed short a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(unsigned short a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(signed int a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(unsigned int a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(signed long a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(unsigned long a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(int64 a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(uint64 a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(float a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(double a, int, int=0) { return sizeof(a); } + +template<typename Stream> inline void Serialize(Stream& s, char a, int, int=0) { WRITEDATA(s, a); } +template<typename Stream> inline void Serialize(Stream& s, signed char a, int, int=0) { WRITEDATA(s, a); } +template<typename Stream> inline void Serialize(Stream& s, unsigned char a, int, int=0) { WRITEDATA(s, a); } +template<typename Stream> inline void Serialize(Stream& s, signed short a, int, int=0) { WRITEDATA(s, a); } +template<typename Stream> inline void Serialize(Stream& s, unsigned short a, int, int=0) { WRITEDATA(s, a); } +template<typename Stream> inline void Serialize(Stream& s, signed int a, int, int=0) { WRITEDATA(s, a); } +template<typename Stream> inline void Serialize(Stream& s, unsigned int a, int, int=0) { WRITEDATA(s, a); } +template<typename Stream> inline void Serialize(Stream& s, signed long a, int, int=0) { WRITEDATA(s, a); } +template<typename Stream> inline void Serialize(Stream& s, unsigned long a, int, int=0) { WRITEDATA(s, a); } +template<typename Stream> inline void Serialize(Stream& s, int64 a, int, int=0) { WRITEDATA(s, a); } +template<typename Stream> inline void Serialize(Stream& s, uint64 a, int, int=0) { WRITEDATA(s, a); } +template<typename Stream> inline void Serialize(Stream& s, float a, int, int=0) { WRITEDATA(s, a); } +template<typename Stream> inline void Serialize(Stream& s, double a, int, int=0) { WRITEDATA(s, a); } + +template<typename Stream> inline void Unserialize(Stream& s, char& a, int, int=0) { READDATA(s, a); } +template<typename Stream> inline void Unserialize(Stream& s, signed char& a, int, int=0) { READDATA(s, a); } +template<typename Stream> inline void Unserialize(Stream& s, unsigned char& a, int, int=0) { READDATA(s, a); } +template<typename Stream> inline void Unserialize(Stream& s, signed short& a, int, int=0) { READDATA(s, a); } +template<typename Stream> inline void Unserialize(Stream& s, unsigned short& a, int, int=0) { READDATA(s, a); } +template<typename Stream> inline void Unserialize(Stream& s, signed int& a, int, int=0) { READDATA(s, a); } +template<typename Stream> inline void Unserialize(Stream& s, unsigned int& a, int, int=0) { READDATA(s, a); } +template<typename Stream> inline void Unserialize(Stream& s, signed long& a, int, int=0) { READDATA(s, a); } +template<typename Stream> inline void Unserialize(Stream& s, unsigned long& a, int, int=0) { READDATA(s, a); } +template<typename Stream> inline void Unserialize(Stream& s, int64& a, int, int=0) { READDATA(s, a); } +template<typename Stream> inline void Unserialize(Stream& s, uint64& a, int, int=0) { READDATA(s, a); } +template<typename Stream> inline void Unserialize(Stream& s, float& a, int, int=0) { READDATA(s, a); } +template<typename Stream> inline void Unserialize(Stream& s, double& a, int, int=0) { READDATA(s, a); } + +inline unsigned int GetSerializeSize(bool a, int, int=0) { return sizeof(char); } +template<typename Stream> inline void Serialize(Stream& s, bool a, int, int=0) { char f=a; WRITEDATA(s, f); } +template<typename Stream> inline void Unserialize(Stream& s, bool& a, int, int=0) { char f; READDATA(s, f); a=f; } + + + + + + +// +// Compact size +// size < 253 -- 1 byte +// size <= USHRT_MAX -- 3 bytes (253 + 2 bytes) +// size <= UINT_MAX -- 5 bytes (254 + 4 bytes) +// size > UINT_MAX -- 9 bytes (255 + 8 bytes) +// +inline unsigned int GetSizeOfCompactSize(uint64 nSize) +{ + if (nSize < UCHAR_MAX-2) return sizeof(unsigned char); + else if (nSize <= USHRT_MAX) return sizeof(unsigned char) + sizeof(unsigned short); + else if (nSize <= UINT_MAX) return sizeof(unsigned char) + sizeof(unsigned int); + else return sizeof(unsigned char) + sizeof(uint64); +} + +template<typename Stream> +void WriteCompactSize(Stream& os, uint64 nSize) +{ + if (nSize < UCHAR_MAX-2) + { + unsigned char chSize = nSize; + WRITEDATA(os, chSize); + } + else if (nSize <= USHRT_MAX) + { + unsigned char chSize = UCHAR_MAX-2; + unsigned short xSize = nSize; + WRITEDATA(os, chSize); + WRITEDATA(os, xSize); + } + else if (nSize <= UINT_MAX) + { + unsigned char chSize = UCHAR_MAX-1; + unsigned int xSize = nSize; + WRITEDATA(os, chSize); + WRITEDATA(os, xSize); + } + else + { + unsigned char chSize = UCHAR_MAX; + WRITEDATA(os, chSize); + WRITEDATA(os, nSize); + } + return; +} + +template<typename Stream> +uint64 ReadCompactSize(Stream& is) +{ + unsigned char chSize; + READDATA(is, chSize); + uint64 nSizeRet = 0; + if (chSize < UCHAR_MAX-2) + { + nSizeRet = chSize; + } + else if (chSize == UCHAR_MAX-2) + { + unsigned short nSize; + READDATA(is, nSize); + nSizeRet = nSize; + } + else if (chSize == UCHAR_MAX-1) + { + unsigned int nSize; + READDATA(is, nSize); + nSizeRet = nSize; + } + else + { + uint64 nSize; + READDATA(is, nSize); + nSizeRet = nSize; + } + if (nSizeRet > (uint64)INT_MAX) + throw std::ios_base::failure("ReadCompactSize() : size too large"); + return nSizeRet; +} + + + +// +// Wrapper for serializing arrays and POD +// There's a clever template way to make arrays serialize normally, but MSVC6 doesn't support it +// +#define FLATDATA(obj) REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj))) +class CFlatData +{ +protected: + char* pbegin; + char* pend; +public: + CFlatData(void* pbeginIn, void* pendIn) : pbegin((char*)pbeginIn), pend((char*)pendIn) { } + char* begin() { return pbegin; } + const char* begin() const { return pbegin; } + char* end() { return pend; } + const char* end() const { return pend; } + + unsigned int GetSerializeSize(int, int=0) const + { + return pend - pbegin; + } + + template<typename Stream> + void Serialize(Stream& s, int, int=0) const + { + s.write(pbegin, pend - pbegin); + } + + template<typename Stream> + void Unserialize(Stream& s, int, int=0) + { + s.read(pbegin, pend - pbegin); + } +}; + + + +// +// string stored as a fixed length field +// +template<std::size_t LEN> +class CFixedFieldString +{ +protected: + const string* pcstr; + string* pstr; +public: + explicit CFixedFieldString(const string& str) : pcstr(&str), pstr(NULL) { } + explicit CFixedFieldString(string& str) : pcstr(&str), pstr(&str) { } + + unsigned int GetSerializeSize(int, int=0) const + { + return LEN; + } + + template<typename Stream> + void Serialize(Stream& s, int, int=0) const + { + char pszBuf[LEN]; + strncpy(pszBuf, pcstr->c_str(), LEN); + s.write(pszBuf, LEN); + } + + template<typename Stream> + void Unserialize(Stream& s, int, int=0) + { + if (pstr == NULL) + throw std::ios_base::failure("CFixedFieldString::Unserialize : trying to unserialize to const string"); + char pszBuf[LEN+1]; + s.read(pszBuf, LEN); + pszBuf[LEN] = '\0'; + *pstr = pszBuf; + } +}; + + + + + +// +// Forward declarations +// + +// string +template<typename C> unsigned int GetSerializeSize(const basic_string<C>& str, int, int=0); +template<typename Stream, typename C> void Serialize(Stream& os, const basic_string<C>& str, int, int=0); +template<typename Stream, typename C> void Unserialize(Stream& is, basic_string<C>& str, int, int=0); + +// vector +template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&); +template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&); +template<typename T, typename A> inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion=VERSION); +template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&); +template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&); +template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion=VERSION); +template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&); +template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&); +template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion=VERSION); + +// others derived from vector +extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion=VERSION); +template<typename Stream> void Serialize(Stream& os, const CScript& v, int nType, int nVersion=VERSION); +template<typename Stream> void Unserialize(Stream& is, CScript& v, int nType, int nVersion=VERSION); + +// pair +template<typename K, typename T> unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion=VERSION); +template<typename Stream, typename K, typename T> void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion=VERSION); +template<typename Stream, typename K, typename T> void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion=VERSION); + +// map +template<typename K, typename T, typename Pred, typename A> unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion=VERSION); +template<typename Stream, typename K, typename T, typename Pred, typename A> void Serialize(Stream& os, const std::map<K, T, Pred, A>& m, int nType, int nVersion=VERSION); +template<typename Stream, typename K, typename T, typename Pred, typename A> void Unserialize(Stream& is, std::map<K, T, Pred, A>& m, int nType, int nVersion=VERSION); + +// set +template<typename K, typename Pred, typename A> unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion=VERSION); +template<typename Stream, typename K, typename Pred, typename A> void Serialize(Stream& os, const std::set<K, Pred, A>& m, int nType, int nVersion=VERSION); +template<typename Stream, typename K, typename Pred, typename A> void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion=VERSION); + + + + + +// +// If none of the specialized versions above matched, default to calling member function. +// "int nType" is changed to "long nType" to keep from getting an ambiguous overload error. +// The compiler will only cast int to long if none of the other templates matched. +// Thanks to Boost serialization for this idea. +// +template<typename T> +inline unsigned int GetSerializeSize(const T& a, long nType, int nVersion=VERSION) +{ + return a.GetSerializeSize((int)nType, nVersion); +} + +template<typename Stream, typename T> +inline void Serialize(Stream& os, const T& a, long nType, int nVersion=VERSION) +{ + a.Serialize(os, (int)nType, nVersion); +} + +template<typename Stream, typename T> +inline void Unserialize(Stream& is, T& a, long nType, int nVersion=VERSION) +{ + a.Unserialize(is, (int)nType, nVersion); +} + + + + + +// +// string +// +template<typename C> +unsigned int GetSerializeSize(const basic_string<C>& str, int, int) +{ + return GetSizeOfCompactSize(str.size()) + str.size() * sizeof(str[0]); +} + +template<typename Stream, typename C> +void Serialize(Stream& os, const basic_string<C>& str, int, int) +{ + WriteCompactSize(os, str.size()); + if (!str.empty()) + os.write((char*)&str[0], str.size() * sizeof(str[0])); +} + +template<typename Stream, typename C> +void Unserialize(Stream& is, basic_string<C>& str, int, int) +{ + unsigned int nSize = ReadCompactSize(is); + str.resize(nSize); + if (nSize != 0) + is.read((char*)&str[0], nSize * sizeof(str[0])); +} + + + +// +// vector +// +template<typename T, typename A> +unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&) +{ + return (GetSizeOfCompactSize(v.size()) + v.size() * sizeof(T)); +} + +template<typename T, typename A> +unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&) +{ + unsigned int nSize = GetSizeOfCompactSize(v.size()); + for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi) + nSize += GetSerializeSize((*vi), nType, nVersion); + return nSize; +} + +template<typename T, typename A> +inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion) +{ + return GetSerializeSize_impl(v, nType, nVersion, boost::is_fundamental<T>()); +} + + +template<typename Stream, typename T, typename A> +void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&) +{ + WriteCompactSize(os, v.size()); + if (!v.empty()) + os.write((char*)&v[0], v.size() * sizeof(T)); +} + +template<typename Stream, typename T, typename A> +void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&) +{ + WriteCompactSize(os, v.size()); + for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi) + ::Serialize(os, (*vi), nType, nVersion); +} + +template<typename Stream, typename T, typename A> +inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion) +{ + Serialize_impl(os, v, nType, nVersion, boost::is_fundamental<T>()); +} + + +template<typename Stream, typename T, typename A> +void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&) +{ + //unsigned int nSize = ReadCompactSize(is); + //v.resize(nSize); + //is.read((char*)&v[0], nSize * sizeof(T)); + + // Limit size per read so bogus size value won't cause out of memory + v.clear(); + unsigned int nSize = ReadCompactSize(is); + unsigned int i = 0; + while (i < nSize) + { + unsigned int blk = min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T))); + v.resize(i + blk); + is.read((char*)&v[i], blk * sizeof(T)); + i += blk; + } +} + +template<typename Stream, typename T, typename A> +void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&) +{ + //unsigned int nSize = ReadCompactSize(is); + //v.resize(nSize); + //for (std::vector<T, A>::iterator vi = v.begin(); vi != v.end(); ++vi) + // Unserialize(is, (*vi), nType, nVersion); + + v.clear(); + unsigned int nSize = ReadCompactSize(is); + unsigned int i = 0; + unsigned int nMid = 0; + while (nMid < nSize) + { + nMid += 5000000 / sizeof(T); + if (nMid > nSize) + nMid = nSize; + v.resize(nMid); + for (; i < nMid; i++) + Unserialize(is, v[i], nType, nVersion); + } +} + +template<typename Stream, typename T, typename A> +inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion) +{ + Unserialize_impl(is, v, nType, nVersion, boost::is_fundamental<T>()); +} + + + +// +// others derived from vector +// +inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion) +{ + return GetSerializeSize((const vector<unsigned char>&)v, nType, nVersion); +} + +template<typename Stream> +void Serialize(Stream& os, const CScript& v, int nType, int nVersion) +{ + Serialize(os, (const vector<unsigned char>&)v, nType, nVersion); +} + +template<typename Stream> +void Unserialize(Stream& is, CScript& v, int nType, int nVersion) +{ + Unserialize(is, (vector<unsigned char>&)v, nType, nVersion); +} + + + +// +// pair +// +template<typename K, typename T> +unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion) +{ + return GetSerializeSize(item.first, nType, nVersion) + GetSerializeSize(item.second, nType, nVersion); +} + +template<typename Stream, typename K, typename T> +void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion) +{ + Serialize(os, item.first, nType, nVersion); + Serialize(os, item.second, nType, nVersion); +} + +template<typename Stream, typename K, typename T> +void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion) +{ + Unserialize(is, item.first, nType, nVersion); + Unserialize(is, item.second, nType, nVersion); +} + + + +// +// map +// +template<typename K, typename T, typename Pred, typename A> +unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion) +{ + unsigned int nSize = GetSizeOfCompactSize(m.size()); + for (typename std::map<K, T, Pred, A>::const_iterator mi = m.begin(); mi != m.end(); ++mi) + nSize += GetSerializeSize((*mi), nType, nVersion); + return nSize; +} + +template<typename Stream, typename K, typename T, typename Pred, typename A> +void Serialize(Stream& os, const std::map<K, T, Pred, A>& m, int nType, int nVersion) +{ + WriteCompactSize(os, m.size()); + for (typename std::map<K, T, Pred, A>::const_iterator mi = m.begin(); mi != m.end(); ++mi) + Serialize(os, (*mi), nType, nVersion); +} + +template<typename Stream, typename K, typename T, typename Pred, typename A> +void Unserialize(Stream& is, std::map<K, T, Pred, A>& m, int nType, int nVersion) +{ + m.clear(); + unsigned int nSize = ReadCompactSize(is); + typename std::map<K, T, Pred, A>::iterator mi = m.begin(); + for (unsigned int i = 0; i < nSize; i++) + { + pair<K, T> item; + Unserialize(is, item, nType, nVersion); + mi = m.insert(mi, item); + } +} + + + +// +// set +// +template<typename K, typename Pred, typename A> +unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion) +{ + unsigned int nSize = GetSizeOfCompactSize(m.size()); + for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it) + nSize += GetSerializeSize((*it), nType, nVersion); + return nSize; +} + +template<typename Stream, typename K, typename Pred, typename A> +void Serialize(Stream& os, const std::set<K, Pred, A>& m, int nType, int nVersion) +{ + WriteCompactSize(os, m.size()); + for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it) + Serialize(os, (*it), nType, nVersion); +} + +template<typename Stream, typename K, typename Pred, typename A> +void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion) +{ + m.clear(); + unsigned int nSize = ReadCompactSize(is); + typename std::set<K, Pred, A>::iterator it = m.begin(); + for (unsigned int i = 0; i < nSize; i++) + { + K key; + Unserialize(is, key, nType, nVersion); + it = m.insert(it, key); + } +} + + + +// +// Support for IMPLEMENT_SERIALIZE and READWRITE macro +// +class CSerActionGetSerializeSize { }; +class CSerActionSerialize { }; +class CSerActionUnserialize { }; + +template<typename Stream, typename T> +inline unsigned int SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionGetSerializeSize ser_action) +{ + return ::GetSerializeSize(obj, nType, nVersion); +} + +template<typename Stream, typename T> +inline unsigned int SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionSerialize ser_action) +{ + ::Serialize(s, obj, nType, nVersion); + return 0; +} + +template<typename Stream, typename T> +inline unsigned int SerReadWrite(Stream& s, T& obj, int nType, int nVersion, CSerActionUnserialize ser_action) +{ + ::Unserialize(s, obj, nType, nVersion); + return 0; +} + +struct ser_streamplaceholder +{ + int nType; + int nVersion; +}; + + + + + + + + + +// +// Allocator that clears its contents before deletion +// +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::pointer pointer; + typedef typename base::const_pointer const_pointer; + typedef typename base::reference reference; + typedef typename base::const_reference const_reference; + typedef typename base::value_type value_type; + secure_allocator() throw() {} + secure_allocator(const secure_allocator& a) throw() : base(a) {} + ~secure_allocator() throw() {} + template<typename _Other> struct rebind + { typedef secure_allocator<_Other> other; }; + + void deallocate(T* p, std::size_t n) + { + if (p != NULL) + memset(p, 0, sizeof(T) * n); + allocator<T>::deallocate(p, n); + } +}; + + + +// +// Double ended buffer combining vector and stream-like interfaces. +// >> and << read and write unformatted data using the above serialization templates. +// Fills with data in linear time; some stringstream implementations take N^2 time. +// +class CDataStream +{ +protected: + typedef vector<char, secure_allocator<char> > vector_type; + vector_type vch; + unsigned int nReadPos; + short state; + short exceptmask; +public: + int nType; + int nVersion; + + typedef vector_type::allocator_type allocator_type; + typedef vector_type::size_type size_type; + typedef vector_type::difference_type difference_type; + typedef vector_type::reference reference; + typedef vector_type::const_reference const_reference; + typedef vector_type::value_type value_type; + typedef vector_type::iterator iterator; + typedef vector_type::const_iterator const_iterator; + typedef vector_type::reverse_iterator reverse_iterator; + + explicit CDataStream(int nTypeIn=0, int nVersionIn=VERSION) + { + Init(nTypeIn, nVersionIn); + } + + CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn=0, int nVersionIn=VERSION) : vch(pbegin, pend) + { + Init(nTypeIn, nVersionIn); + } + +#if !defined(_MSC_VER) || _MSC_VER >= 1300 + CDataStream(const char* pbegin, const char* pend, int nTypeIn=0, int nVersionIn=VERSION) : vch(pbegin, pend) + { + Init(nTypeIn, nVersionIn); + } +#endif + + CDataStream(const vector_type& vchIn, int nTypeIn=0, int nVersionIn=VERSION) : vch(vchIn.begin(), vchIn.end()) + { + Init(nTypeIn, nVersionIn); + } + + CDataStream(const vector<char>& vchIn, int nTypeIn=0, int nVersionIn=VERSION) : vch(vchIn.begin(), vchIn.end()) + { + Init(nTypeIn, nVersionIn); + } + + CDataStream(const vector<unsigned char>& vchIn, int nTypeIn=0, int nVersionIn=VERSION) : vch((char*)&vchIn.begin()[0], (char*)&vchIn.end()[0]) + { + Init(nTypeIn, nVersionIn); + } + + void Init(int nTypeIn=0, int nVersionIn=VERSION) + { + nReadPos = 0; + nType = nTypeIn; + nVersion = nVersionIn; + state = 0; + exceptmask = ios::badbit | ios::failbit; + } + + CDataStream& operator+=(const CDataStream& b) + { + vch.insert(vch.end(), b.begin(), b.end()); + return *this; + } + + friend CDataStream operator+(const CDataStream& a, const CDataStream& b) + { + CDataStream ret = a; + ret += b; + return (ret); + } + + string str() const + { + return (string(begin(), end())); + } + + + // + // Vector subset + // + const_iterator begin() const { return vch.begin() + nReadPos; } + iterator begin() { return vch.begin() + nReadPos; } + const_iterator end() const { return vch.end(); } + iterator end() { return vch.end(); } + size_type size() const { return vch.size() - nReadPos; } + bool empty() const { return vch.size() == nReadPos; } + void resize(size_type n, value_type c=0) { vch.resize(n + nReadPos, c); } + void reserve(size_type n) { vch.reserve(n + nReadPos); } + const_reference operator[](size_type pos) const { return vch[pos + nReadPos]; } + reference operator[](size_type pos) { return vch[pos + nReadPos]; } + void clear() { vch.clear(); nReadPos = 0; } + iterator insert(iterator it, const char& x=char()) { return vch.insert(it, x); } + void insert(iterator it, size_type n, const char& x) { vch.insert(it, n, x); } + + void insert(iterator it, const_iterator first, const_iterator last) + { + if (it == vch.begin() + nReadPos && last - first <= nReadPos) + { + // special case for inserting at the front when there's room + nReadPos -= (last - first); + memcpy(&vch[nReadPos], &first[0], last - first); + } + else + vch.insert(it, first, last); + } + + void insert(iterator it, vector<char>::const_iterator first, vector<char>::const_iterator last) + { + if (it == vch.begin() + nReadPos && last - first <= nReadPos) + { + // special case for inserting at the front when there's room + nReadPos -= (last - first); + memcpy(&vch[nReadPos], &first[0], last - first); + } + else + vch.insert(it, first, last); + } + +#if !defined(_MSC_VER) || _MSC_VER >= 1300 + void insert(iterator it, const char* first, const char* last) + { + if (it == vch.begin() + nReadPos && last - first <= nReadPos) + { + // special case for inserting at the front when there's room + nReadPos -= (last - first); + memcpy(&vch[nReadPos], &first[0], last - first); + } + else + vch.insert(it, first, last); + } +#endif + + iterator erase(iterator it) + { + if (it == vch.begin() + nReadPos) + { + // special case for erasing from the front + if (++nReadPos >= vch.size()) + { + // whenever we reach the end, we take the opportunity to clear the buffer + nReadPos = 0; + return vch.erase(vch.begin(), vch.end()); + } + return vch.begin() + nReadPos; + } + else + return vch.erase(it); + } + + iterator erase(iterator first, iterator last) + { + if (first == vch.begin() + nReadPos) + { + // special case for erasing from the front + if (last == vch.end()) + { + nReadPos = 0; + return vch.erase(vch.begin(), vch.end()); + } + else + { + nReadPos = (last - vch.begin()); + return last; + } + } + else + return vch.erase(first, last); + } + + inline void Compact() + { + vch.erase(vch.begin(), vch.begin() + nReadPos); + nReadPos = 0; + } + + bool Rewind(size_type n) + { + // Rewind by n characters if the buffer hasn't been compacted yet + if (n > nReadPos) + return false; + nReadPos -= n; + return true; + } + + + // + // Stream subset + // + void setstate(short bits, const char* psz) + { + state |= bits; + if (state & exceptmask) + throw std::ios_base::failure(psz); + } + + bool eof() const { return size() == 0; } + bool fail() const { return state & (ios::badbit | ios::failbit); } + bool good() const { return !eof() && (state == 0); } + void clear(short n) { state = n; } // name conflict with vector clear() + short exceptions() { return exceptmask; } + short exceptions(short mask) { short prev = exceptmask; exceptmask = mask; setstate(0, "CDataStream"); return prev; } + CDataStream* rdbuf() { return this; } + int in_avail() { return size(); } + + void SetType(int n) { nType = n; } + int GetType() { return nType; } + void SetVersion(int n) { nVersion = n; } + int GetVersion() { return nVersion; } + void ReadVersion() { *this >> nVersion; } + void WriteVersion() { *this << nVersion; } + + CDataStream& read(char* pch, int nSize) + { + // Read from the beginning of the buffer + assert(nSize >= 0); + unsigned int nReadPosNext = nReadPos + nSize; + if (nReadPosNext >= vch.size()) + { + if (nReadPosNext > vch.size()) + { + setstate(ios::failbit, "CDataStream::read() : end of data"); + memset(pch, 0, nSize); + nSize = vch.size() - nReadPos; + } + memcpy(pch, &vch[nReadPos], nSize); + nReadPos = 0; + vch.clear(); + return (*this); + } + memcpy(pch, &vch[nReadPos], nSize); + nReadPos = nReadPosNext; + return (*this); + } + + CDataStream& ignore(int nSize) + { + // Ignore from the beginning of the buffer + assert(nSize >= 0); + unsigned int nReadPosNext = nReadPos + nSize; + if (nReadPosNext >= vch.size()) + { + if (nReadPosNext > vch.size()) + { + setstate(ios::failbit, "CDataStream::ignore() : end of data"); + nSize = vch.size() - nReadPos; + } + nReadPos = 0; + vch.clear(); + return (*this); + } + nReadPos = nReadPosNext; + return (*this); + } + + CDataStream& write(const char* pch, int nSize) + { + // Write to the end of the buffer + assert(nSize >= 0); + vch.insert(vch.end(), pch, pch + nSize); + return (*this); + } + + template<typename Stream> + void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const + { + // Special case: stream << stream concatenates like stream += stream + if (!vch.empty()) + s.write((char*)&vch[0], vch.size() * sizeof(vch[0])); + } + + template<typename T> + unsigned int GetSerializeSize(const T& obj) + { + // Tells the size of the object if serialized to this stream + return ::GetSerializeSize(obj, nType, nVersion); + } + + template<typename T> + CDataStream& operator<<(const T& obj) + { + // Serialize to this stream + ::Serialize(*this, obj, nType, nVersion); + return (*this); + } + + template<typename T> + CDataStream& operator>>(T& obj) + { + // Unserialize from this stream + ::Unserialize(*this, obj, nType, nVersion); + return (*this); + } +}; + +#ifdef TESTCDATASTREAM +// VC6sp6 +// CDataStream: +// n=1000 0 seconds +// n=2000 0 seconds +// n=4000 0 seconds +// n=8000 0 seconds +// n=16000 0 seconds +// n=32000 0 seconds +// n=64000 1 seconds +// n=128000 1 seconds +// n=256000 2 seconds +// n=512000 4 seconds +// n=1024000 8 seconds +// n=2048000 16 seconds +// n=4096000 32 seconds +// stringstream: +// n=1000 1 seconds +// n=2000 1 seconds +// n=4000 13 seconds +// n=8000 87 seconds +// n=16000 400 seconds +// n=32000 1660 seconds +// n=64000 6749 seconds +// n=128000 27241 seconds +// n=256000 109804 seconds +#include <iostream> +int main(int argc, char *argv[]) +{ + vector<unsigned char> vch(0xcc, 250); + printf("CDataStream:\n"); + for (int n = 1000; n <= 4500000; n *= 2) + { + CDataStream ss; + time_t nStart = time(NULL); + for (int i = 0; i < n; i++) + ss.write((char*)&vch[0], vch.size()); + printf("n=%-10d %d seconds\n", n, time(NULL) - nStart); + } + printf("stringstream:\n"); + for (int n = 1000; n <= 4500000; n *= 2) + { + stringstream ss; + time_t nStart = time(NULL); + for (int i = 0; i < n; i++) + ss.write((char*)&vch[0], vch.size()); + printf("n=%-10d %d seconds\n", n, time(NULL) - nStart); + } +} +#endif + + + + + + + + + + +// +// Automatic closing wrapper for FILE* +// - Will automatically close the file when it goes out of scope if not null. +// - If you're returning the file pointer, return file.release(). +// - If you need to close the file early, use file.fclose() instead of fclose(file). +// +class CAutoFile +{ +protected: + FILE* file; + short state; + short exceptmask; +public: + int nType; + int nVersion; + + typedef FILE element_type; + + CAutoFile(FILE* filenew=NULL, int nTypeIn=SER_DISK, int nVersionIn=VERSION) + { + file = filenew; + nType = nTypeIn; + nVersion = nVersionIn; + state = 0; + exceptmask = ios::badbit | ios::failbit; + } + + ~CAutoFile() + { + fclose(); + } + + void fclose() + { + if (file != NULL && file != stdin && file != stdout && file != stderr) + ::fclose(file); + file = NULL; + } + + FILE* release() { FILE* ret = file; file = NULL; return ret; } + operator FILE*() { return file; } + FILE* operator->() { return file; } + FILE& operator*() { return *file; } + FILE** operator&() { return &file; } + FILE* operator=(FILE* pnew) { return file = pnew; } + bool operator!() { return (file == NULL); } + + + // + // Stream subset + // + void setstate(short bits, const char* psz) + { + state |= bits; + if (state & exceptmask) + throw std::ios_base::failure(psz); + } + + bool fail() const { return state & (ios::badbit | ios::failbit); } + bool good() const { return state == 0; } + void clear(short n = 0) { state = n; } + short exceptions() { return exceptmask; } + short exceptions(short mask) { short prev = exceptmask; exceptmask = mask; setstate(0, "CAutoFile"); return prev; } + + void SetType(int n) { nType = n; } + int GetType() { return nType; } + void SetVersion(int n) { nVersion = n; } + int GetVersion() { return nVersion; } + void ReadVersion() { *this >> nVersion; } + void WriteVersion() { *this << nVersion; } + + CAutoFile& read(char* pch, int nSize) + { + if (!file) + throw std::ios_base::failure("CAutoFile::read : file handle is NULL"); + if (fread(pch, 1, nSize, file) != nSize) + setstate(ios::failbit, feof(file) ? "CAutoFile::read : end of file" : "CAutoFile::read : fread failed"); + return (*this); + } + + CAutoFile& write(const char* pch, int nSize) + { + if (!file) + throw std::ios_base::failure("CAutoFile::write : file handle is NULL"); + if (fwrite(pch, 1, nSize, file) != nSize) + setstate(ios::failbit, "CAutoFile::write : write failed"); + return (*this); + } + + template<typename T> + unsigned int GetSerializeSize(const T& obj) + { + // Tells the size of the object if serialized to this stream + return ::GetSerializeSize(obj, nType, nVersion); + } + + template<typename T> + CAutoFile& operator<<(const T& obj) + { + // Serialize to this stream + if (!file) + throw std::ios_base::failure("CAutoFile::operator<< : file handle is NULL"); + ::Serialize(*this, obj, nType, nVersion); + return (*this); + } + + template<typename T> + CAutoFile& operator>>(T& obj) + { + // Unserialize from this stream + if (!file) + throw std::ios_base::failure("CAutoFile::operator>> : file handle is NULL"); + ::Unserialize(*this, obj, nType, nVersion); + return (*this); + } +}; @@ -1,156 +1,156 @@ -# Auto-generated by EclipseNSIS Script Wizard
-# 3.10.2009 19:00:28
-
-Name Bitcoin
-
-RequestExecutionLevel highest
-
-# General Symbol Definitions
-!define REGKEY "SOFTWARE\$(^Name)"
-!define VERSION 0.3.0
-!define COMPANY "Bitcoin project"
-!define URL http://www.bitcoin.org/
-
-# MUI Symbol Definitions
-!define MUI_ICON "src\rc\bitcoin.ico"
-!define MUI_FINISHPAGE_NOAUTOCLOSE
-!define MUI_STARTMENUPAGE_REGISTRY_ROOT HKLM
-!define MUI_STARTMENUPAGE_REGISTRY_KEY ${REGKEY}
-!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME StartMenuGroup
-!define MUI_STARTMENUPAGE_DEFAULTFOLDER Bitcoin
-!define MUI_FINISHPAGE_RUN $INSTDIR\bitcoin.exe
-!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico"
-!define MUI_UNFINISHPAGE_NOAUTOCLOSE
-
-# Included files
-!include Sections.nsh
-!include MUI2.nsh
-
-# Variables
-Var StartMenuGroup
-
-# Installer pages
-!insertmacro MUI_PAGE_WELCOME
-!insertmacro MUI_PAGE_DIRECTORY
-!insertmacro MUI_PAGE_STARTMENU Application $StartMenuGroup
-!insertmacro MUI_PAGE_INSTFILES
-!insertmacro MUI_PAGE_FINISH
-!insertmacro MUI_UNPAGE_CONFIRM
-!insertmacro MUI_UNPAGE_INSTFILES
-
-# Installer languages
-!insertmacro MUI_LANGUAGE English
-
-# Installer attributes
-OutFile bitcoin-0.3.0-win32-setup.exe
-InstallDir $PROGRAMFILES\Bitcoin
-CRCCheck on
-XPStyle on
-ShowInstDetails show
-VIProductVersion 0.3.0.0
-VIAddVersionKey ProductName Bitcoin
-VIAddVersionKey ProductVersion "${VERSION}"
-VIAddVersionKey CompanyName "${COMPANY}"
-VIAddVersionKey CompanyWebsite "${URL}"
-VIAddVersionKey FileVersion "${VERSION}"
-VIAddVersionKey FileDescription ""
-VIAddVersionKey LegalCopyright ""
-InstallDirRegKey HKCU "${REGKEY}" Path
-ShowUninstDetails show
-
-# Installer sections
-Section -Main SEC0000
- SetOutPath $INSTDIR
- SetOverwrite on
- File bitcoin.exe
- File libeay32.dll
- File mingwm10.dll
- File license.txt
- File readme.txt
- SetOutPath $INSTDIR\daemon
- File /r daemon\*.*
- SetOutPath $INSTDIR\locale
- File /r locale\*.*
- SetOutPath $INSTDIR\src
- File /r src\*.*
- SetOutPath $INSTDIR
- WriteRegStr HKCU "${REGKEY}\Components" Main 1
-SectionEnd
-
-Section -post SEC0001
- WriteRegStr HKCU "${REGKEY}" Path $INSTDIR
- SetOutPath $INSTDIR
- WriteUninstaller $INSTDIR\uninstall.exe
- !insertmacro MUI_STARTMENU_WRITE_BEGIN Application
- CreateDirectory $SMPROGRAMS\$StartMenuGroup
- CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Bitcoin.lnk" $INSTDIR\bitcoin.exe
- CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Uninstall Bitcoin.lnk" $INSTDIR\uninstall.exe
- !insertmacro MUI_STARTMENU_WRITE_END
- WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayName "$(^Name)"
- WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayVersion "${VERSION}"
- WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" Publisher "${COMPANY}"
- WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" URLInfoAbout "${URL}"
- WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayIcon $INSTDIR\uninstall.exe
- WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" UninstallString $INSTDIR\uninstall.exe
- WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoModify 1
- WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoRepair 1
-SectionEnd
-
-# Macro for selecting uninstaller sections
-!macro SELECT_UNSECTION SECTION_NAME UNSECTION_ID
- Push $R0
- ReadRegStr $R0 HKCU "${REGKEY}\Components" "${SECTION_NAME}"
- StrCmp $R0 1 0 next${UNSECTION_ID}
- !insertmacro SelectSection "${UNSECTION_ID}"
- GoTo done${UNSECTION_ID}
-next${UNSECTION_ID}:
- !insertmacro UnselectSection "${UNSECTION_ID}"
-done${UNSECTION_ID}:
- Pop $R0
-!macroend
-
-# Uninstaller sections
-Section /o -un.Main UNSEC0000
- Delete /REBOOTOK $INSTDIR\bitcoin.exe
- Delete /REBOOTOK $INSTDIR\libeay32.dll
- Delete /REBOOTOK $INSTDIR\mingwm10.dll
- Delete /REBOOTOK $INSTDIR\license.txt
- Delete /REBOOTOK $INSTDIR\readme.txt
- RMDir /r /REBOOTOK $INSTDIR\daemon
- RMDir /r /REBOOTOK $INSTDIR\locale
- RMDir /r /REBOOTOK $INSTDIR\src
- DeleteRegValue HKCU "${REGKEY}\Components" Main
-SectionEnd
-
-Section -un.post UNSEC0001
- DeleteRegKey HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)"
- Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Uninstall Bitcoin.lnk"
- Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Bitcoin.lnk"
- Delete /REBOOTOK "$SMSTARTUP\Bitcoin.lnk"
- Delete /REBOOTOK $INSTDIR\uninstall.exe
- Delete /REBOOTOK $INSTDIR\debug.log
- Delete /REBOOTOK $INSTDIR\db.log
- DeleteRegValue HKCU "${REGKEY}" StartMenuGroup
- DeleteRegValue HKCU "${REGKEY}" Path
- DeleteRegKey /IfEmpty HKCU "${REGKEY}\Components"
- DeleteRegKey /IfEmpty HKCU "${REGKEY}"
- RmDir /REBOOTOK $SMPROGRAMS\$StartMenuGroup
- RmDir /REBOOTOK $INSTDIR
- Push $R0
- StrCpy $R0 $StartMenuGroup 1
- StrCmp $R0 ">" no_smgroup
-no_smgroup:
- Pop $R0
-SectionEnd
-
-# Installer functions
-Function .onInit
- InitPluginsDir
-FunctionEnd
-
-# Uninstaller functions
-Function un.onInit
- ReadRegStr $INSTDIR HKCU "${REGKEY}" Path
- !insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuGroup
- !insertmacro SELECT_UNSECTION Main ${UNSEC0000}
-FunctionEnd
+# Auto-generated by EclipseNSIS Script Wizard +# 3.10.2009 19:00:28 + +Name Bitcoin + +RequestExecutionLevel highest + +# General Symbol Definitions +!define REGKEY "SOFTWARE\$(^Name)" +!define VERSION 0.3.0 +!define COMPANY "Bitcoin project" +!define URL http://www.bitcoin.org/ + +# MUI Symbol Definitions +!define MUI_ICON "src\rc\bitcoin.ico" +!define MUI_FINISHPAGE_NOAUTOCLOSE +!define MUI_STARTMENUPAGE_REGISTRY_ROOT HKLM +!define MUI_STARTMENUPAGE_REGISTRY_KEY ${REGKEY} +!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME StartMenuGroup +!define MUI_STARTMENUPAGE_DEFAULTFOLDER Bitcoin +!define MUI_FINISHPAGE_RUN $INSTDIR\bitcoin.exe +!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico" +!define MUI_UNFINISHPAGE_NOAUTOCLOSE + +# Included files +!include Sections.nsh +!include MUI2.nsh + +# Variables +Var StartMenuGroup + +# Installer pages +!insertmacro MUI_PAGE_WELCOME +!insertmacro MUI_PAGE_DIRECTORY +!insertmacro MUI_PAGE_STARTMENU Application $StartMenuGroup +!insertmacro MUI_PAGE_INSTFILES +!insertmacro MUI_PAGE_FINISH +!insertmacro MUI_UNPAGE_CONFIRM +!insertmacro MUI_UNPAGE_INSTFILES + +# Installer languages +!insertmacro MUI_LANGUAGE English + +# Installer attributes +OutFile bitcoin-0.3.0-win32-setup.exe +InstallDir $PROGRAMFILES\Bitcoin +CRCCheck on +XPStyle on +ShowInstDetails show +VIProductVersion 0.3.0.0 +VIAddVersionKey ProductName Bitcoin +VIAddVersionKey ProductVersion "${VERSION}" +VIAddVersionKey CompanyName "${COMPANY}" +VIAddVersionKey CompanyWebsite "${URL}" +VIAddVersionKey FileVersion "${VERSION}" +VIAddVersionKey FileDescription "" +VIAddVersionKey LegalCopyright "" +InstallDirRegKey HKCU "${REGKEY}" Path +ShowUninstDetails show + +# Installer sections +Section -Main SEC0000 + SetOutPath $INSTDIR + SetOverwrite on + File bitcoin.exe + File libeay32.dll + File mingwm10.dll + File license.txt + File readme.txt + SetOutPath $INSTDIR\daemon + File /r daemon\*.* + SetOutPath $INSTDIR\locale + File /r locale\*.* + SetOutPath $INSTDIR\src + File /r src\*.* + SetOutPath $INSTDIR + WriteRegStr HKCU "${REGKEY}\Components" Main 1 +SectionEnd + +Section -post SEC0001 + WriteRegStr HKCU "${REGKEY}" Path $INSTDIR + SetOutPath $INSTDIR + WriteUninstaller $INSTDIR\uninstall.exe + !insertmacro MUI_STARTMENU_WRITE_BEGIN Application + CreateDirectory $SMPROGRAMS\$StartMenuGroup + CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Bitcoin.lnk" $INSTDIR\bitcoin.exe + CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Uninstall Bitcoin.lnk" $INSTDIR\uninstall.exe + !insertmacro MUI_STARTMENU_WRITE_END + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayName "$(^Name)" + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayVersion "${VERSION}" + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" Publisher "${COMPANY}" + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" URLInfoAbout "${URL}" + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayIcon $INSTDIR\uninstall.exe + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" UninstallString $INSTDIR\uninstall.exe + WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoModify 1 + WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoRepair 1 +SectionEnd + +# Macro for selecting uninstaller sections +!macro SELECT_UNSECTION SECTION_NAME UNSECTION_ID + Push $R0 + ReadRegStr $R0 HKCU "${REGKEY}\Components" "${SECTION_NAME}" + StrCmp $R0 1 0 next${UNSECTION_ID} + !insertmacro SelectSection "${UNSECTION_ID}" + GoTo done${UNSECTION_ID} +next${UNSECTION_ID}: + !insertmacro UnselectSection "${UNSECTION_ID}" +done${UNSECTION_ID}: + Pop $R0 +!macroend + +# Uninstaller sections +Section /o -un.Main UNSEC0000 + Delete /REBOOTOK $INSTDIR\bitcoin.exe + Delete /REBOOTOK $INSTDIR\libeay32.dll + Delete /REBOOTOK $INSTDIR\mingwm10.dll + Delete /REBOOTOK $INSTDIR\license.txt + Delete /REBOOTOK $INSTDIR\readme.txt + RMDir /r /REBOOTOK $INSTDIR\daemon + RMDir /r /REBOOTOK $INSTDIR\locale + RMDir /r /REBOOTOK $INSTDIR\src + DeleteRegValue HKCU "${REGKEY}\Components" Main +SectionEnd + +Section -un.post UNSEC0001 + DeleteRegKey HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" + Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Uninstall Bitcoin.lnk" + Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Bitcoin.lnk" + Delete /REBOOTOK "$SMSTARTUP\Bitcoin.lnk" + Delete /REBOOTOK $INSTDIR\uninstall.exe + Delete /REBOOTOK $INSTDIR\debug.log + Delete /REBOOTOK $INSTDIR\db.log + DeleteRegValue HKCU "${REGKEY}" StartMenuGroup + DeleteRegValue HKCU "${REGKEY}" Path + DeleteRegKey /IfEmpty HKCU "${REGKEY}\Components" + DeleteRegKey /IfEmpty HKCU "${REGKEY}" + RmDir /REBOOTOK $SMPROGRAMS\$StartMenuGroup + RmDir /REBOOTOK $INSTDIR + Push $R0 + StrCpy $R0 $StartMenuGroup 1 + StrCmp $R0 ">" no_smgroup +no_smgroup: + Pop $R0 +SectionEnd + +# Installer functions +Function .onInit + InitPluginsDir +FunctionEnd + +# Uninstaller functions +Function un.onInit + ReadRegStr $INSTDIR HKCU "${REGKEY}" Path + !insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuGroup + !insertmacro SELECT_UNSECTION Main ${UNSEC0000} +FunctionEnd @@ -1,554 +1,554 @@ -// This file is public domain
-// SHA routines extracted as a standalone file from:
-// Crypto++: a C++ Class Library of Cryptographic Schemes
-// Version 5.5.2 (9/24/2007)
-// http://www.cryptopp.com
-
-// sha.cpp - modified by Wei Dai from Steve Reid's public domain sha1.c
-
-// Steve Reid implemented SHA-1. Wei Dai implemented SHA-2.
-// Both are in the public domain.
-
-#include <assert.h>
-#include <memory.h>
-#include "sha.h"
-
-namespace CryptoPP
-{
-
-// start of Steve Reid's code
-
-#define blk0(i) (W[i] = data[i])
-#define blk1(i) (W[i&15] = rotlFixed(W[(i+13)&15]^W[(i+8)&15]^W[(i+2)&15]^W[i&15],1))
-
-void SHA1::InitState(HashWordType *state)
-{
- state[0] = 0x67452301L;
- state[1] = 0xEFCDAB89L;
- state[2] = 0x98BADCFEL;
- state[3] = 0x10325476L;
- state[4] = 0xC3D2E1F0L;
-}
-
-#define f1(x,y,z) (z^(x&(y^z)))
-#define f2(x,y,z) (x^y^z)
-#define f3(x,y,z) ((x&y)|(z&(x|y)))
-#define f4(x,y,z) (x^y^z)
-
-/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
-#define R0(v,w,x,y,z,i) z+=f1(w,x,y)+blk0(i)+0x5A827999+rotlFixed(v,5);w=rotlFixed(w,30);
-#define R1(v,w,x,y,z,i) z+=f1(w,x,y)+blk1(i)+0x5A827999+rotlFixed(v,5);w=rotlFixed(w,30);
-#define R2(v,w,x,y,z,i) z+=f2(w,x,y)+blk1(i)+0x6ED9EBA1+rotlFixed(v,5);w=rotlFixed(w,30);
-#define R3(v,w,x,y,z,i) z+=f3(w,x,y)+blk1(i)+0x8F1BBCDC+rotlFixed(v,5);w=rotlFixed(w,30);
-#define R4(v,w,x,y,z,i) z+=f4(w,x,y)+blk1(i)+0xCA62C1D6+rotlFixed(v,5);w=rotlFixed(w,30);
-
-void SHA1::Transform(word32 *state, const word32 *data)
-{
- word32 W[16];
- /* Copy context->state[] to working vars */
- word32 a = state[0];
- word32 b = state[1];
- word32 c = state[2];
- word32 d = state[3];
- word32 e = state[4];
- /* 4 rounds of 20 operations each. Loop unrolled. */
- R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
- R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
- R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
- R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
- R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
- R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
- R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
- R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
- R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
- R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
- R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
- R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
- R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
- R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
- R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
- R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
- R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
- R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
- R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
- R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
- /* Add the working vars back into context.state[] */
- state[0] += a;
- state[1] += b;
- state[2] += c;
- state[3] += d;
- state[4] += e;
-}
-
-// end of Steve Reid's code
-
-// *************************************************************
-
-void SHA224::InitState(HashWordType *state)
-{
- static const word32 s[8] = {0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4};
- memcpy(state, s, sizeof(s));
-}
-
-void SHA256::InitState(HashWordType *state)
-{
- static const word32 s[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
- memcpy(state, s, sizeof(s));
-}
-
-static const word32 SHA256_K[64] = {
- 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
- 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
- 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
- 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
- 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
- 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
- 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
- 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
- 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
- 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
- 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
- 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
- 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
- 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
- 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
- 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
-};
-
-#define blk2(i) (W[i&15]+=s1(W[(i-2)&15])+W[(i-7)&15]+s0(W[(i-15)&15]))
-
-#define Ch(x,y,z) (z^(x&(y^z)))
-#define Maj(x,y,z) ((x&y)|(z&(x|y)))
-
-#define a(i) T[(0-i)&7]
-#define b(i) T[(1-i)&7]
-#define c(i) T[(2-i)&7]
-#define d(i) T[(3-i)&7]
-#define e(i) T[(4-i)&7]
-#define f(i) T[(5-i)&7]
-#define g(i) T[(6-i)&7]
-#define h(i) T[(7-i)&7]
-
-#define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA256_K[i+j]+(j?blk2(i):blk0(i));\
- d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i))
-
-// for SHA256
-#define S0(x) (rotrFixed(x,2)^rotrFixed(x,13)^rotrFixed(x,22))
-#define S1(x) (rotrFixed(x,6)^rotrFixed(x,11)^rotrFixed(x,25))
-#define s0(x) (rotrFixed(x,7)^rotrFixed(x,18)^(x>>3))
-#define s1(x) (rotrFixed(x,17)^rotrFixed(x,19)^(x>>10))
-
-void SHA256::Transform(word32 *state, const word32 *data)
-{
- word32 W[16];
- word32 T[8];
- /* Copy context->state[] to working vars */
- memcpy(T, state, sizeof(T));
- /* 64 operations, partially loop unrolled */
- for (unsigned int j=0; j<64; j+=16)
- {
- R( 0); R( 1); R( 2); R( 3);
- R( 4); R( 5); R( 6); R( 7);
- R( 8); R( 9); R(10); R(11);
- R(12); R(13); R(14); R(15);
- }
- /* Add the working vars back into context.state[] */
- state[0] += a(0);
- state[1] += b(0);
- state[2] += c(0);
- state[3] += d(0);
- state[4] += e(0);
- state[5] += f(0);
- state[6] += g(0);
- state[7] += h(0);
-}
-
-/*
-// smaller but slower
-void SHA256_Transform(word32 *state, const word32 *data)
-{
- word32 T[20];
- word32 W[32];
- unsigned int i = 0, j = 0;
- word32 *t = T+8;
-
- memcpy(t, state, 8*4);
- word32 e = t[4], a = t[0];
-
- do
- {
- word32 w = data[j];
- W[j] = w;
- w += K[j];
- w += t[7];
- w += S1(e);
- w += Ch(e, t[5], t[6]);
- e = t[3] + w;
- t[3] = t[3+8] = e;
- w += S0(t[0]);
- a = w + Maj(a, t[1], t[2]);
- t[-1] = t[7] = a;
- --t;
- ++j;
- if (j%8 == 0)
- t += 8;
- } while (j<16);
-
- do
- {
- i = j&0xf;
- word32 w = s1(W[i+16-2]) + s0(W[i+16-15]) + W[i] + W[i+16-7];
- W[i+16] = W[i] = w;
- w += K[j];
- w += t[7];
- w += S1(e);
- w += Ch(e, t[5], t[6]);
- e = t[3] + w;
- t[3] = t[3+8] = e;
- w += S0(t[0]);
- a = w + Maj(a, t[1], t[2]);
- t[-1] = t[7] = a;
-
- w = s1(W[(i+1)+16-2]) + s0(W[(i+1)+16-15]) + W[(i+1)] + W[(i+1)+16-7];
- W[(i+1)+16] = W[(i+1)] = w;
- w += K[j+1];
- w += (t-1)[7];
- w += S1(e);
- w += Ch(e, (t-1)[5], (t-1)[6]);
- e = (t-1)[3] + w;
- (t-1)[3] = (t-1)[3+8] = e;
- w += S0((t-1)[0]);
- a = w + Maj(a, (t-1)[1], (t-1)[2]);
- (t-1)[-1] = (t-1)[7] = a;
-
- t-=2;
- j+=2;
- if (j%8 == 0)
- t += 8;
- } while (j<64);
-
- state[0] += a;
- state[1] += t[1];
- state[2] += t[2];
- state[3] += t[3];
- state[4] += e;
- state[5] += t[5];
- state[6] += t[6];
- state[7] += t[7];
-}
-*/
-
-#undef S0
-#undef S1
-#undef s0
-#undef s1
-#undef R
-
-// *************************************************************
-
-#ifdef WORD64_AVAILABLE
-
-void SHA384::InitState(HashWordType *state)
-{
- static const word64 s[8] = {
- W64LIT(0xcbbb9d5dc1059ed8), W64LIT(0x629a292a367cd507),
- W64LIT(0x9159015a3070dd17), W64LIT(0x152fecd8f70e5939),
- W64LIT(0x67332667ffc00b31), W64LIT(0x8eb44a8768581511),
- W64LIT(0xdb0c2e0d64f98fa7), W64LIT(0x47b5481dbefa4fa4)};
- memcpy(state, s, sizeof(s));
-}
-
-void SHA512::InitState(HashWordType *state)
-{
- static const word64 s[8] = {
- W64LIT(0x6a09e667f3bcc908), W64LIT(0xbb67ae8584caa73b),
- W64LIT(0x3c6ef372fe94f82b), W64LIT(0xa54ff53a5f1d36f1),
- W64LIT(0x510e527fade682d1), W64LIT(0x9b05688c2b3e6c1f),
- W64LIT(0x1f83d9abfb41bd6b), W64LIT(0x5be0cd19137e2179)};
- memcpy(state, s, sizeof(s));
-}
-
-CRYPTOPP_ALIGN_DATA(16) static const word64 SHA512_K[80] CRYPTOPP_SECTION_ALIGN16 = {
- W64LIT(0x428a2f98d728ae22), W64LIT(0x7137449123ef65cd),
- W64LIT(0xb5c0fbcfec4d3b2f), W64LIT(0xe9b5dba58189dbbc),
- W64LIT(0x3956c25bf348b538), W64LIT(0x59f111f1b605d019),
- W64LIT(0x923f82a4af194f9b), W64LIT(0xab1c5ed5da6d8118),
- W64LIT(0xd807aa98a3030242), W64LIT(0x12835b0145706fbe),
- W64LIT(0x243185be4ee4b28c), W64LIT(0x550c7dc3d5ffb4e2),
- W64LIT(0x72be5d74f27b896f), W64LIT(0x80deb1fe3b1696b1),
- W64LIT(0x9bdc06a725c71235), W64LIT(0xc19bf174cf692694),
- W64LIT(0xe49b69c19ef14ad2), W64LIT(0xefbe4786384f25e3),
- W64LIT(0x0fc19dc68b8cd5b5), W64LIT(0x240ca1cc77ac9c65),
- W64LIT(0x2de92c6f592b0275), W64LIT(0x4a7484aa6ea6e483),
- W64LIT(0x5cb0a9dcbd41fbd4), W64LIT(0x76f988da831153b5),
- W64LIT(0x983e5152ee66dfab), W64LIT(0xa831c66d2db43210),
- W64LIT(0xb00327c898fb213f), W64LIT(0xbf597fc7beef0ee4),
- W64LIT(0xc6e00bf33da88fc2), W64LIT(0xd5a79147930aa725),
- W64LIT(0x06ca6351e003826f), W64LIT(0x142929670a0e6e70),
- W64LIT(0x27b70a8546d22ffc), W64LIT(0x2e1b21385c26c926),
- W64LIT(0x4d2c6dfc5ac42aed), W64LIT(0x53380d139d95b3df),
- W64LIT(0x650a73548baf63de), W64LIT(0x766a0abb3c77b2a8),
- W64LIT(0x81c2c92e47edaee6), W64LIT(0x92722c851482353b),
- W64LIT(0xa2bfe8a14cf10364), W64LIT(0xa81a664bbc423001),
- W64LIT(0xc24b8b70d0f89791), W64LIT(0xc76c51a30654be30),
- W64LIT(0xd192e819d6ef5218), W64LIT(0xd69906245565a910),
- W64LIT(0xf40e35855771202a), W64LIT(0x106aa07032bbd1b8),
- W64LIT(0x19a4c116b8d2d0c8), W64LIT(0x1e376c085141ab53),
- W64LIT(0x2748774cdf8eeb99), W64LIT(0x34b0bcb5e19b48a8),
- W64LIT(0x391c0cb3c5c95a63), W64LIT(0x4ed8aa4ae3418acb),
- W64LIT(0x5b9cca4f7763e373), W64LIT(0x682e6ff3d6b2b8a3),
- W64LIT(0x748f82ee5defb2fc), W64LIT(0x78a5636f43172f60),
- W64LIT(0x84c87814a1f0ab72), W64LIT(0x8cc702081a6439ec),
- W64LIT(0x90befffa23631e28), W64LIT(0xa4506cebde82bde9),
- W64LIT(0xbef9a3f7b2c67915), W64LIT(0xc67178f2e372532b),
- W64LIT(0xca273eceea26619c), W64LIT(0xd186b8c721c0c207),
- W64LIT(0xeada7dd6cde0eb1e), W64LIT(0xf57d4f7fee6ed178),
- W64LIT(0x06f067aa72176fba), W64LIT(0x0a637dc5a2c898a6),
- W64LIT(0x113f9804bef90dae), W64LIT(0x1b710b35131c471b),
- W64LIT(0x28db77f523047d84), W64LIT(0x32caab7b40c72493),
- W64LIT(0x3c9ebe0a15c9bebc), W64LIT(0x431d67c49c100d4c),
- W64LIT(0x4cc5d4becb3e42b6), W64LIT(0x597f299cfc657e2a),
- W64LIT(0x5fcb6fab3ad6faec), W64LIT(0x6c44198c4a475817)
-};
-
-#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86
-// put assembly version in separate function, otherwise MSVC 2005 SP1 doesn't generate correct code for the non-assembly version
-CRYPTOPP_NAKED static void CRYPTOPP_FASTCALL SHA512_SSE2_Transform(word64 *state, const word64 *data)
-{
-#ifdef __GNUC__
- __asm__ __volatile__
- (
- ".intel_syntax noprefix;"
- AS1( push ebx)
- AS2( mov ebx, eax)
-#else
- AS1( push ebx)
- AS1( push esi)
- AS1( push edi)
- AS2( lea ebx, SHA512_K)
-#endif
-
- AS2( mov eax, esp)
- AS2( and esp, 0xfffffff0)
- AS2( sub esp, 27*16) // 17*16 for expanded data, 20*8 for state
- AS1( push eax)
- AS2( xor eax, eax)
- AS2( lea edi, [esp+4+8*8]) // start at middle of state buffer. will decrement pointer each round to avoid copying
- AS2( lea esi, [esp+4+20*8+8]) // 16-byte alignment, then add 8
-
- AS2( movq mm4, [ecx+0*8])
- AS2( movq [edi+0*8], mm4)
- AS2( movq mm0, [ecx+1*8])
- AS2( movq [edi+1*8], mm0)
- AS2( movq mm0, [ecx+2*8])
- AS2( movq [edi+2*8], mm0)
- AS2( movq mm0, [ecx+3*8])
- AS2( movq [edi+3*8], mm0)
- AS2( movq mm5, [ecx+4*8])
- AS2( movq [edi+4*8], mm5)
- AS2( movq mm0, [ecx+5*8])
- AS2( movq [edi+5*8], mm0)
- AS2( movq mm0, [ecx+6*8])
- AS2( movq [edi+6*8], mm0)
- AS2( movq mm0, [ecx+7*8])
- AS2( movq [edi+7*8], mm0)
- ASJ( jmp, 0, f)
-
-#define SSE2_S0_S1(r, a, b, c) \
- AS2( movq mm6, r)\
- AS2( psrlq r, a)\
- AS2( movq mm7, r)\
- AS2( psllq mm6, 64-c)\
- AS2( pxor mm7, mm6)\
- AS2( psrlq r, b-a)\
- AS2( pxor mm7, r)\
- AS2( psllq mm6, c-b)\
- AS2( pxor mm7, mm6)\
- AS2( psrlq r, c-b)\
- AS2( pxor r, mm7)\
- AS2( psllq mm6, b-a)\
- AS2( pxor r, mm6)
-
-#define SSE2_s0(r, a, b, c) \
- AS2( movdqa xmm6, r)\
- AS2( psrlq r, a)\
- AS2( movdqa xmm7, r)\
- AS2( psllq xmm6, 64-c)\
- AS2( pxor xmm7, xmm6)\
- AS2( psrlq r, b-a)\
- AS2( pxor xmm7, r)\
- AS2( psrlq r, c-b)\
- AS2( pxor r, xmm7)\
- AS2( psllq xmm6, c-a)\
- AS2( pxor r, xmm6)
-
-#define SSE2_s1(r, a, b, c) \
- AS2( movdqa xmm6, r)\
- AS2( psrlq r, a)\
- AS2( movdqa xmm7, r)\
- AS2( psllq xmm6, 64-c)\
- AS2( pxor xmm7, xmm6)\
- AS2( psrlq r, b-a)\
- AS2( pxor xmm7, r)\
- AS2( psllq xmm6, c-b)\
- AS2( pxor xmm7, xmm6)\
- AS2( psrlq r, c-b)\
- AS2( pxor r, xmm7)
-
- ASL(SHA512_Round)
- // k + w is in mm0, a is in mm4, e is in mm5
- AS2( paddq mm0, [edi+7*8]) // h
- AS2( movq mm2, [edi+5*8]) // f
- AS2( movq mm3, [edi+6*8]) // g
- AS2( pxor mm2, mm3)
- AS2( pand mm2, mm5)
- SSE2_S0_S1(mm5,14,18,41)
- AS2( pxor mm2, mm3)
- AS2( paddq mm0, mm2) // h += Ch(e,f,g)
- AS2( paddq mm5, mm0) // h += S1(e)
- AS2( movq mm2, [edi+1*8]) // b
- AS2( movq mm1, mm2)
- AS2( por mm2, mm4)
- AS2( pand mm2, [edi+2*8]) // c
- AS2( pand mm1, mm4)
- AS2( por mm1, mm2)
- AS2( paddq mm1, mm5) // temp = h + Maj(a,b,c)
- AS2( paddq mm5, [edi+3*8]) // e = d + h
- AS2( movq [edi+3*8], mm5)
- AS2( movq [edi+11*8], mm5)
- SSE2_S0_S1(mm4,28,34,39) // S0(a)
- AS2( paddq mm4, mm1) // a = temp + S0(a)
- AS2( movq [edi-8], mm4)
- AS2( movq [edi+7*8], mm4)
- AS1( ret)
-
- // first 16 rounds
- ASL(0)
- AS2( movq mm0, [edx+eax*8])
- AS2( movq [esi+eax*8], mm0)
- AS2( movq [esi+eax*8+16*8], mm0)
- AS2( paddq mm0, [ebx+eax*8])
- ASC( call, SHA512_Round)
- AS1( inc eax)
- AS2( sub edi, 8)
- AS2( test eax, 7)
- ASJ( jnz, 0, b)
- AS2( add edi, 8*8)
- AS2( cmp eax, 16)
- ASJ( jne, 0, b)
-
- // rest of the rounds
- AS2( movdqu xmm0, [esi+(16-2)*8])
- ASL(1)
- // data expansion, W[i-2] already in xmm0
- AS2( movdqu xmm3, [esi])
- AS2( paddq xmm3, [esi+(16-7)*8])
- AS2( movdqa xmm2, [esi+(16-15)*8])
- SSE2_s1(xmm0, 6, 19, 61)
- AS2( paddq xmm0, xmm3)
- SSE2_s0(xmm2, 1, 7, 8)
- AS2( paddq xmm0, xmm2)
- AS2( movdq2q mm0, xmm0)
- AS2( movhlps xmm1, xmm0)
- AS2( paddq mm0, [ebx+eax*8])
- AS2( movlps [esi], xmm0)
- AS2( movlps [esi+8], xmm1)
- AS2( movlps [esi+8*16], xmm0)
- AS2( movlps [esi+8*17], xmm1)
- // 2 rounds
- ASC( call, SHA512_Round)
- AS2( sub edi, 8)
- AS2( movdq2q mm0, xmm1)
- AS2( paddq mm0, [ebx+eax*8+8])
- ASC( call, SHA512_Round)
- // update indices and loop
- AS2( add esi, 16)
- AS2( add eax, 2)
- AS2( sub edi, 8)
- AS2( test eax, 7)
- ASJ( jnz, 1, b)
- // do housekeeping every 8 rounds
- AS2( mov esi, 0xf)
- AS2( and esi, eax)
- AS2( lea esi, [esp+4+20*8+8+esi*8])
- AS2( add edi, 8*8)
- AS2( cmp eax, 80)
- ASJ( jne, 1, b)
-
-#define SSE2_CombineState(i) \
- AS2( movq mm0, [edi+i*8])\
- AS2( paddq mm0, [ecx+i*8])\
- AS2( movq [ecx+i*8], mm0)
-
- SSE2_CombineState(0)
- SSE2_CombineState(1)
- SSE2_CombineState(2)
- SSE2_CombineState(3)
- SSE2_CombineState(4)
- SSE2_CombineState(5)
- SSE2_CombineState(6)
- SSE2_CombineState(7)
-
- AS1( pop esp)
- AS1( emms)
-
-#if defined(__GNUC__)
- AS1( pop ebx)
- ".att_syntax prefix;"
- :
- : "a" (SHA512_K), "c" (state), "d" (data)
- : "%esi", "%edi", "memory", "cc"
- );
-#else
- AS1( pop edi)
- AS1( pop esi)
- AS1( pop ebx)
- AS1( ret)
-#endif
-}
-#endif // #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
-
-void SHA512::Transform(word64 *state, const word64 *data)
-{
-#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86
- if (HasSSE2())
- {
- SHA512_SSE2_Transform(state, data);
- return;
- }
-#endif
-
-#define S0(x) (rotrFixed(x,28)^rotrFixed(x,34)^rotrFixed(x,39))
-#define S1(x) (rotrFixed(x,14)^rotrFixed(x,18)^rotrFixed(x,41))
-#define s0(x) (rotrFixed(x,1)^rotrFixed(x,8)^(x>>7))
-#define s1(x) (rotrFixed(x,19)^rotrFixed(x,61)^(x>>6))
-
-#define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA512_K[i+j]+(j?blk2(i):blk0(i));\
- d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i))
-
- word64 W[16];
- word64 T[8];
- /* Copy context->state[] to working vars */
- memcpy(T, state, sizeof(T));
- /* 80 operations, partially loop unrolled */
- for (unsigned int j=0; j<80; j+=16)
- {
- R( 0); R( 1); R( 2); R( 3);
- R( 4); R( 5); R( 6); R( 7);
- R( 8); R( 9); R(10); R(11);
- R(12); R(13); R(14); R(15);
- }
- /* Add the working vars back into context.state[] */
- state[0] += a(0);
- state[1] += b(0);
- state[2] += c(0);
- state[3] += d(0);
- state[4] += e(0);
- state[5] += f(0);
- state[6] += g(0);
- state[7] += h(0);
-}
-
-#endif
-
-}
+// This file is public domain +// SHA routines extracted as a standalone file from: +// Crypto++: a C++ Class Library of Cryptographic Schemes +// Version 5.5.2 (9/24/2007) +// http://www.cryptopp.com + +// sha.cpp - modified by Wei Dai from Steve Reid's public domain sha1.c + +// Steve Reid implemented SHA-1. Wei Dai implemented SHA-2. +// Both are in the public domain. + +#include <assert.h> +#include <memory.h> +#include "sha.h" + +namespace CryptoPP +{ + +// start of Steve Reid's code + +#define blk0(i) (W[i] = data[i]) +#define blk1(i) (W[i&15] = rotlFixed(W[(i+13)&15]^W[(i+8)&15]^W[(i+2)&15]^W[i&15],1)) + +void SHA1::InitState(HashWordType *state) +{ + state[0] = 0x67452301L; + state[1] = 0xEFCDAB89L; + state[2] = 0x98BADCFEL; + state[3] = 0x10325476L; + state[4] = 0xC3D2E1F0L; +} + +#define f1(x,y,z) (z^(x&(y^z))) +#define f2(x,y,z) (x^y^z) +#define f3(x,y,z) ((x&y)|(z&(x|y))) +#define f4(x,y,z) (x^y^z) + +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ +#define R0(v,w,x,y,z,i) z+=f1(w,x,y)+blk0(i)+0x5A827999+rotlFixed(v,5);w=rotlFixed(w,30); +#define R1(v,w,x,y,z,i) z+=f1(w,x,y)+blk1(i)+0x5A827999+rotlFixed(v,5);w=rotlFixed(w,30); +#define R2(v,w,x,y,z,i) z+=f2(w,x,y)+blk1(i)+0x6ED9EBA1+rotlFixed(v,5);w=rotlFixed(w,30); +#define R3(v,w,x,y,z,i) z+=f3(w,x,y)+blk1(i)+0x8F1BBCDC+rotlFixed(v,5);w=rotlFixed(w,30); +#define R4(v,w,x,y,z,i) z+=f4(w,x,y)+blk1(i)+0xCA62C1D6+rotlFixed(v,5);w=rotlFixed(w,30); + +void SHA1::Transform(word32 *state, const word32 *data) +{ + word32 W[16]; + /* Copy context->state[] to working vars */ + word32 a = state[0]; + word32 b = state[1]; + word32 c = state[2]; + word32 d = state[3]; + word32 e = state[4]; + /* 4 rounds of 20 operations each. Loop unrolled. */ + R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); + R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); + R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); + R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); + R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); + R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); + R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); + R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); + R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); + R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); + R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); + R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); + R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); + R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); + R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); + R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); + R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); + R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); + R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); + R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); + /* Add the working vars back into context.state[] */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; +} + +// end of Steve Reid's code + +// ************************************************************* + +void SHA224::InitState(HashWordType *state) +{ + static const word32 s[8] = {0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4}; + memcpy(state, s, sizeof(s)); +} + +void SHA256::InitState(HashWordType *state) +{ + static const word32 s[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; + memcpy(state, s, sizeof(s)); +} + +static const word32 SHA256_K[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + +#define blk2(i) (W[i&15]+=s1(W[(i-2)&15])+W[(i-7)&15]+s0(W[(i-15)&15])) + +#define Ch(x,y,z) (z^(x&(y^z))) +#define Maj(x,y,z) ((x&y)|(z&(x|y))) + +#define a(i) T[(0-i)&7] +#define b(i) T[(1-i)&7] +#define c(i) T[(2-i)&7] +#define d(i) T[(3-i)&7] +#define e(i) T[(4-i)&7] +#define f(i) T[(5-i)&7] +#define g(i) T[(6-i)&7] +#define h(i) T[(7-i)&7] + +#define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA256_K[i+j]+(j?blk2(i):blk0(i));\ + d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i)) + +// for SHA256 +#define S0(x) (rotrFixed(x,2)^rotrFixed(x,13)^rotrFixed(x,22)) +#define S1(x) (rotrFixed(x,6)^rotrFixed(x,11)^rotrFixed(x,25)) +#define s0(x) (rotrFixed(x,7)^rotrFixed(x,18)^(x>>3)) +#define s1(x) (rotrFixed(x,17)^rotrFixed(x,19)^(x>>10)) + +void SHA256::Transform(word32 *state, const word32 *data) +{ + word32 W[16]; + word32 T[8]; + /* Copy context->state[] to working vars */ + memcpy(T, state, sizeof(T)); + /* 64 operations, partially loop unrolled */ + for (unsigned int j=0; j<64; j+=16) + { + R( 0); R( 1); R( 2); R( 3); + R( 4); R( 5); R( 6); R( 7); + R( 8); R( 9); R(10); R(11); + R(12); R(13); R(14); R(15); + } + /* Add the working vars back into context.state[] */ + state[0] += a(0); + state[1] += b(0); + state[2] += c(0); + state[3] += d(0); + state[4] += e(0); + state[5] += f(0); + state[6] += g(0); + state[7] += h(0); +} + +/* +// smaller but slower +void SHA256_Transform(word32 *state, const word32 *data) +{ + word32 T[20]; + word32 W[32]; + unsigned int i = 0, j = 0; + word32 *t = T+8; + + memcpy(t, state, 8*4); + word32 e = t[4], a = t[0]; + + do + { + word32 w = data[j]; + W[j] = w; + w += K[j]; + w += t[7]; + w += S1(e); + w += Ch(e, t[5], t[6]); + e = t[3] + w; + t[3] = t[3+8] = e; + w += S0(t[0]); + a = w + Maj(a, t[1], t[2]); + t[-1] = t[7] = a; + --t; + ++j; + if (j%8 == 0) + t += 8; + } while (j<16); + + do + { + i = j&0xf; + word32 w = s1(W[i+16-2]) + s0(W[i+16-15]) + W[i] + W[i+16-7]; + W[i+16] = W[i] = w; + w += K[j]; + w += t[7]; + w += S1(e); + w += Ch(e, t[5], t[6]); + e = t[3] + w; + t[3] = t[3+8] = e; + w += S0(t[0]); + a = w + Maj(a, t[1], t[2]); + t[-1] = t[7] = a; + + w = s1(W[(i+1)+16-2]) + s0(W[(i+1)+16-15]) + W[(i+1)] + W[(i+1)+16-7]; + W[(i+1)+16] = W[(i+1)] = w; + w += K[j+1]; + w += (t-1)[7]; + w += S1(e); + w += Ch(e, (t-1)[5], (t-1)[6]); + e = (t-1)[3] + w; + (t-1)[3] = (t-1)[3+8] = e; + w += S0((t-1)[0]); + a = w + Maj(a, (t-1)[1], (t-1)[2]); + (t-1)[-1] = (t-1)[7] = a; + + t-=2; + j+=2; + if (j%8 == 0) + t += 8; + } while (j<64); + + state[0] += a; + state[1] += t[1]; + state[2] += t[2]; + state[3] += t[3]; + state[4] += e; + state[5] += t[5]; + state[6] += t[6]; + state[7] += t[7]; +} +*/ + +#undef S0 +#undef S1 +#undef s0 +#undef s1 +#undef R + +// ************************************************************* + +#ifdef WORD64_AVAILABLE + +void SHA384::InitState(HashWordType *state) +{ + static const word64 s[8] = { + W64LIT(0xcbbb9d5dc1059ed8), W64LIT(0x629a292a367cd507), + W64LIT(0x9159015a3070dd17), W64LIT(0x152fecd8f70e5939), + W64LIT(0x67332667ffc00b31), W64LIT(0x8eb44a8768581511), + W64LIT(0xdb0c2e0d64f98fa7), W64LIT(0x47b5481dbefa4fa4)}; + memcpy(state, s, sizeof(s)); +} + +void SHA512::InitState(HashWordType *state) +{ + static const word64 s[8] = { + W64LIT(0x6a09e667f3bcc908), W64LIT(0xbb67ae8584caa73b), + W64LIT(0x3c6ef372fe94f82b), W64LIT(0xa54ff53a5f1d36f1), + W64LIT(0x510e527fade682d1), W64LIT(0x9b05688c2b3e6c1f), + W64LIT(0x1f83d9abfb41bd6b), W64LIT(0x5be0cd19137e2179)}; + memcpy(state, s, sizeof(s)); +} + +CRYPTOPP_ALIGN_DATA(16) static const word64 SHA512_K[80] CRYPTOPP_SECTION_ALIGN16 = { + W64LIT(0x428a2f98d728ae22), W64LIT(0x7137449123ef65cd), + W64LIT(0xb5c0fbcfec4d3b2f), W64LIT(0xe9b5dba58189dbbc), + W64LIT(0x3956c25bf348b538), W64LIT(0x59f111f1b605d019), + W64LIT(0x923f82a4af194f9b), W64LIT(0xab1c5ed5da6d8118), + W64LIT(0xd807aa98a3030242), W64LIT(0x12835b0145706fbe), + W64LIT(0x243185be4ee4b28c), W64LIT(0x550c7dc3d5ffb4e2), + W64LIT(0x72be5d74f27b896f), W64LIT(0x80deb1fe3b1696b1), + W64LIT(0x9bdc06a725c71235), W64LIT(0xc19bf174cf692694), + W64LIT(0xe49b69c19ef14ad2), W64LIT(0xefbe4786384f25e3), + W64LIT(0x0fc19dc68b8cd5b5), W64LIT(0x240ca1cc77ac9c65), + W64LIT(0x2de92c6f592b0275), W64LIT(0x4a7484aa6ea6e483), + W64LIT(0x5cb0a9dcbd41fbd4), W64LIT(0x76f988da831153b5), + W64LIT(0x983e5152ee66dfab), W64LIT(0xa831c66d2db43210), + W64LIT(0xb00327c898fb213f), W64LIT(0xbf597fc7beef0ee4), + W64LIT(0xc6e00bf33da88fc2), W64LIT(0xd5a79147930aa725), + W64LIT(0x06ca6351e003826f), W64LIT(0x142929670a0e6e70), + W64LIT(0x27b70a8546d22ffc), W64LIT(0x2e1b21385c26c926), + W64LIT(0x4d2c6dfc5ac42aed), W64LIT(0x53380d139d95b3df), + W64LIT(0x650a73548baf63de), W64LIT(0x766a0abb3c77b2a8), + W64LIT(0x81c2c92e47edaee6), W64LIT(0x92722c851482353b), + W64LIT(0xa2bfe8a14cf10364), W64LIT(0xa81a664bbc423001), + W64LIT(0xc24b8b70d0f89791), W64LIT(0xc76c51a30654be30), + W64LIT(0xd192e819d6ef5218), W64LIT(0xd69906245565a910), + W64LIT(0xf40e35855771202a), W64LIT(0x106aa07032bbd1b8), + W64LIT(0x19a4c116b8d2d0c8), W64LIT(0x1e376c085141ab53), + W64LIT(0x2748774cdf8eeb99), W64LIT(0x34b0bcb5e19b48a8), + W64LIT(0x391c0cb3c5c95a63), W64LIT(0x4ed8aa4ae3418acb), + W64LIT(0x5b9cca4f7763e373), W64LIT(0x682e6ff3d6b2b8a3), + W64LIT(0x748f82ee5defb2fc), W64LIT(0x78a5636f43172f60), + W64LIT(0x84c87814a1f0ab72), W64LIT(0x8cc702081a6439ec), + W64LIT(0x90befffa23631e28), W64LIT(0xa4506cebde82bde9), + W64LIT(0xbef9a3f7b2c67915), W64LIT(0xc67178f2e372532b), + W64LIT(0xca273eceea26619c), W64LIT(0xd186b8c721c0c207), + W64LIT(0xeada7dd6cde0eb1e), W64LIT(0xf57d4f7fee6ed178), + W64LIT(0x06f067aa72176fba), W64LIT(0x0a637dc5a2c898a6), + W64LIT(0x113f9804bef90dae), W64LIT(0x1b710b35131c471b), + W64LIT(0x28db77f523047d84), W64LIT(0x32caab7b40c72493), + W64LIT(0x3c9ebe0a15c9bebc), W64LIT(0x431d67c49c100d4c), + W64LIT(0x4cc5d4becb3e42b6), W64LIT(0x597f299cfc657e2a), + W64LIT(0x5fcb6fab3ad6faec), W64LIT(0x6c44198c4a475817) +}; + +#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86 +// put assembly version in separate function, otherwise MSVC 2005 SP1 doesn't generate correct code for the non-assembly version +CRYPTOPP_NAKED static void CRYPTOPP_FASTCALL SHA512_SSE2_Transform(word64 *state, const word64 *data) +{ +#ifdef __GNUC__ + __asm__ __volatile__ + ( + ".intel_syntax noprefix;" + AS1( push ebx) + AS2( mov ebx, eax) +#else + AS1( push ebx) + AS1( push esi) + AS1( push edi) + AS2( lea ebx, SHA512_K) +#endif + + AS2( mov eax, esp) + AS2( and esp, 0xfffffff0) + AS2( sub esp, 27*16) // 17*16 for expanded data, 20*8 for state + AS1( push eax) + AS2( xor eax, eax) + AS2( lea edi, [esp+4+8*8]) // start at middle of state buffer. will decrement pointer each round to avoid copying + AS2( lea esi, [esp+4+20*8+8]) // 16-byte alignment, then add 8 + + AS2( movq mm4, [ecx+0*8]) + AS2( movq [edi+0*8], mm4) + AS2( movq mm0, [ecx+1*8]) + AS2( movq [edi+1*8], mm0) + AS2( movq mm0, [ecx+2*8]) + AS2( movq [edi+2*8], mm0) + AS2( movq mm0, [ecx+3*8]) + AS2( movq [edi+3*8], mm0) + AS2( movq mm5, [ecx+4*8]) + AS2( movq [edi+4*8], mm5) + AS2( movq mm0, [ecx+5*8]) + AS2( movq [edi+5*8], mm0) + AS2( movq mm0, [ecx+6*8]) + AS2( movq [edi+6*8], mm0) + AS2( movq mm0, [ecx+7*8]) + AS2( movq [edi+7*8], mm0) + ASJ( jmp, 0, f) + +#define SSE2_S0_S1(r, a, b, c) \ + AS2( movq mm6, r)\ + AS2( psrlq r, a)\ + AS2( movq mm7, r)\ + AS2( psllq mm6, 64-c)\ + AS2( pxor mm7, mm6)\ + AS2( psrlq r, b-a)\ + AS2( pxor mm7, r)\ + AS2( psllq mm6, c-b)\ + AS2( pxor mm7, mm6)\ + AS2( psrlq r, c-b)\ + AS2( pxor r, mm7)\ + AS2( psllq mm6, b-a)\ + AS2( pxor r, mm6) + +#define SSE2_s0(r, a, b, c) \ + AS2( movdqa xmm6, r)\ + AS2( psrlq r, a)\ + AS2( movdqa xmm7, r)\ + AS2( psllq xmm6, 64-c)\ + AS2( pxor xmm7, xmm6)\ + AS2( psrlq r, b-a)\ + AS2( pxor xmm7, r)\ + AS2( psrlq r, c-b)\ + AS2( pxor r, xmm7)\ + AS2( psllq xmm6, c-a)\ + AS2( pxor r, xmm6) + +#define SSE2_s1(r, a, b, c) \ + AS2( movdqa xmm6, r)\ + AS2( psrlq r, a)\ + AS2( movdqa xmm7, r)\ + AS2( psllq xmm6, 64-c)\ + AS2( pxor xmm7, xmm6)\ + AS2( psrlq r, b-a)\ + AS2( pxor xmm7, r)\ + AS2( psllq xmm6, c-b)\ + AS2( pxor xmm7, xmm6)\ + AS2( psrlq r, c-b)\ + AS2( pxor r, xmm7) + + ASL(SHA512_Round) + // k + w is in mm0, a is in mm4, e is in mm5 + AS2( paddq mm0, [edi+7*8]) // h + AS2( movq mm2, [edi+5*8]) // f + AS2( movq mm3, [edi+6*8]) // g + AS2( pxor mm2, mm3) + AS2( pand mm2, mm5) + SSE2_S0_S1(mm5,14,18,41) + AS2( pxor mm2, mm3) + AS2( paddq mm0, mm2) // h += Ch(e,f,g) + AS2( paddq mm5, mm0) // h += S1(e) + AS2( movq mm2, [edi+1*8]) // b + AS2( movq mm1, mm2) + AS2( por mm2, mm4) + AS2( pand mm2, [edi+2*8]) // c + AS2( pand mm1, mm4) + AS2( por mm1, mm2) + AS2( paddq mm1, mm5) // temp = h + Maj(a,b,c) + AS2( paddq mm5, [edi+3*8]) // e = d + h + AS2( movq [edi+3*8], mm5) + AS2( movq [edi+11*8], mm5) + SSE2_S0_S1(mm4,28,34,39) // S0(a) + AS2( paddq mm4, mm1) // a = temp + S0(a) + AS2( movq [edi-8], mm4) + AS2( movq [edi+7*8], mm4) + AS1( ret) + + // first 16 rounds + ASL(0) + AS2( movq mm0, [edx+eax*8]) + AS2( movq [esi+eax*8], mm0) + AS2( movq [esi+eax*8+16*8], mm0) + AS2( paddq mm0, [ebx+eax*8]) + ASC( call, SHA512_Round) + AS1( inc eax) + AS2( sub edi, 8) + AS2( test eax, 7) + ASJ( jnz, 0, b) + AS2( add edi, 8*8) + AS2( cmp eax, 16) + ASJ( jne, 0, b) + + // rest of the rounds + AS2( movdqu xmm0, [esi+(16-2)*8]) + ASL(1) + // data expansion, W[i-2] already in xmm0 + AS2( movdqu xmm3, [esi]) + AS2( paddq xmm3, [esi+(16-7)*8]) + AS2( movdqa xmm2, [esi+(16-15)*8]) + SSE2_s1(xmm0, 6, 19, 61) + AS2( paddq xmm0, xmm3) + SSE2_s0(xmm2, 1, 7, 8) + AS2( paddq xmm0, xmm2) + AS2( movdq2q mm0, xmm0) + AS2( movhlps xmm1, xmm0) + AS2( paddq mm0, [ebx+eax*8]) + AS2( movlps [esi], xmm0) + AS2( movlps [esi+8], xmm1) + AS2( movlps [esi+8*16], xmm0) + AS2( movlps [esi+8*17], xmm1) + // 2 rounds + ASC( call, SHA512_Round) + AS2( sub edi, 8) + AS2( movdq2q mm0, xmm1) + AS2( paddq mm0, [ebx+eax*8+8]) + ASC( call, SHA512_Round) + // update indices and loop + AS2( add esi, 16) + AS2( add eax, 2) + AS2( sub edi, 8) + AS2( test eax, 7) + ASJ( jnz, 1, b) + // do housekeeping every 8 rounds + AS2( mov esi, 0xf) + AS2( and esi, eax) + AS2( lea esi, [esp+4+20*8+8+esi*8]) + AS2( add edi, 8*8) + AS2( cmp eax, 80) + ASJ( jne, 1, b) + +#define SSE2_CombineState(i) \ + AS2( movq mm0, [edi+i*8])\ + AS2( paddq mm0, [ecx+i*8])\ + AS2( movq [ecx+i*8], mm0) + + SSE2_CombineState(0) + SSE2_CombineState(1) + SSE2_CombineState(2) + SSE2_CombineState(3) + SSE2_CombineState(4) + SSE2_CombineState(5) + SSE2_CombineState(6) + SSE2_CombineState(7) + + AS1( pop esp) + AS1( emms) + +#if defined(__GNUC__) + AS1( pop ebx) + ".att_syntax prefix;" + : + : "a" (SHA512_K), "c" (state), "d" (data) + : "%esi", "%edi", "memory", "cc" + ); +#else + AS1( pop edi) + AS1( pop esi) + AS1( pop ebx) + AS1( ret) +#endif +} +#endif // #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE + +void SHA512::Transform(word64 *state, const word64 *data) +{ +#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86 + if (HasSSE2()) + { + SHA512_SSE2_Transform(state, data); + return; + } +#endif + +#define S0(x) (rotrFixed(x,28)^rotrFixed(x,34)^rotrFixed(x,39)) +#define S1(x) (rotrFixed(x,14)^rotrFixed(x,18)^rotrFixed(x,41)) +#define s0(x) (rotrFixed(x,1)^rotrFixed(x,8)^(x>>7)) +#define s1(x) (rotrFixed(x,19)^rotrFixed(x,61)^(x>>6)) + +#define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA512_K[i+j]+(j?blk2(i):blk0(i));\ + d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i)) + + word64 W[16]; + word64 T[8]; + /* Copy context->state[] to working vars */ + memcpy(T, state, sizeof(T)); + /* 80 operations, partially loop unrolled */ + for (unsigned int j=0; j<80; j+=16) + { + R( 0); R( 1); R( 2); R( 3); + R( 4); R( 5); R( 6); R( 7); + R( 8); R( 9); R(10); R(11); + R(12); R(13); R(14); R(15); + } + /* Add the working vars back into context.state[] */ + state[0] += a(0); + state[1] += b(0); + state[2] += c(0); + state[3] += d(0); + state[4] += e(0); + state[5] += f(0); + state[6] += g(0); + state[7] += h(0); +} + +#endif + +} @@ -1,177 +1,177 @@ -// This file is public domain
-// SHA routines extracted as a standalone file from:
-// Crypto++: a C++ Class Library of Cryptographic Schemes
-// Version 5.5.2 (9/24/2007)
-// http://www.cryptopp.com
-#ifndef CRYPTOPP_SHA_H
-#define CRYPTOPP_SHA_H
-#include <stdlib.h>
-
-namespace CryptoPP
-{
-
-//
-// Dependencies
-//
-
-typedef unsigned char byte;
-typedef unsigned short word16;
-typedef unsigned int word32;
-#if defined(_MSC_VER) || defined(__BORLANDC__)
-typedef unsigned __int64 word64;
-#else
-typedef unsigned long long word64;
-#endif
-
-template <class T> inline T rotlFixed(T x, unsigned int y)
-{
- assert(y < sizeof(T)*8);
- return T((x<<y) | (x>>(sizeof(T)*8-y)));
-}
-
-template <class T> inline T rotrFixed(T x, unsigned int y)
-{
- assert(y < sizeof(T)*8);
- return T((x>>y) | (x<<(sizeof(T)*8-y)));
-}
-
-// ************** endian reversal ***************
-
-#ifdef _MSC_VER
- #if _MSC_VER >= 1400
- #define CRYPTOPP_FAST_ROTATE(x) 1
- #elif _MSC_VER >= 1300
- #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32 | (x) == 64)
- #else
- #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32)
- #endif
-#elif (defined(__MWERKS__) && TARGET_CPU_PPC) || \
- (defined(__GNUC__) && (defined(_ARCH_PWR2) || defined(_ARCH_PWR) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || defined(_ARCH_COM)))
- #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32)
-#elif defined(__GNUC__) && (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86) // depend on GCC's peephole optimization to generate rotate instructions
- #define CRYPTOPP_FAST_ROTATE(x) 1
-#else
- #define CRYPTOPP_FAST_ROTATE(x) 0
-#endif
-
-inline byte ByteReverse(byte value)
-{
- return value;
-}
-
-inline word16 ByteReverse(word16 value)
-{
-#ifdef CRYPTOPP_BYTESWAP_AVAILABLE
- return bswap_16(value);
-#elif defined(_MSC_VER) && _MSC_VER >= 1300
- return _byteswap_ushort(value);
-#else
- return rotlFixed(value, 8U);
-#endif
-}
-
-inline word32 ByteReverse(word32 value)
-{
-#if defined(__GNUC__)
- __asm__ ("bswap %0" : "=r" (value) : "0" (value));
- return value;
-#elif defined(CRYPTOPP_BYTESWAP_AVAILABLE)
- return bswap_32(value);
-#elif defined(__MWERKS__) && TARGET_CPU_PPC
- return (word32)__lwbrx(&value,0);
-#elif _MSC_VER >= 1400 || (_MSC_VER >= 1300 && !defined(_DLL))
- return _byteswap_ulong(value);
-#elif CRYPTOPP_FAST_ROTATE(32)
- // 5 instructions with rotate instruction, 9 without
- return (rotrFixed(value, 8U) & 0xff00ff00) | (rotlFixed(value, 8U) & 0x00ff00ff);
-#else
- // 6 instructions with rotate instruction, 8 without
- value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
- return rotlFixed(value, 16U);
-#endif
-}
-
-#ifdef WORD64_AVAILABLE
-inline word64 ByteReverse(word64 value)
-{
-#if defined(__GNUC__) && defined(__x86_64__)
- __asm__ ("bswap %0" : "=r" (value) : "0" (value));
- return value;
-#elif defined(CRYPTOPP_BYTESWAP_AVAILABLE)
- return bswap_64(value);
-#elif defined(_MSC_VER) && _MSC_VER >= 1300
- return _byteswap_uint64(value);
-#elif defined(CRYPTOPP_SLOW_WORD64)
- return (word64(ByteReverse(word32(value))) << 32) | ByteReverse(word32(value>>32));
-#else
- value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) | ((value & W64LIT(0x00FF00FF00FF00FF)) << 8);
- value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) | ((value & W64LIT(0x0000FFFF0000FFFF)) << 16);
- return rotlFixed(value, 32U);
-#endif
-}
-#endif
-
-
-//
-// SHA
-//
-
-// http://www.weidai.com/scan-mirror/md.html#SHA-1
-class SHA1
-{
-public:
- typedef word32 HashWordType;
- static void InitState(word32 *state);
- static void Transform(word32 *digest, const word32 *data);
- static const char * StaticAlgorithmName() {return "SHA-1";}
-};
-
-typedef SHA1 SHA; // for backwards compatibility
-
-// implements the SHA-256 standard
-class SHA256
-{
-public:
- typedef word32 HashWordType;
- static void InitState(word32 *state);
- static void Transform(word32 *digest, const word32 *data);
- static const char * StaticAlgorithmName() {return "SHA-256";}
-};
-
-// implements the SHA-224 standard
-class SHA224
-{
-public:
- typedef word32 HashWordType;
- static void InitState(word32 *state);
- static void Transform(word32 *digest, const word32 *data) {SHA256::Transform(digest, data);}
- static const char * StaticAlgorithmName() {return "SHA-224";}
-};
-
-#ifdef WORD64_AVAILABLE
-
-// implements the SHA-512 standard
-class SHA512
-{
-public:
- typedef word64 HashWordType;
- static void InitState(word64 *state);
- static void Transform(word64 *digest, const word64 *data);
- static const char * StaticAlgorithmName() {return "SHA-512";}
-};
-
-// implements the SHA-384 standard
-class SHA384
-{
-public:
- typedef word64 HashWordType;
- static void InitState(word64 *state);
- static void Transform(word64 *digest, const word64 *data) {SHA512::Transform(digest, data);}
- static const char * StaticAlgorithmName() {return "SHA-384";}
-};
-
-#endif
-
-}
-
-#endif
+// This file is public domain +// SHA routines extracted as a standalone file from: +// Crypto++: a C++ Class Library of Cryptographic Schemes +// Version 5.5.2 (9/24/2007) +// http://www.cryptopp.com +#ifndef CRYPTOPP_SHA_H +#define CRYPTOPP_SHA_H +#include <stdlib.h> + +namespace CryptoPP +{ + +// +// Dependencies +// + +typedef unsigned char byte; +typedef unsigned short word16; +typedef unsigned int word32; +#if defined(_MSC_VER) || defined(__BORLANDC__) +typedef unsigned __int64 word64; +#else +typedef unsigned long long word64; +#endif + +template <class T> inline T rotlFixed(T x, unsigned int y) +{ + assert(y < sizeof(T)*8); + return T((x<<y) | (x>>(sizeof(T)*8-y))); +} + +template <class T> inline T rotrFixed(T x, unsigned int y) +{ + assert(y < sizeof(T)*8); + return T((x>>y) | (x<<(sizeof(T)*8-y))); +} + +// ************** endian reversal *************** + +#ifdef _MSC_VER + #if _MSC_VER >= 1400 + #define CRYPTOPP_FAST_ROTATE(x) 1 + #elif _MSC_VER >= 1300 + #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32 | (x) == 64) + #else + #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32) + #endif +#elif (defined(__MWERKS__) && TARGET_CPU_PPC) || \ + (defined(__GNUC__) && (defined(_ARCH_PWR2) || defined(_ARCH_PWR) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || defined(_ARCH_COM))) + #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32) +#elif defined(__GNUC__) && (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86) // depend on GCC's peephole optimization to generate rotate instructions + #define CRYPTOPP_FAST_ROTATE(x) 1 +#else + #define CRYPTOPP_FAST_ROTATE(x) 0 +#endif + +inline byte ByteReverse(byte value) +{ + return value; +} + +inline word16 ByteReverse(word16 value) +{ +#ifdef CRYPTOPP_BYTESWAP_AVAILABLE + return bswap_16(value); +#elif defined(_MSC_VER) && _MSC_VER >= 1300 + return _byteswap_ushort(value); +#else + return rotlFixed(value, 8U); +#endif +} + +inline word32 ByteReverse(word32 value) +{ +#if defined(__GNUC__) + __asm__ ("bswap %0" : "=r" (value) : "0" (value)); + return value; +#elif defined(CRYPTOPP_BYTESWAP_AVAILABLE) + return bswap_32(value); +#elif defined(__MWERKS__) && TARGET_CPU_PPC + return (word32)__lwbrx(&value,0); +#elif _MSC_VER >= 1400 || (_MSC_VER >= 1300 && !defined(_DLL)) + return _byteswap_ulong(value); +#elif CRYPTOPP_FAST_ROTATE(32) + // 5 instructions with rotate instruction, 9 without + return (rotrFixed(value, 8U) & 0xff00ff00) | (rotlFixed(value, 8U) & 0x00ff00ff); +#else + // 6 instructions with rotate instruction, 8 without + value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8); + return rotlFixed(value, 16U); +#endif +} + +#ifdef WORD64_AVAILABLE +inline word64 ByteReverse(word64 value) +{ +#if defined(__GNUC__) && defined(__x86_64__) + __asm__ ("bswap %0" : "=r" (value) : "0" (value)); + return value; +#elif defined(CRYPTOPP_BYTESWAP_AVAILABLE) + return bswap_64(value); +#elif defined(_MSC_VER) && _MSC_VER >= 1300 + return _byteswap_uint64(value); +#elif defined(CRYPTOPP_SLOW_WORD64) + return (word64(ByteReverse(word32(value))) << 32) | ByteReverse(word32(value>>32)); +#else + value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) | ((value & W64LIT(0x00FF00FF00FF00FF)) << 8); + value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) | ((value & W64LIT(0x0000FFFF0000FFFF)) << 16); + return rotlFixed(value, 32U); +#endif +} +#endif + + +// +// SHA +// + +// http://www.weidai.com/scan-mirror/md.html#SHA-1 +class SHA1 +{ +public: + typedef word32 HashWordType; + static void InitState(word32 *state); + static void Transform(word32 *digest, const word32 *data); + static const char * StaticAlgorithmName() {return "SHA-1";} +}; + +typedef SHA1 SHA; // for backwards compatibility + +// implements the SHA-256 standard +class SHA256 +{ +public: + typedef word32 HashWordType; + static void InitState(word32 *state); + static void Transform(word32 *digest, const word32 *data); + static const char * StaticAlgorithmName() {return "SHA-256";} +}; + +// implements the SHA-224 standard +class SHA224 +{ +public: + typedef word32 HashWordType; + static void InitState(word32 *state); + static void Transform(word32 *digest, const word32 *data) {SHA256::Transform(digest, data);} + static const char * StaticAlgorithmName() {return "SHA-224";} +}; + +#ifdef WORD64_AVAILABLE + +// implements the SHA-512 standard +class SHA512 +{ +public: + typedef word64 HashWordType; + static void InitState(word64 *state); + static void Transform(word64 *digest, const word64 *data); + static const char * StaticAlgorithmName() {return "SHA-512";} +}; + +// implements the SHA-384 standard +class SHA384 +{ +public: + typedef word64 HashWordType; + static void InitState(word64 *state); + static void Transform(word64 *digest, const word64 *data) {SHA512::Transform(digest, data);} + static const char * StaticAlgorithmName() {return "SHA-384";} +}; + +#endif + +} + +#endif @@ -1,84 +1,84 @@ -/*
- * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * Copy src to string dst of size siz. At most siz-1 characters
- * will be copied. Always NUL terminates (unless siz == 0).
- * Returns strlen(src); if retval >= siz, truncation occurred.
- */
-inline size_t strlcpy(char *dst, const char *src, size_t siz)
-{
- char *d = dst;
- const char *s = src;
- size_t n = siz;
-
- /* Copy as many bytes as will fit */
- if (n != 0)
- {
- while (--n != 0)
- {
- if ((*d++ = *s++) == '\0')
- break;
- }
- }
-
- /* Not enough room in dst, add NUL and traverse rest of src */
- if (n == 0)
- {
- if (siz != 0)
- *d = '\0'; /* NUL-terminate dst */
- while (*s++)
- ;
- }
-
- return(s - src - 1); /* count does not include NUL */
-}
-
-/*
- * Appends src to string dst of size siz (unlike strncat, siz is the
- * full size of dst, not space left). At most siz-1 characters
- * will be copied. Always NUL terminates (unless siz <= strlen(dst)).
- * Returns strlen(src) + MIN(siz, strlen(initial dst)).
- * If retval >= siz, truncation occurred.
- */
-inline size_t strlcat(char *dst, const char *src, size_t siz)
-{
- char *d = dst;
- const char *s = src;
- size_t n = siz;
- size_t dlen;
-
- /* Find the end of dst and adjust bytes left but don't go past end */
- while (n-- != 0 && *d != '\0')
- d++;
- dlen = d - dst;
- n = siz - dlen;
-
- if (n == 0)
- return(dlen + strlen(s));
- while (*s != '\0')
- {
- if (n != 1)
- {
- *d++ = *s;
- n--;
- }
- s++;
- }
- *d = '\0';
-
- return(dlen + (s - src)); /* count does not include NUL */
-}
+/* + * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Copy src to string dst of size siz. At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ +inline size_t strlcpy(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0) + { + while (--n != 0) + { + if ((*d++ = *s++) == '\0') + break; + } + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) + { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} + +/* + * Appends src to string dst of size siz (unlike strncat, siz is the + * full size of dst, not space left). At most siz-1 characters + * will be copied. Always NUL terminates (unless siz <= strlen(dst)). + * Returns strlen(src) + MIN(siz, strlen(initial dst)). + * If retval >= siz, truncation occurred. + */ +inline size_t strlcat(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (n-- != 0 && *d != '\0') + d++; + dlen = d - dst; + n = siz - dlen; + + if (n == 0) + return(dlen + strlen(s)); + while (*s != '\0') + { + if (n != 1) + { + *d++ = *s; + n--; + } + s++; + } + *d = '\0'; + + return(dlen + (s - src)); /* count does not include NUL */ +} @@ -1,2545 +1,2545 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
-
-#include "headers.h"
-#ifdef _MSC_VER
-#include <crtdbg.h>
-#endif
-
-
-
-DEFINE_EVENT_TYPE(wxEVT_UITHREADCALL)
-
-CMainFrame* pframeMain = NULL;
-CMyTaskBarIcon* ptaskbaricon = NULL;
-bool fClosedToTray = false;
-
-
-
-
-
-
-
-
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// Util
-//
-
-void HandleCtrlA(wxKeyEvent& event)
-{
- // Ctrl-a select all
- event.Skip();
- wxTextCtrl* textCtrl = (wxTextCtrl*)event.GetEventObject();
- if (event.GetModifiers() == wxMOD_CONTROL && event.GetKeyCode() == 'A')
- textCtrl->SetSelection(-1, -1);
-}
-
-bool Is24HourTime()
-{
- //char pszHourFormat[256];
- //pszHourFormat[0] = '\0';
- //GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ITIME, pszHourFormat, 256);
- //return (pszHourFormat[0] != '0');
- return true;
-}
-
-string DateStr(int64 nTime)
-{
- // Can only be used safely here in the UI
- return (string)wxDateTime((time_t)nTime).FormatDate();
-}
-
-string DateTimeStr(int64 nTime)
-{
- // Can only be used safely here in the UI
- wxDateTime datetime((time_t)nTime);
- if (Is24HourTime())
- return (string)datetime.Format("%x %H:%M");
- else
- return (string)datetime.Format("%x ") + itostr((datetime.GetHour() + 11) % 12 + 1) + (string)datetime.Format(":%M %p");
-}
-
-wxString GetItemText(wxListCtrl* listCtrl, int nIndex, int nColumn)
-{
- // Helper to simplify access to listctrl
- wxListItem item;
- item.m_itemId = nIndex;
- item.m_col = nColumn;
- item.m_mask = wxLIST_MASK_TEXT;
- if (!listCtrl->GetItem(item))
- return "";
- return item.GetText();
-}
-
-int InsertLine(wxListCtrl* listCtrl, const wxString& str0, const wxString& str1)
-{
- int nIndex = listCtrl->InsertItem(listCtrl->GetItemCount(), str0);
- listCtrl->SetItem(nIndex, 1, str1);
- return nIndex;
-}
-
-int InsertLine(wxListCtrl* listCtrl, const wxString& str0, const wxString& str1, const wxString& str2, const wxString& str3, const wxString& str4)
-{
- int nIndex = listCtrl->InsertItem(listCtrl->GetItemCount(), str0);
- listCtrl->SetItem(nIndex, 1, str1);
- listCtrl->SetItem(nIndex, 2, str2);
- listCtrl->SetItem(nIndex, 3, str3);
- listCtrl->SetItem(nIndex, 4, str4);
- return nIndex;
-}
-
-int InsertLine(wxListCtrl* listCtrl, void* pdata, const wxString& str0, const wxString& str1, const wxString& str2, const wxString& str3, const wxString& str4)
-{
- int nIndex = listCtrl->InsertItem(listCtrl->GetItemCount(), str0);
- listCtrl->SetItemPtrData(nIndex, (wxUIntPtr)pdata);
- listCtrl->SetItem(nIndex, 1, str1);
- listCtrl->SetItem(nIndex, 2, str2);
- listCtrl->SetItem(nIndex, 3, str3);
- listCtrl->SetItem(nIndex, 4, str4);
- return nIndex;
-}
-
-void SetSelection(wxListCtrl* listCtrl, int nIndex)
-{
- int nSize = listCtrl->GetItemCount();
- long nState = (wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED);
- for (int i = 0; i < nSize; i++)
- listCtrl->SetItemState(i, (i == nIndex ? nState : 0), nState);
-}
-
-int GetSelection(wxListCtrl* listCtrl)
-{
- int nSize = listCtrl->GetItemCount();
- for (int i = 0; i < nSize; i++)
- if (listCtrl->GetItemState(i, wxLIST_STATE_FOCUSED))
- return i;
- return -1;
-}
-
-string HtmlEscape(const char* psz, bool fMultiLine=false)
-{
- int len = 0;
- for (const char* p = psz; *p; p++)
- {
- if (*p == '<') len += 4;
- else if (*p == '>') len += 4;
- else if (*p == '&') len += 5;
- else if (*p == '"') len += 6;
- else if (*p == ' ' && p > psz && p[-1] == ' ' && p[1] == ' ') len += 6;
- else if (*p == '\n' && fMultiLine) len += 5;
- else
- len++;
- }
- string str;
- str.reserve(len);
- for (const char* p = psz; *p; p++)
- {
- if (*p == '<') str += "<";
- else if (*p == '>') str += ">";
- else if (*p == '&') str += "&";
- else if (*p == '"') str += """;
- else if (*p == ' ' && p > psz && p[-1] == ' ' && p[1] == ' ') str += " ";
- else if (*p == '\n' && fMultiLine) str += "<br>\n";
- else
- str += *p;
- }
- return str;
-}
-
-string HtmlEscape(const string& str, bool fMultiLine=false)
-{
- return HtmlEscape(str.c_str(), fMultiLine);
-}
-
-void CalledMessageBox(const string& message, const string& caption, int style, wxWindow* parent, int x, int y, int* pnRet, bool* pfDone)
-{
- *pnRet = wxMessageBox(message, caption, style, parent, x, y);
- *pfDone = true;
-}
-
-int ThreadSafeMessageBox(const string& message, const string& caption, int style, wxWindow* parent, int x, int y)
-{
-#ifdef __WXMSW__
- return wxMessageBox(message, caption, style, parent, x, y);
-#else
- if (wxThread::IsMain() || fDaemon)
- {
- return wxMessageBox(message, caption, style, parent, x, y);
- }
- else
- {
- int nRet = 0;
- bool fDone = false;
- UIThreadCall(bind(CalledMessageBox, message, caption, style, parent, x, y, &nRet, &fDone));
- while (!fDone)
- Sleep(100);
- return nRet;
- }
-#endif
-}
-
-bool ThreadSafeAskFee(int64 nFeeRequired, const string& strCaption, wxWindow* parent)
-{
- if (nFeeRequired == 0 || fDaemon)
- return true;
- string strMessage = strprintf(
- _("This transaction is over the size limit. You can still send it for a fee of %s, "
- "which goes to the nodes that process your transaction and helps to support the network. "
- "Do you want to pay the fee?"),
- FormatMoney(nFeeRequired).c_str());
- return (ThreadSafeMessageBox(strMessage, strCaption, wxYES_NO, parent) == wxYES);
-}
-
-void CalledSetStatusBar(const string& strText, int nField)
-{
- if (pframeMain && pframeMain->m_statusBar)
- pframeMain->m_statusBar->SetStatusText(strText, nField);
-}
-
-void SetDefaultReceivingAddress(const string& strAddress)
-{
- // Update main window address and database
- if (pframeMain == NULL)
- return;
- if (strAddress != pframeMain->m_textCtrlAddress->GetValue())
- {
- uint160 hash160;
- if (!AddressToHash160(strAddress, hash160))
- return;
- if (!mapPubKeys.count(hash160))
- return;
- CWalletDB().WriteDefaultKey(mapPubKeys[hash160]);
- pframeMain->m_textCtrlAddress->SetValue(strAddress);
- }
-}
-
-
-
-
-
-
-
-
-
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// CMainFrame
-//
-
-CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent)
-{
- Connect(wxEVT_UITHREADCALL, wxCommandEventHandler(CMainFrame::OnUIThreadCall), NULL, this);
-
- // Set initially selected page
- wxNotebookEvent event;
- event.SetSelection(0);
- OnNotebookPageChanged(event);
- m_notebook->ChangeSelection(0);
-
- // Init
- fRefreshListCtrl = false;
- fRefreshListCtrlRunning = false;
- fOnSetFocusAddress = false;
- fRefresh = false;
- m_choiceFilter->SetSelection(0);
- double dResize = 1.0;
-#ifdef __WXMSW__
- SetIcon(wxICON(bitcoin));
-#else
- SetIcon(bitcoin80_xpm);
- SetBackgroundColour(m_toolBar->GetBackgroundColour());
- wxFont fontTmp = m_staticText41->GetFont();
- fontTmp.SetFamily(wxFONTFAMILY_TELETYPE);
- m_staticTextBalance->SetFont(fontTmp);
- m_staticTextBalance->SetSize(140, 17);
- // resize to fit ubuntu's huge default font
- dResize = 1.22;
- SetSize(dResize * GetSize().GetWidth(), 1.15 * GetSize().GetHeight());
-#endif
- m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " ");
- m_listCtrl->SetFocus();
- ptaskbaricon = new CMyTaskBarIcon();
-#ifdef __WXMAC__
- // Mac automatically moves wxID_EXIT, wxID_PREFERENCES and wxID_ABOUT
- // to their standard places, leaving these menus empty.
- GetMenuBar()->Remove(2); // remove Help menu
- GetMenuBar()->Remove(0); // remove File menu
-#endif
-
- // Init column headers
- int nDateWidth = DateTimeStr(1229413914).size() * 6 + 8;
- if (!strstr(DateTimeStr(1229413914).c_str(), "2008"))
- nDateWidth += 12;
-#ifdef __WXMAC__
- nDateWidth += 5;
- dResize -= 0.01;
-#endif
- wxListCtrl* pplistCtrl[] = {m_listCtrlAll, m_listCtrlSentReceived, m_listCtrlSent, m_listCtrlReceived};
- foreach(wxListCtrl* p, pplistCtrl)
- {
- p->InsertColumn(0, "", wxLIST_FORMAT_LEFT, dResize * 0);
- p->InsertColumn(1, "", wxLIST_FORMAT_LEFT, dResize * 0);
- p->InsertColumn(2, _("Status"), wxLIST_FORMAT_LEFT, dResize * 112);
- p->InsertColumn(3, _("Date"), wxLIST_FORMAT_LEFT, dResize * nDateWidth);
- p->InsertColumn(4, _("Description"), wxLIST_FORMAT_LEFT, dResize * 409 - nDateWidth);
- p->InsertColumn(5, _("Debit"), wxLIST_FORMAT_RIGHT, dResize * 79);
- p->InsertColumn(6, _("Credit"), wxLIST_FORMAT_RIGHT, dResize * 79);
- }
-
- // Init status bar
- int pnWidths[3] = { -100, 88, 300 };
-#ifndef __WXMSW__
- pnWidths[1] = pnWidths[1] * 1.1 * dResize;
- pnWidths[2] = pnWidths[2] * 1.1 * dResize;
-#endif
- m_statusBar->SetFieldsCount(3, pnWidths);
-
- // Fill your address text box
- vector<unsigned char> vchPubKey;
- if (CWalletDB("r").ReadDefaultKey(vchPubKey))
- m_textCtrlAddress->SetValue(PubKeyToAddress(vchPubKey));
-
- // Fill listctrl with wallet transactions
- RefreshListCtrl();
-}
-
-CMainFrame::~CMainFrame()
-{
- pframeMain = NULL;
- delete ptaskbaricon;
- ptaskbaricon = NULL;
-}
-
-void CMainFrame::OnNotebookPageChanged(wxNotebookEvent& event)
-{
- event.Skip();
- nPage = event.GetSelection();
- if (nPage == ALL)
- {
- m_listCtrl = m_listCtrlAll;
- fShowGenerated = true;
- fShowSent = true;
- fShowReceived = true;
- }
- else if (nPage == SENTRECEIVED)
- {
- m_listCtrl = m_listCtrlSentReceived;
- fShowGenerated = false;
- fShowSent = true;
- fShowReceived = true;
- }
- else if (nPage == SENT)
- {
- m_listCtrl = m_listCtrlSent;
- fShowGenerated = false;
- fShowSent = true;
- fShowReceived = false;
- }
- else if (nPage == RECEIVED)
- {
- m_listCtrl = m_listCtrlReceived;
- fShowGenerated = false;
- fShowSent = false;
- fShowReceived = true;
- }
- RefreshListCtrl();
- m_listCtrl->SetFocus();
-}
-
-void CMainFrame::OnClose(wxCloseEvent& event)
-{
- if (fMinimizeOnClose && event.CanVeto() && !IsIconized())
- {
- // Divert close to minimize
- event.Veto();
- fClosedToTray = true;
- Iconize(true);
- }
- else
- {
- Destroy();
- CreateThread(Shutdown, NULL);
- }
-}
-
-void CMainFrame::OnIconize(wxIconizeEvent& event)
-{
- event.Skip();
- // Hide the task bar button when minimized.
- // Event is sent when the frame is minimized or restored.
- // wxWidgets 2.8.9 doesn't have IsIconized() so there's no way
- // to get rid of the deprecated warning. Just ignore it.
- if (!event.Iconized())
- fClosedToTray = false;
-//#ifdef __WXMSW__
- // The tray icon sometimes disappears on ubuntu karmic
- // Hiding the taskbar button doesn't work cleanly on ubuntu lucid
- if (fMinimizeToTray && event.Iconized())
- fClosedToTray = true;
- Show(!fClosedToTray);
-//#endif
- ptaskbaricon->Show(fMinimizeToTray || fClosedToTray);
-}
-
-void CMainFrame::OnMouseEvents(wxMouseEvent& event)
-{
- event.Skip();
- RandAddSeed();
- RAND_add(&event.m_x, sizeof(event.m_x), 0.25);
- RAND_add(&event.m_y, sizeof(event.m_y), 0.25);
-}
-
-void CMainFrame::OnListColBeginDrag(wxListEvent& event)
-{
- // Hidden columns not resizeable
- if (event.GetColumn() <= 1 && !fDebug)
- event.Veto();
- else
- event.Skip();
-}
-
-int CMainFrame::GetSortIndex(const string& strSort)
-{
-#ifdef __WXMSW__
- return 0;
-#else
- // The wx generic listctrl implementation used on GTK doesn't sort,
- // so we have to do it ourselves. Remember, we sort in reverse order.
- // In the wx generic implementation, they store the list of items
- // in a vector, so indexed lookups are fast, but inserts are slower
- // the closer they are to the top.
- int low = 0;
- int high = m_listCtrl->GetItemCount();
- while (low < high)
- {
- int mid = low + ((high - low) / 2);
- if (strSort.compare(m_listCtrl->GetItemText(mid).c_str()) >= 0)
- high = mid;
- else
- low = mid + 1;
- }
- return low;
-#endif
-}
-
-void CMainFrame::InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5, const wxString& str6)
-{
- strSort = " " + strSort; // leading space to workaround wx2.9.0 ubuntu 9.10 bug
- long nData = *(long*)&hashKey; // where first char of hidden column is displayed
-
- // Find item
- if (!fNew && nIndex == -1)
- {
- string strHash = " " + hashKey.ToString();
- while ((nIndex = m_listCtrl->FindItem(nIndex, nData)) != -1)
- if (GetItemText(m_listCtrl, nIndex, 1) == strHash)
- break;
- }
-
- // fNew is for blind insert, only use if you're sure it's new
- if (fNew || nIndex == -1)
- {
- nIndex = m_listCtrl->InsertItem(GetSortIndex(strSort), strSort);
- }
- else
- {
- // If sort key changed, must delete and reinsert to make it relocate
- if (GetItemText(m_listCtrl, nIndex, 0) != strSort)
- {
- m_listCtrl->DeleteItem(nIndex);
- nIndex = m_listCtrl->InsertItem(GetSortIndex(strSort), strSort);
- }
- }
-
- m_listCtrl->SetItem(nIndex, 1, " " + hashKey.ToString());
- m_listCtrl->SetItem(nIndex, 2, str2);
- m_listCtrl->SetItem(nIndex, 3, str3);
- m_listCtrl->SetItem(nIndex, 4, str4);
- m_listCtrl->SetItem(nIndex, 5, str5);
- m_listCtrl->SetItem(nIndex, 6, str6);
- m_listCtrl->SetItemData(nIndex, nData);
-}
-
-bool CMainFrame::DeleteLine(uint256 hashKey)
-{
- long nData = *(long*)&hashKey;
-
- // Find item
- int nIndex = -1;
- string strHash = " " + hashKey.ToString();
- while ((nIndex = m_listCtrl->FindItem(nIndex, nData)) != -1)
- if (GetItemText(m_listCtrl, nIndex, 1) == strHash)
- break;
-
- if (nIndex != -1)
- m_listCtrl->DeleteItem(nIndex);
-
- return nIndex != -1;
-}
-
-string FormatTxStatus(const CWalletTx& wtx)
-{
- // Status
- if (!wtx.IsFinal())
- {
- if (wtx.nLockTime < 500000000)
- return strprintf(_("Open for %d blocks"), nBestHeight - wtx.nLockTime);
- else
- return strprintf(_("Open until %s"), DateTimeStr(wtx.nLockTime).c_str());
- }
- else
- {
- int nDepth = wtx.GetDepthInMainChain();
- if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0)
- return strprintf(_("%d/offline?"), nDepth);
- else if (nDepth < 6)
- return strprintf(_("%d/unconfirmed"), nDepth);
- else
- return strprintf(_("%d confirmations"), nDepth);
- }
-}
-
-string SingleLine(const string& strIn)
-{
- string strOut;
- bool fOneSpace = false;
- foreach(int c, strIn)
- {
- if (isspace(c))
- {
- fOneSpace = true;
- }
- else if (c > ' ')
- {
- if (fOneSpace && !strOut.empty())
- strOut += ' ';
- strOut += c;
- fOneSpace = false;
- }
- }
- return strOut;
-}
-
-bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex)
-{
- int64 nTime = wtx.nTimeDisplayed = wtx.GetTxTime();
- int64 nCredit = wtx.GetCredit(true);
- int64 nDebit = wtx.GetDebit();
- int64 nNet = nCredit - nDebit;
- uint256 hash = wtx.GetHash();
- string strStatus = FormatTxStatus(wtx);
- map<string, string> mapValue = wtx.mapValue;
- wtx.nLinesDisplayed = 1;
- nListViewUpdated++;
-
- // Filter
- if (wtx.IsCoinBase())
- {
- // Don't show generated coin until confirmed by at least one block after it
- // so we don't get the user's hopes up until it looks like it's probably accepted.
- //
- // It is not an error when generated blocks are not accepted. By design,
- // some percentage of blocks, like 10% or more, will end up not accepted.
- // This is the normal mechanism by which the network copes with latency.
- //
- // We display regular transactions right away before any confirmation
- // because they can always get into some block eventually. Generated coins
- // are special because if their block is not accepted, they are not valid.
- //
- if (wtx.GetDepthInMainChain() < 2)
- {
- wtx.nLinesDisplayed = 0;
- return false;
- }
-
- if (!fShowGenerated)
- return false;
- }
-
- // Find the block the tx is in
- CBlockIndex* pindex = NULL;
- map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(wtx.hashBlock);
- if (mi != mapBlockIndex.end())
- pindex = (*mi).second;
-
- // Sort order, unrecorded transactions sort to the top
- string strSort = strprintf("%010d-%01d-%010u",
- (pindex ? pindex->nHeight : INT_MAX),
- (wtx.IsCoinBase() ? 1 : 0),
- wtx.nTimeReceived);
-
- // Insert line
- if (nNet > 0 || wtx.IsCoinBase())
- {
- //
- // Credit
- //
- string strDescription;
- if (wtx.IsCoinBase())
- {
- // Generated
- strDescription = _("Generated");
- if (nCredit == 0)
- {
- int64 nUnmatured = 0;
- foreach(const CTxOut& txout, wtx.vout)
- nUnmatured += txout.GetCredit();
- if (wtx.IsInMainChain())
- {
- strDescription = strprintf(_("Generated (%s matures in %d more blocks)"), FormatMoney(nUnmatured).c_str(), wtx.GetBlocksToMaturity());
-
- // Check if the block was requested by anyone
- if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0)
- strDescription = _("Generated - Warning: This block was not received by any other nodes and will probably not be accepted!");
- }
- else
- {
- strDescription = _("Generated (not accepted)");
- }
- }
- }
- else if (!mapValue["from"].empty() || !mapValue["message"].empty())
- {
- // Received by IP connection
- if (!fShowReceived)
- return false;
- if (!mapValue["from"].empty())
- strDescription += _("From: ") + mapValue["from"];
- if (!mapValue["message"].empty())
- {
- if (!strDescription.empty())
- strDescription += " - ";
- strDescription += mapValue["message"];
- }
- }
- else
- {
- // Received by Bitcoin Address
- if (!fShowReceived)
- return false;
- foreach(const CTxOut& txout, wtx.vout)
- {
- if (txout.IsMine())
- {
- vector<unsigned char> vchPubKey;
- if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey))
- {
- CRITICAL_BLOCK(cs_mapAddressBook)
- {
- //strDescription += _("Received payment to ");
- //strDescription += _("Received with address ");
- strDescription += _("From: unknown, Received with: ");
- string strAddress = PubKeyToAddress(vchPubKey);
- map<string, string>::iterator mi = mapAddressBook.find(strAddress);
- if (mi != mapAddressBook.end() && !(*mi).second.empty())
- {
- string strLabel = (*mi).second;
- strDescription += strAddress.substr(0,12) + "... ";
- strDescription += "(" + strLabel + ")";
- }
- else
- strDescription += strAddress;
- }
- }
- break;
- }
- }
- }
-
- InsertLine(fNew, nIndex, hash, strSort,
- strStatus,
- nTime ? DateTimeStr(nTime) : "",
- SingleLine(strDescription),
- "",
- FormatMoney(nNet, true));
- }
- else
- {
- bool fAllFromMe = true;
- foreach(const CTxIn& txin, wtx.vin)
- fAllFromMe = fAllFromMe && txin.IsMine();
-
- bool fAllToMe = true;
- foreach(const CTxOut& txout, wtx.vout)
- fAllToMe = fAllToMe && txout.IsMine();
-
- if (fAllFromMe && fAllToMe)
- {
- // Payment to self
- int64 nValue = wtx.vout[0].nValue;
- InsertLine(fNew, nIndex, hash, strSort,
- strStatus,
- nTime ? DateTimeStr(nTime) : "",
- _("Payment to yourself"),
- "",
- "");
- /// issue: can't tell which is the payment and which is the change anymore
- // FormatMoney(nNet - nValue, true),
- // FormatMoney(nValue, true));
- }
- else if (fAllFromMe)
- {
- //
- // Debit
- //
- if (!fShowSent)
- return false;
-
- int64 nTxFee = nDebit - wtx.GetValueOut();
- wtx.nLinesDisplayed = 0;
- for (int nOut = 0; nOut < wtx.vout.size(); nOut++)
- {
- const CTxOut& txout = wtx.vout[nOut];
- if (txout.IsMine())
- continue;
-
- string strAddress;
- if (!mapValue["to"].empty())
- {
- // Sent to IP
- strAddress = mapValue["to"];
- }
- else
- {
- // Sent to Bitcoin Address
- uint160 hash160;
- if (ExtractHash160(txout.scriptPubKey, hash160))
- strAddress = Hash160ToAddress(hash160);
- }
-
- string strDescription = _("To: ");
- CRITICAL_BLOCK(cs_mapAddressBook)
- if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty())
- strDescription += mapAddressBook[strAddress] + " ";
- strDescription += strAddress;
- if (!mapValue["message"].empty())
- {
- if (!strDescription.empty())
- strDescription += " - ";
- strDescription += mapValue["message"];
- }
-
- int64 nValue = txout.nValue;
- if (nTxFee > 0)
- {
- nValue += nTxFee;
- nTxFee = 0;
- }
-
- InsertLine(fNew, nIndex, hash, strprintf("%s-%d", strSort.c_str(), nOut),
- strStatus,
- nTime ? DateTimeStr(nTime) : "",
- SingleLine(strDescription),
- FormatMoney(-nValue, true),
- "");
- wtx.nLinesDisplayed++;
- }
- }
- else
- {
- //
- // Mixed debit transaction, can't break down payees
- //
- bool fAllMine = true;
- foreach(const CTxOut& txout, wtx.vout)
- fAllMine = fAllMine && txout.IsMine();
- foreach(const CTxIn& txin, wtx.vin)
- fAllMine = fAllMine && txin.IsMine();
-
- InsertLine(fNew, nIndex, hash, strSort,
- strStatus,
- nTime ? DateTimeStr(nTime) : "",
- "",
- FormatMoney(nNet, true),
- "");
- }
- }
-
- return true;
-}
-
-void CMainFrame::RefreshListCtrl()
-{
- fRefreshListCtrl = true;
- ::wxWakeUpIdle();
-}
-
-void CMainFrame::OnIdle(wxIdleEvent& event)
-{
- if (fRefreshListCtrl)
- {
- // Collect list of wallet transactions and sort newest first
- bool fEntered = false;
- vector<pair<unsigned int, uint256> > vSorted;
- TRY_CRITICAL_BLOCK(cs_mapWallet)
- {
- printf("RefreshListCtrl starting\n");
- fEntered = true;
- fRefreshListCtrl = false;
- vWalletUpdated.clear();
-
- // Do the newest transactions first
- vSorted.reserve(mapWallet.size());
- for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
- {
- const CWalletTx& wtx = (*it).second;
- unsigned int nTime = UINT_MAX - wtx.GetTxTime();
- vSorted.push_back(make_pair(nTime, (*it).first));
- }
- m_listCtrl->DeleteAllItems();
- }
- if (!fEntered)
- return;
-
- sort(vSorted.begin(), vSorted.end());
-
- // Fill list control
- for (int i = 0; i < vSorted.size();)
- {
- if (fShutdown)
- return;
- bool fEntered = false;
- TRY_CRITICAL_BLOCK(cs_mapWallet)
- {
- fEntered = true;
- uint256& hash = vSorted[i++].second;
- map<uint256, CWalletTx>::iterator mi = mapWallet.find(hash);
- if (mi != mapWallet.end())
- InsertTransaction((*mi).second, true);
- }
- if (!fEntered || i == 100 || i % 500 == 0)
- wxYield();
- }
-
- printf("RefreshListCtrl done\n");
-
- // Update transaction total display
- MainFrameRepaint();
- }
- else
- {
- // Check for time updates
- static int64 nLastTime;
- if (GetTime() > nLastTime + 30)
- {
- TRY_CRITICAL_BLOCK(cs_mapWallet)
- {
- nLastTime = GetTime();
- for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
- {
- CWalletTx& wtx = (*it).second;
- if (wtx.nTimeDisplayed && wtx.nTimeDisplayed != wtx.GetTxTime())
- InsertTransaction(wtx, false);
- }
- }
- }
- }
-}
-
-void CMainFrame::RefreshStatusColumn()
-{
- static int nLastTop;
- static CBlockIndex* pindexLastBest;
- static unsigned int nLastRefreshed;
-
- int nTop = max((int)m_listCtrl->GetTopItem(), 0);
- if (nTop == nLastTop && pindexLastBest == pindexBest)
- return;
-
- TRY_CRITICAL_BLOCK(cs_mapWallet)
- {
- int nStart = nTop;
- int nEnd = min(nStart + 100, m_listCtrl->GetItemCount());
-
- if (pindexLastBest == pindexBest && nLastRefreshed == nListViewUpdated)
- {
- // If no updates, only need to do the part that moved onto the screen
- if (nStart >= nLastTop && nStart < nLastTop + 100)
- nStart = nLastTop + 100;
- if (nEnd >= nLastTop && nEnd < nLastTop + 100)
- nEnd = nLastTop;
- }
- nLastTop = nTop;
- pindexLastBest = pindexBest;
- nLastRefreshed = nListViewUpdated;
-
- for (int nIndex = nStart; nIndex < min(nEnd, m_listCtrl->GetItemCount()); nIndex++)
- {
- uint256 hash((string)GetItemText(m_listCtrl, nIndex, 1));
- map<uint256, CWalletTx>::iterator mi = mapWallet.find(hash);
- if (mi == mapWallet.end())
- {
- printf("CMainFrame::RefreshStatusColumn() : tx not found in mapWallet\n");
- continue;
- }
- CWalletTx& wtx = (*mi).second;
- if (wtx.IsCoinBase() || wtx.GetTxTime() != wtx.nTimeDisplayed)
- {
- if (!InsertTransaction(wtx, false, nIndex))
- m_listCtrl->DeleteItem(nIndex--);
- }
- else
- m_listCtrl->SetItem(nIndex, 2, FormatTxStatus(wtx));
- }
- }
-}
-
-void CMainFrame::OnPaint(wxPaintEvent& event)
-{
- event.Skip();
- if (fRefresh)
- {
- fRefresh = false;
- Refresh();
- }
-}
-
-
-unsigned int nNeedRepaint = 0;
-unsigned int nLastRepaint = 0;
-int64 nLastRepaintTime = 0;
-int64 nRepaintInterval = 500;
-
-void ThreadDelayedRepaint(void* parg)
-{
- while (!fShutdown)
- {
- if (nLastRepaint != nNeedRepaint && GetTimeMillis() - nLastRepaintTime >= nRepaintInterval)
- {
- nLastRepaint = nNeedRepaint;
- if (pframeMain)
- {
- printf("DelayedRepaint\n");
- wxPaintEvent event;
- pframeMain->fRefresh = true;
- pframeMain->GetEventHandler()->AddPendingEvent(event);
- }
- }
- Sleep(nRepaintInterval);
- }
-}
-
-void MainFrameRepaint()
-{
- // This is called by network code that shouldn't access pframeMain
- // directly because it could still be running after the UI is closed.
- if (pframeMain)
- {
- // Don't repaint too often
- static int64 nLastRepaintRequest;
- if (GetTimeMillis() - nLastRepaintRequest < 100)
- {
- nNeedRepaint++;
- return;
- }
- nLastRepaintRequest = GetTimeMillis();
-
- printf("MainFrameRepaint\n");
- wxPaintEvent event;
- pframeMain->fRefresh = true;
- pframeMain->GetEventHandler()->AddPendingEvent(event);
- }
-}
-
-void CMainFrame::OnPaintListCtrl(wxPaintEvent& event)
-{
- // Skip lets the listctrl do the paint, we're just hooking the message
- event.Skip();
-
- if (ptaskbaricon)
- ptaskbaricon->UpdateTooltip();
-
- //
- // Slower stuff
- //
- static int nTransactionCount;
- bool fPaintedBalance = false;
- if (GetTimeMillis() - nLastRepaintTime >= nRepaintInterval)
- {
- nLastRepaint = nNeedRepaint;
- nLastRepaintTime = GetTimeMillis();
-
- // Update listctrl contents
- if (!vWalletUpdated.empty())
- {
- TRY_CRITICAL_BLOCK(cs_mapWallet)
- {
- string strTop;
- if (m_listCtrl->GetItemCount())
- strTop = (string)m_listCtrl->GetItemText(0);
- foreach(uint256 hash, vWalletUpdated)
- {
- map<uint256, CWalletTx>::iterator mi = mapWallet.find(hash);
- if (mi != mapWallet.end())
- InsertTransaction((*mi).second, false);
- }
- vWalletUpdated.clear();
- if (m_listCtrl->GetItemCount() && strTop != (string)m_listCtrl->GetItemText(0))
- m_listCtrl->ScrollList(0, INT_MIN/2);
- }
- }
-
- // Balance total
- TRY_CRITICAL_BLOCK(cs_mapWallet)
- {
- fPaintedBalance = true;
- m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " ");
-
- // Count hidden and multi-line transactions
- nTransactionCount = 0;
- for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
- {
- CWalletTx& wtx = (*it).second;
- nTransactionCount += wtx.nLinesDisplayed;
- }
- }
- }
- if (!vWalletUpdated.empty() || !fPaintedBalance)
- nNeedRepaint++;
-
- // Update status column of visible items only
- RefreshStatusColumn();
-
- // Update status bar
- string strGen = "";
- if (fGenerateBitcoins)
- strGen = _(" Generating");
- if (fGenerateBitcoins && vNodes.empty())
- strGen = _("(not connected)");
- m_statusBar->SetStatusText(strGen, 1);
-
- string strStatus = strprintf(_(" %d connections %d blocks %d transactions"), vNodes.size(), nBestHeight + 1, nTransactionCount);
- m_statusBar->SetStatusText(strStatus, 2);
-
- if (fDebug && GetTime() - nThreadSocketHandlerHeartbeat > 60)
- m_statusBar->SetStatusText(" ERROR: ThreadSocketHandler has stopped", 0);
-
- // Update receiving address
- string strDefaultAddress = PubKeyToAddress(vchDefaultKey);
- if (m_textCtrlAddress->GetValue() != strDefaultAddress)
- m_textCtrlAddress->SetValue(strDefaultAddress);
-}
-
-
-void UIThreadCall(boost::function0<void> fn)
-{
- // Call this with a function object created with bind.
- // bind needs all parameters to match the function's expected types
- // and all default parameters specified. Some examples:
- // UIThreadCall(bind(wxBell));
- // UIThreadCall(bind(wxMessageBox, wxT("Message"), wxT("Title"), wxOK, (wxWindow*)NULL, -1, -1));
- // UIThreadCall(bind(&CMainFrame::OnMenuHelpAbout, pframeMain, event));
- if (pframeMain)
- {
- wxCommandEvent event(wxEVT_UITHREADCALL);
- event.SetClientData((void*)new boost::function0<void>(fn));
- pframeMain->GetEventHandler()->AddPendingEvent(event);
- }
-}
-
-void CMainFrame::OnUIThreadCall(wxCommandEvent& event)
-{
- boost::function0<void>* pfn = (boost::function0<void>*)event.GetClientData();
- (*pfn)();
- delete pfn;
-}
-
-void CMainFrame::OnMenuFileExit(wxCommandEvent& event)
-{
- // File->Exit
- Close(true);
-}
-
-void CMainFrame::OnMenuOptionsGenerate(wxCommandEvent& event)
-{
- // Options->Generate Coins
- GenerateBitcoins(event.IsChecked());
-}
-
-void CMainFrame::OnUpdateUIOptionsGenerate(wxUpdateUIEvent& event)
-{
- event.Check(fGenerateBitcoins);
-}
-
-void CMainFrame::OnMenuOptionsChangeYourAddress(wxCommandEvent& event)
-{
- // Options->Your Receiving Addresses
- CAddressBookDialog dialog(this, "", CAddressBookDialog::RECEIVING, false);
- if (!dialog.ShowModal())
- return;
-}
-
-void CMainFrame::OnMenuOptionsOptions(wxCommandEvent& event)
-{
- // Options->Options
- COptionsDialog dialog(this);
- dialog.ShowModal();
-}
-
-void CMainFrame::OnMenuHelpAbout(wxCommandEvent& event)
-{
- // Help->About
- CAboutDialog dialog(this);
- dialog.ShowModal();
-}
-
-void CMainFrame::OnButtonSend(wxCommandEvent& event)
-{
- // Toolbar: Send
- CSendDialog dialog(this);
- dialog.ShowModal();
-}
-
-void CMainFrame::OnButtonAddressBook(wxCommandEvent& event)
-{
- // Toolbar: Address Book
- CAddressBookDialog dialogAddr(this, "", CAddressBookDialog::SENDING, false);
- if (dialogAddr.ShowModal() == 2)
- {
- // Send
- CSendDialog dialogSend(this, dialogAddr.GetSelectedAddress());
- dialogSend.ShowModal();
- }
-}
-
-void CMainFrame::OnSetFocusAddress(wxFocusEvent& event)
-{
- // Automatically select-all when entering window
- event.Skip();
- m_textCtrlAddress->SetSelection(-1, -1);
- fOnSetFocusAddress = true;
-}
-
-void CMainFrame::OnMouseEventsAddress(wxMouseEvent& event)
-{
- event.Skip();
- if (fOnSetFocusAddress)
- m_textCtrlAddress->SetSelection(-1, -1);
- fOnSetFocusAddress = false;
-}
-
-void CMainFrame::OnButtonNew(wxCommandEvent& event)
-{
- // Ask name
- CGetTextFromUserDialog dialog(this,
- _("New Receiving Address"),
- _("It's good policy to use a new address for each payment you receive.\n\nLabel"),
- "");
- if (!dialog.ShowModal())
- return;
- string strName = dialog.GetValue();
-
- // Generate new key
- string strAddress = PubKeyToAddress(GenerateNewKey());
-
- // Save
- SetAddressBookName(strAddress, strName);
- SetDefaultReceivingAddress(strAddress);
-}
-
-void CMainFrame::OnButtonCopy(wxCommandEvent& event)
-{
- // Copy address box to clipboard
- if (wxTheClipboard->Open())
- {
- wxTheClipboard->SetData(new wxTextDataObject(m_textCtrlAddress->GetValue()));
- wxTheClipboard->Close();
- }
-}
-
-void CMainFrame::OnListItemActivated(wxListEvent& event)
-{
- uint256 hash((string)GetItemText(m_listCtrl, event.GetIndex(), 1));
- CWalletTx wtx;
- CRITICAL_BLOCK(cs_mapWallet)
- {
- map<uint256, CWalletTx>::iterator mi = mapWallet.find(hash);
- if (mi == mapWallet.end())
- {
- printf("CMainFrame::OnListItemActivated() : tx not found in mapWallet\n");
- return;
- }
- wtx = (*mi).second;
- }
- CTxDetailsDialog dialog(this, wtx);
- dialog.ShowModal();
- //CTxDetailsDialog* pdialog = new CTxDetailsDialog(this, wtx);
- //pdialog->Show();
-}
-
-
-
-
-
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// CTxDetailsDialog
-//
-
-CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetailsDialogBase(parent)
-{
- CRITICAL_BLOCK(cs_mapAddressBook)
- {
- string strHTML;
- strHTML.reserve(4000);
- strHTML += "<html><font face='verdana, arial, helvetica, sans-serif'>";
-
- int64 nTime = wtx.GetTxTime();
- int64 nCredit = wtx.GetCredit();
- int64 nDebit = wtx.GetDebit();
- int64 nNet = nCredit - nDebit;
-
-
-
- strHTML += _("<b>Status:</b> ") + FormatTxStatus(wtx);
- int nRequests = wtx.GetRequestCount();
- if (nRequests != -1)
- {
- if (nRequests == 0)
- strHTML += _(", has not been successfully broadcast yet");
- else if (nRequests == 1)
- strHTML += strprintf(_(", broadcast through %d node"), nRequests);
- else
- strHTML += strprintf(_(", broadcast through %d nodes"), nRequests);
- }
- strHTML += "<br>";
-
- strHTML += _("<b>Date:</b> ") + (nTime ? DateTimeStr(nTime) : "") + "<br>";
-
-
- //
- // From
- //
- if (wtx.IsCoinBase())
- {
- strHTML += _("<b>Source:</b> Generated<br>");
- }
- else if (!wtx.mapValue["from"].empty())
- {
- // Online transaction
- if (!wtx.mapValue["from"].empty())
- strHTML += _("<b>From:</b> ") + HtmlEscape(wtx.mapValue["from"]) + "<br>";
- }
- else
- {
- // Offline transaction
- if (nNet > 0)
- {
- // Credit
- foreach(const CTxOut& txout, wtx.vout)
- {
- if (txout.IsMine())
- {
- vector<unsigned char> vchPubKey;
- if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey))
- {
- string strAddress = PubKeyToAddress(vchPubKey);
- if (mapAddressBook.count(strAddress))
- {
- strHTML += string() + _("<b>From:</b> ") + _("unknown") + "<br>";
- strHTML += _("<b>To:</b> ");
- strHTML += HtmlEscape(strAddress);
- if (!mapAddressBook[strAddress].empty())
- strHTML += _(" (yours, label: ") + mapAddressBook[strAddress] + ")";
- else
- strHTML += _(" (yours)");
- strHTML += "<br>";
- }
- }
- break;
- }
- }
- }
- }
-
-
- //
- // To
- //
- string strAddress;
- if (!wtx.mapValue["to"].empty())
- {
- // Online transaction
- strAddress = wtx.mapValue["to"];
- strHTML += _("<b>To:</b> ");
- if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty())
- strHTML += mapAddressBook[strAddress] + " ";
- strHTML += HtmlEscape(strAddress) + "<br>";
- }
-
-
- //
- // Amount
- //
- if (wtx.IsCoinBase() && nCredit == 0)
- {
- //
- // Coinbase
- //
- int64 nUnmatured = 0;
- foreach(const CTxOut& txout, wtx.vout)
- nUnmatured += txout.GetCredit();
- strHTML += _("<b>Credit:</b> ");
- if (wtx.IsInMainChain())
- strHTML += strprintf(_("(%s matures in %d more blocks)"), FormatMoney(nUnmatured).c_str(), wtx.GetBlocksToMaturity());
- else
- strHTML += _("(not accepted)");
- strHTML += "<br>";
- }
- else if (nNet > 0)
- {
- //
- // Credit
- //
- strHTML += _("<b>Credit:</b> ") + FormatMoney(nNet) + "<br>";
- }
- else
- {
- bool fAllFromMe = true;
- foreach(const CTxIn& txin, wtx.vin)
- fAllFromMe = fAllFromMe && txin.IsMine();
-
- bool fAllToMe = true;
- foreach(const CTxOut& txout, wtx.vout)
- fAllToMe = fAllToMe && txout.IsMine();
-
- if (fAllFromMe)
- {
- //
- // Debit
- //
- foreach(const CTxOut& txout, wtx.vout)
- {
- if (txout.IsMine())
- continue;
-
- if (wtx.mapValue["to"].empty())
- {
- // Offline transaction
- uint160 hash160;
- if (ExtractHash160(txout.scriptPubKey, hash160))
- {
- string strAddress = Hash160ToAddress(hash160);
- strHTML += _("<b>To:</b> ");
- if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty())
- strHTML += mapAddressBook[strAddress] + " ";
- strHTML += strAddress;
- strHTML += "<br>";
- }
- }
-
- strHTML += _("<b>Debit:</b> ") + FormatMoney(-txout.nValue) + "<br>";
- }
-
- if (fAllToMe)
- {
- // Payment to self
- /// issue: can't tell which is the payment and which is the change anymore
- //int64 nValue = wtx.vout[0].nValue;
- //strHTML += _("<b>Debit:</b> ") + FormatMoney(-nValue) + "<br>";
- //strHTML += _("<b>Credit:</b> ") + FormatMoney(nValue) + "<br>";
- }
-
- int64 nTxFee = nDebit - wtx.GetValueOut();
- if (nTxFee > 0)
- strHTML += _("<b>Transaction fee:</b> ") + FormatMoney(-nTxFee) + "<br>";
- }
- else
- {
- //
- // Mixed debit transaction
- //
- foreach(const CTxIn& txin, wtx.vin)
- if (txin.IsMine())
- strHTML += _("<b>Debit:</b> ") + FormatMoney(-txin.GetDebit()) + "<br>";
- foreach(const CTxOut& txout, wtx.vout)
- if (txout.IsMine())
- strHTML += _("<b>Credit:</b> ") + FormatMoney(txout.GetCredit()) + "<br>";
- }
- }
-
- strHTML += _("<b>Net amount:</b> ") + FormatMoney(nNet, true) + "<br>";
-
-
- //
- // Message
- //
- if (!wtx.mapValue["message"].empty())
- strHTML += string() + "<br><b>" + _("Message:") + "</b><br>" + HtmlEscape(wtx.mapValue["message"], true) + "<br>";
-
- if (wtx.IsCoinBase())
- strHTML += string() + "<br>" + _("Generated coins must wait 120 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, it will change to \"not accepted\" and not be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.") + "<br>";
-
-
- //
- // Debug view
- //
- if (fDebug)
- {
- strHTML += "<hr><br>debug print<br><br>";
- foreach(const CTxIn& txin, wtx.vin)
- if (txin.IsMine())
- strHTML += "<b>Debit:</b> " + FormatMoney(-txin.GetDebit()) + "<br>";
- foreach(const CTxOut& txout, wtx.vout)
- if (txout.IsMine())
- strHTML += "<b>Credit:</b> " + FormatMoney(txout.GetCredit()) + "<br>";
-
- strHTML += "<b>Inputs:</b><br>";
- CRITICAL_BLOCK(cs_mapWallet)
- {
- foreach(const CTxIn& txin, wtx.vin)
- {
- COutPoint prevout = txin.prevout;
- map<uint256, CWalletTx>::iterator mi = mapWallet.find(prevout.hash);
- if (mi != mapWallet.end())
- {
- const CWalletTx& prev = (*mi).second;
- if (prevout.n < prev.vout.size())
- {
- strHTML += HtmlEscape(prev.ToString(), true);
- strHTML += " " + FormatTxStatus(prev) + ", ";
- strHTML = strHTML + "IsMine=" + (prev.vout[prevout.n].IsMine() ? "true" : "false") + "<br>";
- }
- }
- }
- }
-
- strHTML += "<br><hr><br><b>Transaction:</b><br>";
- strHTML += HtmlEscape(wtx.ToString(), true);
- }
-
-
-
- strHTML += "</font></html>";
- string(strHTML.begin(), strHTML.end()).swap(strHTML);
- m_htmlWin->SetPage(strHTML);
- m_buttonOK->SetFocus();
- }
-}
-
-void CTxDetailsDialog::OnButtonOK(wxCommandEvent& event)
-{
- Close();
- //Destroy();
-}
-
-
-
-
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// COptionsDialog
-//
-
-COptionsDialog::COptionsDialog(wxWindow* parent) : COptionsDialogBase(parent)
-{
- // Set up list box of page choices
- m_listBox->Append(_("Main"));
- //m_listBox->Append(_("Test 2"));
- m_listBox->SetSelection(0);
- SelectPage(0);
-#ifdef __WXGTK__
- m_checkBoxStartOnSystemStartup->SetLabel(_("&Start Bitcoin on window system startup"));
-#endif
-#ifdef __WXMAC_OSX__
- m_checkBoxStartOnSystemStartup->Enable(false); // not implemented yet
-#endif
-
- // Init values
- m_textCtrlTransactionFee->SetValue(FormatMoney(nTransactionFee));
- m_checkBoxLimitProcessors->SetValue(fLimitProcessors);
- m_spinCtrlLimitProcessors->Enable(fLimitProcessors);
- m_spinCtrlLimitProcessors->SetValue(nLimitProcessors);
- int nProcessors = wxThread::GetCPUCount();
- if (nProcessors < 1)
- nProcessors = 999;
- m_spinCtrlLimitProcessors->SetRange(1, nProcessors);
- m_checkBoxStartOnSystemStartup->SetValue(fTmpStartOnSystemStartup = GetStartOnSystemStartup());
- m_checkBoxMinimizeToTray->SetValue(fMinimizeToTray);
- m_checkBoxMinimizeOnClose->SetValue(fMinimizeOnClose);
- m_checkBoxUseProxy->SetValue(fUseProxy);
- m_textCtrlProxyIP->Enable(fUseProxy);
- m_textCtrlProxyPort->Enable(fUseProxy);
- m_staticTextProxyIP->Enable(fUseProxy);
- m_staticTextProxyPort->Enable(fUseProxy);
- m_textCtrlProxyIP->SetValue(addrProxy.ToStringIP());
- m_textCtrlProxyPort->SetValue(addrProxy.ToStringPort());
-
- m_buttonOK->SetFocus();
-}
-
-void COptionsDialog::SelectPage(int nPage)
-{
- m_panelMain->Show(nPage == 0);
- m_panelTest2->Show(nPage == 1);
-
- m_scrolledWindow->Layout();
- m_scrolledWindow->SetScrollbars(0, 0, 0, 0, 0, 0);
-}
-
-void COptionsDialog::OnListBox(wxCommandEvent& event)
-{
- SelectPage(event.GetSelection());
-}
-
-void COptionsDialog::OnKillFocusTransactionFee(wxFocusEvent& event)
-{
- event.Skip();
- int64 nTmp = nTransactionFee;
- ParseMoney(m_textCtrlTransactionFee->GetValue(), nTmp);
- m_textCtrlTransactionFee->SetValue(FormatMoney(nTmp));
-}
-
-void COptionsDialog::OnCheckBoxLimitProcessors(wxCommandEvent& event)
-{
- m_spinCtrlLimitProcessors->Enable(event.IsChecked());
-}
-
-void COptionsDialog::OnCheckBoxUseProxy(wxCommandEvent& event)
-{
- m_textCtrlProxyIP->Enable(event.IsChecked());
- m_textCtrlProxyPort->Enable(event.IsChecked());
- m_staticTextProxyIP->Enable(event.IsChecked());
- m_staticTextProxyPort->Enable(event.IsChecked());
-}
-
-CAddress COptionsDialog::GetProxyAddr()
-{
- // Be careful about byte order, addr.ip and addr.port are big endian
- CAddress addr(m_textCtrlProxyIP->GetValue() + ":" + m_textCtrlProxyPort->GetValue());
- if (addr.ip == INADDR_NONE)
- addr.ip = addrProxy.ip;
- int nPort = atoi(m_textCtrlProxyPort->GetValue());
- addr.port = htons(nPort);
- if (nPort <= 0 || nPort > USHRT_MAX)
- addr.port = addrProxy.port;
- return addr;
-}
-
-void COptionsDialog::OnKillFocusProxy(wxFocusEvent& event)
-{
- event.Skip();
- m_textCtrlProxyIP->SetValue(GetProxyAddr().ToStringIP());
- m_textCtrlProxyPort->SetValue(GetProxyAddr().ToStringPort());
-}
-
-
-void COptionsDialog::OnButtonOK(wxCommandEvent& event)
-{
- OnButtonApply(event);
- Close();
-}
-
-void COptionsDialog::OnButtonCancel(wxCommandEvent& event)
-{
- Close();
-}
-
-void COptionsDialog::OnButtonApply(wxCommandEvent& event)
-{
- CWalletDB walletdb;
-
- int64 nPrevTransactionFee = nTransactionFee;
- if (ParseMoney(m_textCtrlTransactionFee->GetValue(), nTransactionFee) && nTransactionFee != nPrevTransactionFee)
- walletdb.WriteSetting("nTransactionFee", nTransactionFee);
-
- int nPrevMaxProc = (fLimitProcessors ? nLimitProcessors : INT_MAX);
- if (fLimitProcessors != m_checkBoxLimitProcessors->GetValue())
- {
- fLimitProcessors = m_checkBoxLimitProcessors->GetValue();
- walletdb.WriteSetting("fLimitProcessors", fLimitProcessors);
- }
- if (nLimitProcessors != m_spinCtrlLimitProcessors->GetValue())
- {
- nLimitProcessors = m_spinCtrlLimitProcessors->GetValue();
- walletdb.WriteSetting("nLimitProcessors", nLimitProcessors);
- }
- if (fGenerateBitcoins && (fLimitProcessors ? nLimitProcessors : INT_MAX) > nPrevMaxProc)
- GenerateBitcoins(fGenerateBitcoins);
-
- if (fTmpStartOnSystemStartup != m_checkBoxStartOnSystemStartup->GetValue())
- {
- fTmpStartOnSystemStartup = m_checkBoxStartOnSystemStartup->GetValue();
- SetStartOnSystemStartup(fTmpStartOnSystemStartup);
- }
-
- if (fMinimizeToTray != m_checkBoxMinimizeToTray->GetValue())
- {
- fMinimizeToTray = m_checkBoxMinimizeToTray->GetValue();
- walletdb.WriteSetting("fMinimizeToTray", fMinimizeToTray);
- ptaskbaricon->Show(fMinimizeToTray || fClosedToTray);
- }
-
- if (fMinimizeOnClose != m_checkBoxMinimizeOnClose->GetValue())
- {
- fMinimizeOnClose = m_checkBoxMinimizeOnClose->GetValue();
- walletdb.WriteSetting("fMinimizeOnClose", fMinimizeOnClose);
- }
-
- fUseProxy = m_checkBoxUseProxy->GetValue();
- walletdb.WriteSetting("fUseProxy", fUseProxy);
-
- addrProxy = GetProxyAddr();
- walletdb.WriteSetting("addrProxy", addrProxy);
-}
-
-
-
-
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// CAboutDialog
-//
-
-CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent)
-{
- m_staticTextVersion->SetLabel(strprintf(_("version %d.%d.%d beta"), VERSION/10000, (VERSION/100)%100, VERSION%100));
-
- // Change (c) into UTF-8 or ANSI copyright symbol
- wxString str = m_staticTextMain->GetLabel();
-#if wxUSE_UNICODE
- str.Replace("(c)", wxString::FromUTF8("\xC2\xA9"));
-#else
- str.Replace("(c)", "\xA9");
-#endif
- m_staticTextMain->SetLabel(str);
-#ifndef __WXMSW__
- // Resize on Linux to make the window fit the text.
- // The text was wrapped manually rather than using the Wrap setting because
- // the wrap would be too small on Linux and it can't be changed at this point.
- wxFont fontTmp = m_staticTextMain->GetFont();
- if (fontTmp.GetPointSize() > 8);
- fontTmp.SetPointSize(8);
- m_staticTextMain->SetFont(fontTmp);
- SetSize(GetSize().GetWidth() + 44, GetSize().GetHeight() + 10);
-#endif
-}
-
-void CAboutDialog::OnButtonOK(wxCommandEvent& event)
-{
- Close();
-}
-
-
-
-
-
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// CSendDialog
-//
-
-CSendDialog::CSendDialog(wxWindow* parent, const wxString& strAddress) : CSendDialogBase(parent)
-{
- // Init
- m_textCtrlAddress->SetValue(strAddress);
- m_choiceTransferType->SetSelection(0);
- m_bitmapCheckMark->Show(false);
- fEnabledPrev = true;
- m_textCtrlAddress->SetFocus();
- //// todo: should add a display of your balance for convenience
-#ifndef __WXMSW__
- wxFont fontTmp = m_staticTextInstructions->GetFont();
- if (fontTmp.GetPointSize() > 9);
- fontTmp.SetPointSize(9);
- m_staticTextInstructions->SetFont(fontTmp);
- SetSize(725, 380);
-#endif
-
- // Set Icon
- wxIcon iconSend;
- iconSend.CopyFromBitmap(wxBitmap(send16noshadow_xpm));
- SetIcon(iconSend);
-
- wxCommandEvent event;
- OnTextAddress(event);
-
- // Fixup the tab order
- m_buttonPaste->MoveAfterInTabOrder(m_buttonCancel);
- m_buttonAddress->MoveAfterInTabOrder(m_buttonPaste);
- this->Layout();
-}
-
-void CSendDialog::OnTextAddress(wxCommandEvent& event)
-{
- // Check mark
- event.Skip();
- bool fBitcoinAddress = IsValidBitcoinAddress(m_textCtrlAddress->GetValue());
- m_bitmapCheckMark->Show(fBitcoinAddress);
-
- // Grey out message if bitcoin address
- bool fEnable = !fBitcoinAddress;
- m_staticTextFrom->Enable(fEnable);
- m_textCtrlFrom->Enable(fEnable);
- m_staticTextMessage->Enable(fEnable);
- m_textCtrlMessage->Enable(fEnable);
- m_textCtrlMessage->SetBackgroundColour(wxSystemSettings::GetColour(fEnable ? wxSYS_COLOUR_WINDOW : wxSYS_COLOUR_BTNFACE));
- if (!fEnable && fEnabledPrev)
- {
- strFromSave = m_textCtrlFrom->GetValue();
- strMessageSave = m_textCtrlMessage->GetValue();
- m_textCtrlFrom->SetValue(_("Will appear as \"From: Unknown\""));
- m_textCtrlMessage->SetValue(_("Can't include a message when sending to a Bitcoin address"));
- }
- else if (fEnable && !fEnabledPrev)
- {
- m_textCtrlFrom->SetValue(strFromSave);
- m_textCtrlMessage->SetValue(strMessageSave);
- }
- fEnabledPrev = fEnable;
-}
-
-void CSendDialog::OnKillFocusAmount(wxFocusEvent& event)
-{
- // Reformat the amount
- event.Skip();
- if (m_textCtrlAmount->GetValue().Trim().empty())
- return;
- int64 nTmp;
- if (ParseMoney(m_textCtrlAmount->GetValue(), nTmp))
- m_textCtrlAmount->SetValue(FormatMoney(nTmp));
-}
-
-void CSendDialog::OnButtonAddressBook(wxCommandEvent& event)
-{
- // Open address book
- CAddressBookDialog dialog(this, m_textCtrlAddress->GetValue(), CAddressBookDialog::SENDING, true);
- if (dialog.ShowModal())
- m_textCtrlAddress->SetValue(dialog.GetSelectedAddress());
-}
-
-void CSendDialog::OnButtonPaste(wxCommandEvent& event)
-{
- // Copy clipboard to address box
- if (wxTheClipboard->Open())
- {
- if (wxTheClipboard->IsSupported(wxDF_TEXT))
- {
- wxTextDataObject data;
- wxTheClipboard->GetData(data);
- m_textCtrlAddress->SetValue(data.GetText());
- }
- wxTheClipboard->Close();
- }
-}
-
-void CSendDialog::OnButtonSend(wxCommandEvent& event)
-{
- CWalletTx wtx;
- string strAddress = (string)m_textCtrlAddress->GetValue();
-
- // Parse amount
- int64 nValue = 0;
- if (!ParseMoney(m_textCtrlAmount->GetValue(), nValue) || nValue <= 0)
- {
- wxMessageBox(_("Error in amount "), _("Send Coins"));
- return;
- }
- if (nValue > GetBalance())
- {
- wxMessageBox(_("Amount exceeds your balance "), _("Send Coins"));
- return;
- }
- if (nValue + nTransactionFee > GetBalance())
- {
- wxMessageBox(string(_("Total exceeds your balance when the ")) + FormatMoney(nTransactionFee) + _(" transaction fee is included "), _("Send Coins"));
- return;
- }
-
- // Parse bitcoin address
- uint160 hash160;
- bool fBitcoinAddress = AddressToHash160(strAddress, hash160);
-
- if (fBitcoinAddress)
- {
- // Send to bitcoin address
- CScript scriptPubKey;
- scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG;
-
- string strError = SendMoney(scriptPubKey, nValue, wtx, true);
- if (strError == "")
- wxMessageBox(_("Payment sent "), _("Sending..."));
- else if (strError != "ABORTED")
- wxMessageBox(strError + " ", _("Sending..."));
- }
- else
- {
- // Parse IP address
- CAddress addr(strAddress);
- if (!addr.IsValid())
- {
- wxMessageBox(_("Invalid address "), _("Send Coins"));
- return;
- }
-
- // Message
- wtx.mapValue["to"] = strAddress;
- wtx.mapValue["from"] = m_textCtrlFrom->GetValue();
- wtx.mapValue["message"] = m_textCtrlMessage->GetValue();
-
- // Send to IP address
- CSendingDialog* pdialog = new CSendingDialog(this, addr, nValue, wtx);
- if (!pdialog->ShowModal())
- return;
- }
-
- CRITICAL_BLOCK(cs_mapAddressBook)
- if (!mapAddressBook.count(strAddress))
- SetAddressBookName(strAddress, "");
-
- EndModal(true);
-}
-
-void CSendDialog::OnButtonCancel(wxCommandEvent& event)
-{
- // Cancel
- EndModal(false);
-}
-
-
-
-
-
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// CSendingDialog
-//
-
-CSendingDialog::CSendingDialog(wxWindow* parent, const CAddress& addrIn, int64 nPriceIn, const CWalletTx& wtxIn) : CSendingDialogBase(NULL) // we have to give null so parent can't destroy us
-{
- addr = addrIn;
- nPrice = nPriceIn;
- wtx = wtxIn;
- start = wxDateTime::UNow();
- memset(pszStatus, 0, sizeof(pszStatus));
- fCanCancel = true;
- fAbort = false;
- fSuccess = false;
- fUIDone = false;
- fWorkDone = false;
-#ifndef __WXMSW__
- SetSize(1.2 * GetSize().GetWidth(), 1.08 * GetSize().GetHeight());
-#endif
-
- SetTitle(strprintf(_("Sending %s to %s"), FormatMoney(nPrice).c_str(), wtx.mapValue["to"].c_str()));
- m_textCtrlStatus->SetValue("");
-
- CreateThread(SendingDialogStartTransfer, this);
-}
-
-CSendingDialog::~CSendingDialog()
-{
- printf("~CSendingDialog()\n");
-}
-
-void CSendingDialog::Close()
-{
- // Last one out turn out the lights.
- // fWorkDone signals that work side is done and UI thread should call destroy.
- // fUIDone signals that UI window has closed and work thread should call destroy.
- // This allows the window to disappear and end modality when cancelled
- // without making the user wait for ConnectNode to return. The dialog object
- // hangs around in the background until the work thread exits.
- if (IsModal())
- EndModal(fSuccess);
- else
- Show(false);
- if (fWorkDone)
- Destroy();
- else
- fUIDone = true;
-}
-
-void CSendingDialog::OnClose(wxCloseEvent& event)
-{
- if (!event.CanVeto() || fWorkDone || fAbort || !fCanCancel)
- {
- Close();
- }
- else
- {
- event.Veto();
- wxCommandEvent cmdevent;
- OnButtonCancel(cmdevent);
- }
-}
-
-void CSendingDialog::OnButtonOK(wxCommandEvent& event)
-{
- if (fWorkDone)
- Close();
-}
-
-void CSendingDialog::OnButtonCancel(wxCommandEvent& event)
-{
- if (fCanCancel)
- fAbort = true;
-}
-
-void CSendingDialog::OnPaint(wxPaintEvent& event)
-{
- event.Skip();
- if (strlen(pszStatus) > 130)
- m_textCtrlStatus->SetValue(string("\n") + pszStatus);
- else
- m_textCtrlStatus->SetValue(string("\n\n") + pszStatus);
- m_staticTextSending->SetFocus();
- if (!fCanCancel)
- m_buttonCancel->Enable(false);
- if (fWorkDone)
- {
- m_buttonOK->Enable(true);
- m_buttonOK->SetFocus();
- m_buttonCancel->Enable(false);
- }
- if (fAbort && fCanCancel && IsShown())
- {
- strcpy(pszStatus, _("CANCELLED"));
- m_buttonOK->Enable(true);
- m_buttonOK->SetFocus();
- m_buttonCancel->Enable(false);
- m_buttonCancel->SetLabel(_("Cancelled"));
- Close();
- wxMessageBox(_("Transfer cancelled "), _("Sending..."), wxOK, this);
- }
-}
-
-
-//
-// Everything from here on is not in the UI thread and must only communicate
-// with the rest of the dialog through variables and calling repaint.
-//
-
-void CSendingDialog::Repaint()
-{
- Refresh();
- wxPaintEvent event;
- GetEventHandler()->AddPendingEvent(event);
-}
-
-bool CSendingDialog::Status()
-{
- if (fUIDone)
- {
- Destroy();
- return false;
- }
- if (fAbort && fCanCancel)
- {
- memset(pszStatus, 0, 10);
- strcpy(pszStatus, _("CANCELLED"));
- Repaint();
- fWorkDone = true;
- return false;
- }
- return true;
-}
-
-bool CSendingDialog::Status(const string& str)
-{
- if (!Status())
- return false;
-
- // This can be read by the UI thread at any time,
- // so copy in a way that can be read cleanly at all times.
- memset(pszStatus, 0, min(str.size()+1, sizeof(pszStatus)));
- strlcpy(pszStatus, str.c_str(), sizeof(pszStatus));
-
- Repaint();
- return true;
-}
-
-bool CSendingDialog::Error(const string& str)
-{
- fCanCancel = false;
- fWorkDone = true;
- Status(string(_("Error: ")) + str);
- return false;
-}
-
-void SendingDialogStartTransfer(void* parg)
-{
- ((CSendingDialog*)parg)->StartTransfer();
-}
-
-void CSendingDialog::StartTransfer()
-{
- // Make sure we have enough money
- if (nPrice + nTransactionFee > GetBalance())
- {
- Error(_("Insufficient funds"));
- return;
- }
-
- // We may have connected already for product details
- if (!Status(_("Connecting...")))
- return;
- CNode* pnode = ConnectNode(addr, 15 * 60);
- if (!pnode)
- {
- Error(_("Unable to connect"));
- return;
- }
-
- // Send order to seller, with response going to OnReply2 via event handler
- if (!Status(_("Requesting public key...")))
- return;
- pnode->PushRequest("checkorder", wtx, SendingDialogOnReply2, this);
-}
-
-void SendingDialogOnReply2(void* parg, CDataStream& vRecv)
-{
- ((CSendingDialog*)parg)->OnReply2(vRecv);
-}
-
-void CSendingDialog::OnReply2(CDataStream& vRecv)
-{
- if (!Status(_("Received public key...")))
- return;
-
- CScript scriptPubKey;
- int nRet;
- try
- {
- vRecv >> nRet;
- if (nRet > 0)
- {
- string strMessage;
- vRecv >> strMessage;
- Error(_("Transfer was not accepted"));
- //// todo: enlarge the window and enable a hidden white box to put seller's message
- return;
- }
- vRecv >> scriptPubKey;
- }
- catch (...)
- {
- //// what do we want to do about this?
- Error(_("Invalid response received"));
- return;
- }
-
- // Pause to give the user a chance to cancel
- while (wxDateTime::UNow() < start + wxTimeSpan(0, 0, 0, 2 * 1000))
- {
- Sleep(200);
- if (!Status())
- return;
- }
-
- CRITICAL_BLOCK(cs_main)
- {
- // Pay
- if (!Status(_("Creating transaction...")))
- return;
- if (nPrice + nTransactionFee > GetBalance())
- {
- Error(_("Insufficient funds"));
- return;
- }
- CKey key;
- int64 nFeeRequired;
- if (!CreateTransaction(scriptPubKey, nPrice, wtx, key, nFeeRequired))
- {
- if (nPrice + nFeeRequired > GetBalance())
- Error(strprintf(_("This is an oversized transaction that requires a transaction fee of %s"), FormatMoney(nFeeRequired).c_str()));
- else
- Error(_("Transaction creation failed"));
- return;
- }
-
- // Transaction fee
- if (!ThreadSafeAskFee(nFeeRequired, _("Sending..."), this))
- {
- Error(_("Transaction aborted"));
- return;
- }
-
- // Make sure we're still connected
- CNode* pnode = ConnectNode(addr, 2 * 60 * 60);
- if (!pnode)
- {
- Error(_("Lost connection, transaction cancelled"));
- return;
- }
-
- // Last chance to cancel
- Sleep(50);
- if (!Status())
- return;
- fCanCancel = false;
- if (fAbort)
- {
- fCanCancel = true;
- if (!Status())
- return;
- fCanCancel = false;
- }
- if (!Status(_("Sending payment...")))
- return;
-
- // Commit
- if (!CommitTransaction(wtx, key))
- {
- Error(_("The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."));
- return;
- }
-
- // Send payment tx to seller, with response going to OnReply3 via event handler
- CWalletTx wtxSend = wtx;
- wtxSend.fFromMe = false;
- pnode->PushRequest("submitorder", wtxSend, SendingDialogOnReply3, this);
-
- Status(_("Waiting for confirmation..."));
- MainFrameRepaint();
- }
-}
-
-void SendingDialogOnReply3(void* parg, CDataStream& vRecv)
-{
- ((CSendingDialog*)parg)->OnReply3(vRecv);
-}
-
-void CSendingDialog::OnReply3(CDataStream& vRecv)
-{
- int nRet;
- try
- {
- vRecv >> nRet;
- if (nRet > 0)
- {
- Error(_("The payment was sent, but the recipient was unable to verify it.\n"
- "The transaction is recorded and will credit to the recipient,\n"
- "but the comment information will be blank."));
- return;
- }
- }
- catch (...)
- {
- //// what do we want to do about this?
- Error(_("Payment was sent, but an invalid response was received"));
- return;
- }
-
- fSuccess = true;
- fWorkDone = true;
- Status(_("Payment completed"));
-}
-
-
-
-
-
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// CAddressBookDialog
-//
-
-CAddressBookDialog::CAddressBookDialog(wxWindow* parent, const wxString& strInitSelected, int nPageIn, bool fDuringSendIn) : CAddressBookDialogBase(parent)
-{
- // Set initially selected page
- wxNotebookEvent event;
- event.SetSelection(nPageIn);
- OnNotebookPageChanged(event);
- m_notebook->ChangeSelection(nPageIn);
-
- fDuringSend = fDuringSendIn;
- if (!fDuringSend)
- m_buttonCancel->Show(false);
-
- // Set Icon
- wxIcon iconAddressBook;
- iconAddressBook.CopyFromBitmap(wxBitmap(addressbook16_xpm));
- SetIcon(iconAddressBook);
-
- // Init column headers
- m_listCtrlSending->InsertColumn(0, _("Name"), wxLIST_FORMAT_LEFT, 200);
- m_listCtrlSending->InsertColumn(1, _("Address"), wxLIST_FORMAT_LEFT, 350);
- m_listCtrlSending->SetFocus();
- m_listCtrlReceiving->InsertColumn(0, _("Label"), wxLIST_FORMAT_LEFT, 200);
- m_listCtrlReceiving->InsertColumn(1, _("Bitcoin Address"), wxLIST_FORMAT_LEFT, 350);
- m_listCtrlReceiving->SetFocus();
-
- // Fill listctrl with address book data
- CRITICAL_BLOCK(cs_mapKeys)
- CRITICAL_BLOCK(cs_mapAddressBook)
- {
- string strDefaultReceiving = (string)pframeMain->m_textCtrlAddress->GetValue();
- foreach(const PAIRTYPE(string, string)& item, mapAddressBook)
- {
- string strAddress = item.first;
- string strName = item.second;
- uint160 hash160;
- bool fMine = (AddressToHash160(strAddress, hash160) && mapPubKeys.count(hash160));
- wxListCtrl* plistCtrl = fMine ? m_listCtrlReceiving : m_listCtrlSending;
- int nIndex = InsertLine(plistCtrl, strName, strAddress);
- if (strAddress == (fMine ? strDefaultReceiving : string(strInitSelected)))
- plistCtrl->SetItemState(nIndex, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED);
- }
- }
-}
-
-wxString CAddressBookDialog::GetSelectedAddress()
-{
- int nIndex = GetSelection(m_listCtrl);
- if (nIndex == -1)
- return "";
- return GetItemText(m_listCtrl, nIndex, 1);
-}
-
-wxString CAddressBookDialog::GetSelectedSendingAddress()
-{
- int nIndex = GetSelection(m_listCtrlSending);
- if (nIndex == -1)
- return "";
- return GetItemText(m_listCtrlSending, nIndex, 1);
-}
-
-wxString CAddressBookDialog::GetSelectedReceivingAddress()
-{
- int nIndex = GetSelection(m_listCtrlReceiving);
- if (nIndex == -1)
- return "";
- return GetItemText(m_listCtrlReceiving, nIndex, 1);
-}
-
-void CAddressBookDialog::OnNotebookPageChanged(wxNotebookEvent& event)
-{
- event.Skip();
- nPage = event.GetSelection();
- if (nPage == SENDING)
- m_listCtrl = m_listCtrlSending;
- else if (nPage == RECEIVING)
- m_listCtrl = m_listCtrlReceiving;
- m_buttonDelete->Show(nPage == SENDING);
- m_buttonCopy->Show(nPage == RECEIVING);
- this->Layout();
- m_listCtrl->SetFocus();
-}
-
-void CAddressBookDialog::OnListEndLabelEdit(wxListEvent& event)
-{
- // Update address book with edited name
- event.Skip();
- if (event.IsEditCancelled())
- return;
- string strAddress = (string)GetItemText(m_listCtrl, event.GetIndex(), 1);
- SetAddressBookName(strAddress, string(event.GetText()));
- pframeMain->RefreshListCtrl();
-}
-
-void CAddressBookDialog::OnListItemSelected(wxListEvent& event)
-{
- event.Skip();
- if (nPage == RECEIVING)
- SetDefaultReceivingAddress((string)GetSelectedReceivingAddress());
-}
-
-void CAddressBookDialog::OnListItemActivated(wxListEvent& event)
-{
- event.Skip();
- if (fDuringSend)
- {
- // Doubleclick returns selection
- EndModal(GetSelectedAddress() != "" ? 2 : 0);
- return;
- }
-
- // Doubleclick edits item
- wxCommandEvent event2;
- OnButtonEdit(event2);
-}
-
-void CAddressBookDialog::OnButtonDelete(wxCommandEvent& event)
-{
- if (nPage != SENDING)
- return;
- for (int nIndex = m_listCtrl->GetItemCount()-1; nIndex >= 0; nIndex--)
- {
- if (m_listCtrl->GetItemState(nIndex, wxLIST_STATE_SELECTED))
- {
- string strAddress = (string)GetItemText(m_listCtrl, nIndex, 1);
- CWalletDB().EraseName(strAddress);
- m_listCtrl->DeleteItem(nIndex);
- }
- }
- pframeMain->RefreshListCtrl();
-}
-
-void CAddressBookDialog::OnButtonCopy(wxCommandEvent& event)
-{
- // Copy address box to clipboard
- if (wxTheClipboard->Open())
- {
- wxTheClipboard->SetData(new wxTextDataObject(GetSelectedAddress()));
- wxTheClipboard->Close();
- }
-}
-
-bool CAddressBookDialog::CheckIfMine(const string& strAddress, const string& strTitle)
-{
- uint160 hash160;
- bool fMine = (AddressToHash160(strAddress, hash160) && mapPubKeys.count(hash160));
- if (fMine)
- wxMessageBox(_("This is one of your own addresses for receiving payments and cannot be entered in the address book. "), strTitle);
- return fMine;
-}
-
-void CAddressBookDialog::OnButtonEdit(wxCommandEvent& event)
-{
- int nIndex = GetSelection(m_listCtrl);
- if (nIndex == -1)
- return;
- string strName = (string)m_listCtrl->GetItemText(nIndex);
- string strAddress = (string)GetItemText(m_listCtrl, nIndex, 1);
- string strAddressOrg = strAddress;
-
- if (nPage == SENDING)
- {
- // Ask name and address
- do
- {
- CGetTextFromUserDialog dialog(this, _("Edit Address"), _("Name"), strName, _("Address"), strAddress);
- if (!dialog.ShowModal())
- return;
- strName = dialog.GetValue1();
- strAddress = dialog.GetValue2();
- }
- while (CheckIfMine(strAddress, _("Edit Address")));
-
- }
- else if (nPage == RECEIVING)
- {
- // Ask name
- CGetTextFromUserDialog dialog(this, _("Edit Address Label"), _("Label"), strName);
- if (!dialog.ShowModal())
- return;
- strName = dialog.GetValue();
- }
-
- // Write back
- if (strAddress != strAddressOrg)
- CWalletDB().EraseName(strAddressOrg);
- SetAddressBookName(strAddress, strName);
- m_listCtrl->SetItem(nIndex, 1, strAddress);
- m_listCtrl->SetItemText(nIndex, strName);
- pframeMain->RefreshListCtrl();
-}
-
-void CAddressBookDialog::OnButtonNew(wxCommandEvent& event)
-{
- string strName;
- string strAddress;
-
- if (nPage == SENDING)
- {
- // Ask name and address
- do
- {
- CGetTextFromUserDialog dialog(this, _("Add Address"), _("Name"), strName, _("Address"), strAddress);
- if (!dialog.ShowModal())
- return;
- strName = dialog.GetValue1();
- strAddress = dialog.GetValue2();
- }
- while (CheckIfMine(strAddress, _("Add Address")));
- }
- else if (nPage == RECEIVING)
- {
- // Ask name
- CGetTextFromUserDialog dialog(this,
- _("New Receiving Address"),
- _("It's good policy to use a new address for each payment you receive.\n\nLabel"),
- "");
- if (!dialog.ShowModal())
- return;
- strName = dialog.GetValue();
-
- // Generate new key
- strAddress = PubKeyToAddress(GenerateNewKey());
- }
-
- // Add to list and select it
- SetAddressBookName(strAddress, strName);
- int nIndex = InsertLine(m_listCtrl, strName, strAddress);
- SetSelection(m_listCtrl, nIndex);
- m_listCtrl->SetFocus();
- if (nPage == SENDING)
- pframeMain->RefreshListCtrl();
-}
-
-void CAddressBookDialog::OnButtonOK(wxCommandEvent& event)
-{
- // OK
- EndModal(GetSelectedAddress() != "" ? 1 : 0);
-}
-
-void CAddressBookDialog::OnButtonCancel(wxCommandEvent& event)
-{
- // Cancel
- EndModal(0);
-}
-
-void CAddressBookDialog::OnClose(wxCloseEvent& event)
-{
- // Close
- EndModal(0);
-}
-
-
-
-
-
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// CMyTaskBarIcon
-//
-
-enum
-{
- ID_TASKBAR_RESTORE = 10001,
- ID_TASKBAR_OPTIONS,
- ID_TASKBAR_GENERATE,
- ID_TASKBAR_EXIT,
-};
-
-BEGIN_EVENT_TABLE(CMyTaskBarIcon, wxTaskBarIcon)
- EVT_TASKBAR_LEFT_DCLICK(CMyTaskBarIcon::OnLeftButtonDClick)
- EVT_MENU(ID_TASKBAR_RESTORE, CMyTaskBarIcon::OnMenuRestore)
- EVT_MENU(ID_TASKBAR_OPTIONS, CMyTaskBarIcon::OnMenuOptions)
- EVT_MENU(ID_TASKBAR_GENERATE, CMyTaskBarIcon::OnMenuGenerate)
- EVT_UPDATE_UI(ID_TASKBAR_GENERATE, CMyTaskBarIcon::OnUpdateUIGenerate)
- EVT_MENU(ID_TASKBAR_EXIT, CMyTaskBarIcon::OnMenuExit)
-END_EVENT_TABLE()
-
-void CMyTaskBarIcon::Show(bool fShow)
-{
- static char pszPrevTip[200];
- if (fShow)
- {
- string strTooltip = _("Bitcoin");
- if (fGenerateBitcoins)
- strTooltip = _("Bitcoin - Generating");
- if (fGenerateBitcoins && vNodes.empty())
- strTooltip = _("Bitcoin - (not connected)");
-
- // Optimization, only update when changed, using char array to be reentrant
- if (strncmp(pszPrevTip, strTooltip.c_str(), sizeof(pszPrevTip)-1) != 0)
- {
- strlcpy(pszPrevTip, strTooltip.c_str(), sizeof(pszPrevTip));
-#ifdef __WXMSW__
- // somehow it'll choose the wrong size and scale it down if
- // we use the main icon, so we hand it one with only 16x16
- SetIcon(wxICON(favicon), strTooltip);
-#else
- SetIcon(bitcoin80_xpm, strTooltip);
-#endif
- }
- }
- else
- {
- strlcpy(pszPrevTip, "", sizeof(pszPrevTip));
- RemoveIcon();
- }
-}
-
-void CMyTaskBarIcon::Hide()
-{
- Show(false);
-}
-
-void CMyTaskBarIcon::OnLeftButtonDClick(wxTaskBarIconEvent& event)
-{
- Restore();
-}
-
-void CMyTaskBarIcon::OnMenuRestore(wxCommandEvent& event)
-{
- Restore();
-}
-
-void CMyTaskBarIcon::OnMenuOptions(wxCommandEvent& event)
-{
- // Since it's modal, get the main window to do it
- wxCommandEvent event2(wxEVT_COMMAND_MENU_SELECTED, wxID_PREFERENCES);
- pframeMain->GetEventHandler()->AddPendingEvent(event2);
-}
-
-void CMyTaskBarIcon::Restore()
-{
- pframeMain->Show();
- wxIconizeEvent event(0, false);
- pframeMain->GetEventHandler()->AddPendingEvent(event);
- pframeMain->Iconize(false);
- pframeMain->Raise();
-}
-
-void CMyTaskBarIcon::OnMenuGenerate(wxCommandEvent& event)
-{
- GenerateBitcoins(event.IsChecked());
-}
-
-void CMyTaskBarIcon::OnUpdateUIGenerate(wxUpdateUIEvent& event)
-{
- event.Check(fGenerateBitcoins);
-}
-
-void CMyTaskBarIcon::OnMenuExit(wxCommandEvent& event)
-{
- pframeMain->Close(true);
-}
-
-void CMyTaskBarIcon::UpdateTooltip()
-{
- if (IsIconInstalled())
- Show(true);
-}
-
-wxMenu* CMyTaskBarIcon::CreatePopupMenu()
-{
- wxMenu* pmenu = new wxMenu;
- pmenu->Append(ID_TASKBAR_RESTORE, _("&Open Bitcoin"));
- pmenu->Append(ID_TASKBAR_OPTIONS, _("O&ptions..."));
- pmenu->AppendCheckItem(ID_TASKBAR_GENERATE, _("&Generate Coins"))->Check(fGenerateBitcoins);
-#ifndef __WXMAC_OSX__ // Mac has built-in quit menu
- pmenu->AppendSeparator();
- pmenu->Append(ID_TASKBAR_EXIT, _("E&xit"));
-#endif
- return pmenu;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-void CreateMainWindow()
-{
- pframeMain = new CMainFrame(NULL);
- if (mapArgs.count("-min"))
- pframeMain->Iconize(true);
- pframeMain->Show(true); // have to show first to get taskbar button to hide
- if (fMinimizeToTray && pframeMain->IsIconized())
- fClosedToTray = true;
- pframeMain->Show(!fClosedToTray);
- ptaskbaricon->Show(fMinimizeToTray || fClosedToTray);
- CreateThread(ThreadDelayedRepaint, NULL);
-}
+// Copyright (c) 2009-2010 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +#include "headers.h" +#ifdef _MSC_VER +#include <crtdbg.h> +#endif + + + +DEFINE_EVENT_TYPE(wxEVT_UITHREADCALL) + +CMainFrame* pframeMain = NULL; +CMyTaskBarIcon* ptaskbaricon = NULL; +bool fClosedToTray = false; + + + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// Util +// + +void HandleCtrlA(wxKeyEvent& event) +{ + // Ctrl-a select all + event.Skip(); + wxTextCtrl* textCtrl = (wxTextCtrl*)event.GetEventObject(); + if (event.GetModifiers() == wxMOD_CONTROL && event.GetKeyCode() == 'A') + textCtrl->SetSelection(-1, -1); +} + +bool Is24HourTime() +{ + //char pszHourFormat[256]; + //pszHourFormat[0] = '\0'; + //GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ITIME, pszHourFormat, 256); + //return (pszHourFormat[0] != '0'); + return true; +} + +string DateStr(int64 nTime) +{ + // Can only be used safely here in the UI + return (string)wxDateTime((time_t)nTime).FormatDate(); +} + +string DateTimeStr(int64 nTime) +{ + // Can only be used safely here in the UI + wxDateTime datetime((time_t)nTime); + if (Is24HourTime()) + return (string)datetime.Format("%x %H:%M"); + else + return (string)datetime.Format("%x ") + itostr((datetime.GetHour() + 11) % 12 + 1) + (string)datetime.Format(":%M %p"); +} + +wxString GetItemText(wxListCtrl* listCtrl, int nIndex, int nColumn) +{ + // Helper to simplify access to listctrl + wxListItem item; + item.m_itemId = nIndex; + item.m_col = nColumn; + item.m_mask = wxLIST_MASK_TEXT; + if (!listCtrl->GetItem(item)) + return ""; + return item.GetText(); +} + +int InsertLine(wxListCtrl* listCtrl, const wxString& str0, const wxString& str1) +{ + int nIndex = listCtrl->InsertItem(listCtrl->GetItemCount(), str0); + listCtrl->SetItem(nIndex, 1, str1); + return nIndex; +} + +int InsertLine(wxListCtrl* listCtrl, const wxString& str0, const wxString& str1, const wxString& str2, const wxString& str3, const wxString& str4) +{ + int nIndex = listCtrl->InsertItem(listCtrl->GetItemCount(), str0); + listCtrl->SetItem(nIndex, 1, str1); + listCtrl->SetItem(nIndex, 2, str2); + listCtrl->SetItem(nIndex, 3, str3); + listCtrl->SetItem(nIndex, 4, str4); + return nIndex; +} + +int InsertLine(wxListCtrl* listCtrl, void* pdata, const wxString& str0, const wxString& str1, const wxString& str2, const wxString& str3, const wxString& str4) +{ + int nIndex = listCtrl->InsertItem(listCtrl->GetItemCount(), str0); + listCtrl->SetItemPtrData(nIndex, (wxUIntPtr)pdata); + listCtrl->SetItem(nIndex, 1, str1); + listCtrl->SetItem(nIndex, 2, str2); + listCtrl->SetItem(nIndex, 3, str3); + listCtrl->SetItem(nIndex, 4, str4); + return nIndex; +} + +void SetSelection(wxListCtrl* listCtrl, int nIndex) +{ + int nSize = listCtrl->GetItemCount(); + long nState = (wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED); + for (int i = 0; i < nSize; i++) + listCtrl->SetItemState(i, (i == nIndex ? nState : 0), nState); +} + +int GetSelection(wxListCtrl* listCtrl) +{ + int nSize = listCtrl->GetItemCount(); + for (int i = 0; i < nSize; i++) + if (listCtrl->GetItemState(i, wxLIST_STATE_FOCUSED)) + return i; + return -1; +} + +string HtmlEscape(const char* psz, bool fMultiLine=false) +{ + int len = 0; + for (const char* p = psz; *p; p++) + { + if (*p == '<') len += 4; + else if (*p == '>') len += 4; + else if (*p == '&') len += 5; + else if (*p == '"') len += 6; + else if (*p == ' ' && p > psz && p[-1] == ' ' && p[1] == ' ') len += 6; + else if (*p == '\n' && fMultiLine) len += 5; + else + len++; + } + string str; + str.reserve(len); + for (const char* p = psz; *p; p++) + { + if (*p == '<') str += "<"; + else if (*p == '>') str += ">"; + else if (*p == '&') str += "&"; + else if (*p == '"') str += """; + else if (*p == ' ' && p > psz && p[-1] == ' ' && p[1] == ' ') str += " "; + else if (*p == '\n' && fMultiLine) str += "<br>\n"; + else + str += *p; + } + return str; +} + +string HtmlEscape(const string& str, bool fMultiLine=false) +{ + return HtmlEscape(str.c_str(), fMultiLine); +} + +void CalledMessageBox(const string& message, const string& caption, int style, wxWindow* parent, int x, int y, int* pnRet, bool* pfDone) +{ + *pnRet = wxMessageBox(message, caption, style, parent, x, y); + *pfDone = true; +} + +int ThreadSafeMessageBox(const string& message, const string& caption, int style, wxWindow* parent, int x, int y) +{ +#ifdef __WXMSW__ + return wxMessageBox(message, caption, style, parent, x, y); +#else + if (wxThread::IsMain() || fDaemon) + { + return wxMessageBox(message, caption, style, parent, x, y); + } + else + { + int nRet = 0; + bool fDone = false; + UIThreadCall(bind(CalledMessageBox, message, caption, style, parent, x, y, &nRet, &fDone)); + while (!fDone) + Sleep(100); + return nRet; + } +#endif +} + +bool ThreadSafeAskFee(int64 nFeeRequired, const string& strCaption, wxWindow* parent) +{ + if (nFeeRequired == 0 || fDaemon) + return true; + string strMessage = strprintf( + _("This transaction is over the size limit. You can still send it for a fee of %s, " + "which goes to the nodes that process your transaction and helps to support the network. " + "Do you want to pay the fee?"), + FormatMoney(nFeeRequired).c_str()); + return (ThreadSafeMessageBox(strMessage, strCaption, wxYES_NO, parent) == wxYES); +} + +void CalledSetStatusBar(const string& strText, int nField) +{ + if (pframeMain && pframeMain->m_statusBar) + pframeMain->m_statusBar->SetStatusText(strText, nField); +} + +void SetDefaultReceivingAddress(const string& strAddress) +{ + // Update main window address and database + if (pframeMain == NULL) + return; + if (strAddress != pframeMain->m_textCtrlAddress->GetValue()) + { + uint160 hash160; + if (!AddressToHash160(strAddress, hash160)) + return; + if (!mapPubKeys.count(hash160)) + return; + CWalletDB().WriteDefaultKey(mapPubKeys[hash160]); + pframeMain->m_textCtrlAddress->SetValue(strAddress); + } +} + + + + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CMainFrame +// + +CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) +{ + Connect(wxEVT_UITHREADCALL, wxCommandEventHandler(CMainFrame::OnUIThreadCall), NULL, this); + + // Set initially selected page + wxNotebookEvent event; + event.SetSelection(0); + OnNotebookPageChanged(event); + m_notebook->ChangeSelection(0); + + // Init + fRefreshListCtrl = false; + fRefreshListCtrlRunning = false; + fOnSetFocusAddress = false; + fRefresh = false; + m_choiceFilter->SetSelection(0); + double dResize = 1.0; +#ifdef __WXMSW__ + SetIcon(wxICON(bitcoin)); +#else + SetIcon(bitcoin80_xpm); + SetBackgroundColour(m_toolBar->GetBackgroundColour()); + wxFont fontTmp = m_staticText41->GetFont(); + fontTmp.SetFamily(wxFONTFAMILY_TELETYPE); + m_staticTextBalance->SetFont(fontTmp); + m_staticTextBalance->SetSize(140, 17); + // resize to fit ubuntu's huge default font + dResize = 1.22; + SetSize(dResize * GetSize().GetWidth(), 1.15 * GetSize().GetHeight()); +#endif + m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); + m_listCtrl->SetFocus(); + ptaskbaricon = new CMyTaskBarIcon(); +#ifdef __WXMAC__ + // Mac automatically moves wxID_EXIT, wxID_PREFERENCES and wxID_ABOUT + // to their standard places, leaving these menus empty. + GetMenuBar()->Remove(2); // remove Help menu + GetMenuBar()->Remove(0); // remove File menu +#endif + + // Init column headers + int nDateWidth = DateTimeStr(1229413914).size() * 6 + 8; + if (!strstr(DateTimeStr(1229413914).c_str(), "2008")) + nDateWidth += 12; +#ifdef __WXMAC__ + nDateWidth += 5; + dResize -= 0.01; +#endif + wxListCtrl* pplistCtrl[] = {m_listCtrlAll, m_listCtrlSentReceived, m_listCtrlSent, m_listCtrlReceived}; + foreach(wxListCtrl* p, pplistCtrl) + { + p->InsertColumn(0, "", wxLIST_FORMAT_LEFT, dResize * 0); + p->InsertColumn(1, "", wxLIST_FORMAT_LEFT, dResize * 0); + p->InsertColumn(2, _("Status"), wxLIST_FORMAT_LEFT, dResize * 112); + p->InsertColumn(3, _("Date"), wxLIST_FORMAT_LEFT, dResize * nDateWidth); + p->InsertColumn(4, _("Description"), wxLIST_FORMAT_LEFT, dResize * 409 - nDateWidth); + p->InsertColumn(5, _("Debit"), wxLIST_FORMAT_RIGHT, dResize * 79); + p->InsertColumn(6, _("Credit"), wxLIST_FORMAT_RIGHT, dResize * 79); + } + + // Init status bar + int pnWidths[3] = { -100, 88, 300 }; +#ifndef __WXMSW__ + pnWidths[1] = pnWidths[1] * 1.1 * dResize; + pnWidths[2] = pnWidths[2] * 1.1 * dResize; +#endif + m_statusBar->SetFieldsCount(3, pnWidths); + + // Fill your address text box + vector<unsigned char> vchPubKey; + if (CWalletDB("r").ReadDefaultKey(vchPubKey)) + m_textCtrlAddress->SetValue(PubKeyToAddress(vchPubKey)); + + // Fill listctrl with wallet transactions + RefreshListCtrl(); +} + +CMainFrame::~CMainFrame() +{ + pframeMain = NULL; + delete ptaskbaricon; + ptaskbaricon = NULL; +} + +void CMainFrame::OnNotebookPageChanged(wxNotebookEvent& event) +{ + event.Skip(); + nPage = event.GetSelection(); + if (nPage == ALL) + { + m_listCtrl = m_listCtrlAll; + fShowGenerated = true; + fShowSent = true; + fShowReceived = true; + } + else if (nPage == SENTRECEIVED) + { + m_listCtrl = m_listCtrlSentReceived; + fShowGenerated = false; + fShowSent = true; + fShowReceived = true; + } + else if (nPage == SENT) + { + m_listCtrl = m_listCtrlSent; + fShowGenerated = false; + fShowSent = true; + fShowReceived = false; + } + else if (nPage == RECEIVED) + { + m_listCtrl = m_listCtrlReceived; + fShowGenerated = false; + fShowSent = false; + fShowReceived = true; + } + RefreshListCtrl(); + m_listCtrl->SetFocus(); +} + +void CMainFrame::OnClose(wxCloseEvent& event) +{ + if (fMinimizeOnClose && event.CanVeto() && !IsIconized()) + { + // Divert close to minimize + event.Veto(); + fClosedToTray = true; + Iconize(true); + } + else + { + Destroy(); + CreateThread(Shutdown, NULL); + } +} + +void CMainFrame::OnIconize(wxIconizeEvent& event) +{ + event.Skip(); + // Hide the task bar button when minimized. + // Event is sent when the frame is minimized or restored. + // wxWidgets 2.8.9 doesn't have IsIconized() so there's no way + // to get rid of the deprecated warning. Just ignore it. + if (!event.Iconized()) + fClosedToTray = false; +//#ifdef __WXMSW__ + // The tray icon sometimes disappears on ubuntu karmic + // Hiding the taskbar button doesn't work cleanly on ubuntu lucid + if (fMinimizeToTray && event.Iconized()) + fClosedToTray = true; + Show(!fClosedToTray); +//#endif + ptaskbaricon->Show(fMinimizeToTray || fClosedToTray); +} + +void CMainFrame::OnMouseEvents(wxMouseEvent& event) +{ + event.Skip(); + RandAddSeed(); + RAND_add(&event.m_x, sizeof(event.m_x), 0.25); + RAND_add(&event.m_y, sizeof(event.m_y), 0.25); +} + +void CMainFrame::OnListColBeginDrag(wxListEvent& event) +{ + // Hidden columns not resizeable + if (event.GetColumn() <= 1 && !fDebug) + event.Veto(); + else + event.Skip(); +} + +int CMainFrame::GetSortIndex(const string& strSort) +{ +#ifdef __WXMSW__ + return 0; +#else + // The wx generic listctrl implementation used on GTK doesn't sort, + // so we have to do it ourselves. Remember, we sort in reverse order. + // In the wx generic implementation, they store the list of items + // in a vector, so indexed lookups are fast, but inserts are slower + // the closer they are to the top. + int low = 0; + int high = m_listCtrl->GetItemCount(); + while (low < high) + { + int mid = low + ((high - low) / 2); + if (strSort.compare(m_listCtrl->GetItemText(mid).c_str()) >= 0) + high = mid; + else + low = mid + 1; + } + return low; +#endif +} + +void CMainFrame::InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5, const wxString& str6) +{ + strSort = " " + strSort; // leading space to workaround wx2.9.0 ubuntu 9.10 bug + long nData = *(long*)&hashKey; // where first char of hidden column is displayed + + // Find item + if (!fNew && nIndex == -1) + { + string strHash = " " + hashKey.ToString(); + while ((nIndex = m_listCtrl->FindItem(nIndex, nData)) != -1) + if (GetItemText(m_listCtrl, nIndex, 1) == strHash) + break; + } + + // fNew is for blind insert, only use if you're sure it's new + if (fNew || nIndex == -1) + { + nIndex = m_listCtrl->InsertItem(GetSortIndex(strSort), strSort); + } + else + { + // If sort key changed, must delete and reinsert to make it relocate + if (GetItemText(m_listCtrl, nIndex, 0) != strSort) + { + m_listCtrl->DeleteItem(nIndex); + nIndex = m_listCtrl->InsertItem(GetSortIndex(strSort), strSort); + } + } + + m_listCtrl->SetItem(nIndex, 1, " " + hashKey.ToString()); + m_listCtrl->SetItem(nIndex, 2, str2); + m_listCtrl->SetItem(nIndex, 3, str3); + m_listCtrl->SetItem(nIndex, 4, str4); + m_listCtrl->SetItem(nIndex, 5, str5); + m_listCtrl->SetItem(nIndex, 6, str6); + m_listCtrl->SetItemData(nIndex, nData); +} + +bool CMainFrame::DeleteLine(uint256 hashKey) +{ + long nData = *(long*)&hashKey; + + // Find item + int nIndex = -1; + string strHash = " " + hashKey.ToString(); + while ((nIndex = m_listCtrl->FindItem(nIndex, nData)) != -1) + if (GetItemText(m_listCtrl, nIndex, 1) == strHash) + break; + + if (nIndex != -1) + m_listCtrl->DeleteItem(nIndex); + + return nIndex != -1; +} + +string FormatTxStatus(const CWalletTx& wtx) +{ + // Status + if (!wtx.IsFinal()) + { + if (wtx.nLockTime < 500000000) + return strprintf(_("Open for %d blocks"), nBestHeight - wtx.nLockTime); + else + return strprintf(_("Open until %s"), DateTimeStr(wtx.nLockTime).c_str()); + } + else + { + int nDepth = wtx.GetDepthInMainChain(); + if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0) + return strprintf(_("%d/offline?"), nDepth); + else if (nDepth < 6) + return strprintf(_("%d/unconfirmed"), nDepth); + else + return strprintf(_("%d confirmations"), nDepth); + } +} + +string SingleLine(const string& strIn) +{ + string strOut; + bool fOneSpace = false; + foreach(int c, strIn) + { + if (isspace(c)) + { + fOneSpace = true; + } + else if (c > ' ') + { + if (fOneSpace && !strOut.empty()) + strOut += ' '; + strOut += c; + fOneSpace = false; + } + } + return strOut; +} + +bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) +{ + int64 nTime = wtx.nTimeDisplayed = wtx.GetTxTime(); + int64 nCredit = wtx.GetCredit(true); + int64 nDebit = wtx.GetDebit(); + int64 nNet = nCredit - nDebit; + uint256 hash = wtx.GetHash(); + string strStatus = FormatTxStatus(wtx); + map<string, string> mapValue = wtx.mapValue; + wtx.nLinesDisplayed = 1; + nListViewUpdated++; + + // Filter + if (wtx.IsCoinBase()) + { + // Don't show generated coin until confirmed by at least one block after it + // so we don't get the user's hopes up until it looks like it's probably accepted. + // + // It is not an error when generated blocks are not accepted. By design, + // some percentage of blocks, like 10% or more, will end up not accepted. + // This is the normal mechanism by which the network copes with latency. + // + // We display regular transactions right away before any confirmation + // because they can always get into some block eventually. Generated coins + // are special because if their block is not accepted, they are not valid. + // + if (wtx.GetDepthInMainChain() < 2) + { + wtx.nLinesDisplayed = 0; + return false; + } + + if (!fShowGenerated) + return false; + } + + // Find the block the tx is in + CBlockIndex* pindex = NULL; + map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(wtx.hashBlock); + if (mi != mapBlockIndex.end()) + pindex = (*mi).second; + + // Sort order, unrecorded transactions sort to the top + string strSort = strprintf("%010d-%01d-%010u", + (pindex ? pindex->nHeight : INT_MAX), + (wtx.IsCoinBase() ? 1 : 0), + wtx.nTimeReceived); + + // Insert line + if (nNet > 0 || wtx.IsCoinBase()) + { + // + // Credit + // + string strDescription; + if (wtx.IsCoinBase()) + { + // Generated + strDescription = _("Generated"); + if (nCredit == 0) + { + int64 nUnmatured = 0; + foreach(const CTxOut& txout, wtx.vout) + nUnmatured += txout.GetCredit(); + if (wtx.IsInMainChain()) + { + strDescription = strprintf(_("Generated (%s matures in %d more blocks)"), FormatMoney(nUnmatured).c_str(), wtx.GetBlocksToMaturity()); + + // Check if the block was requested by anyone + if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0) + strDescription = _("Generated - Warning: This block was not received by any other nodes and will probably not be accepted!"); + } + else + { + strDescription = _("Generated (not accepted)"); + } + } + } + else if (!mapValue["from"].empty() || !mapValue["message"].empty()) + { + // Received by IP connection + if (!fShowReceived) + return false; + if (!mapValue["from"].empty()) + strDescription += _("From: ") + mapValue["from"]; + if (!mapValue["message"].empty()) + { + if (!strDescription.empty()) + strDescription += " - "; + strDescription += mapValue["message"]; + } + } + else + { + // Received by Bitcoin Address + if (!fShowReceived) + return false; + foreach(const CTxOut& txout, wtx.vout) + { + if (txout.IsMine()) + { + vector<unsigned char> vchPubKey; + if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey)) + { + CRITICAL_BLOCK(cs_mapAddressBook) + { + //strDescription += _("Received payment to "); + //strDescription += _("Received with address "); + strDescription += _("From: unknown, Received with: "); + string strAddress = PubKeyToAddress(vchPubKey); + map<string, string>::iterator mi = mapAddressBook.find(strAddress); + if (mi != mapAddressBook.end() && !(*mi).second.empty()) + { + string strLabel = (*mi).second; + strDescription += strAddress.substr(0,12) + "... "; + strDescription += "(" + strLabel + ")"; + } + else + strDescription += strAddress; + } + } + break; + } + } + } + + InsertLine(fNew, nIndex, hash, strSort, + strStatus, + nTime ? DateTimeStr(nTime) : "", + SingleLine(strDescription), + "", + FormatMoney(nNet, true)); + } + else + { + bool fAllFromMe = true; + foreach(const CTxIn& txin, wtx.vin) + fAllFromMe = fAllFromMe && txin.IsMine(); + + bool fAllToMe = true; + foreach(const CTxOut& txout, wtx.vout) + fAllToMe = fAllToMe && txout.IsMine(); + + if (fAllFromMe && fAllToMe) + { + // Payment to self + int64 nValue = wtx.vout[0].nValue; + InsertLine(fNew, nIndex, hash, strSort, + strStatus, + nTime ? DateTimeStr(nTime) : "", + _("Payment to yourself"), + "", + ""); + /// issue: can't tell which is the payment and which is the change anymore + // FormatMoney(nNet - nValue, true), + // FormatMoney(nValue, true)); + } + else if (fAllFromMe) + { + // + // Debit + // + if (!fShowSent) + return false; + + int64 nTxFee = nDebit - wtx.GetValueOut(); + wtx.nLinesDisplayed = 0; + for (int nOut = 0; nOut < wtx.vout.size(); nOut++) + { + const CTxOut& txout = wtx.vout[nOut]; + if (txout.IsMine()) + continue; + + string strAddress; + if (!mapValue["to"].empty()) + { + // Sent to IP + strAddress = mapValue["to"]; + } + else + { + // Sent to Bitcoin Address + uint160 hash160; + if (ExtractHash160(txout.scriptPubKey, hash160)) + strAddress = Hash160ToAddress(hash160); + } + + string strDescription = _("To: "); + CRITICAL_BLOCK(cs_mapAddressBook) + if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty()) + strDescription += mapAddressBook[strAddress] + " "; + strDescription += strAddress; + if (!mapValue["message"].empty()) + { + if (!strDescription.empty()) + strDescription += " - "; + strDescription += mapValue["message"]; + } + + int64 nValue = txout.nValue; + if (nTxFee > 0) + { + nValue += nTxFee; + nTxFee = 0; + } + + InsertLine(fNew, nIndex, hash, strprintf("%s-%d", strSort.c_str(), nOut), + strStatus, + nTime ? DateTimeStr(nTime) : "", + SingleLine(strDescription), + FormatMoney(-nValue, true), + ""); + wtx.nLinesDisplayed++; + } + } + else + { + // + // Mixed debit transaction, can't break down payees + // + bool fAllMine = true; + foreach(const CTxOut& txout, wtx.vout) + fAllMine = fAllMine && txout.IsMine(); + foreach(const CTxIn& txin, wtx.vin) + fAllMine = fAllMine && txin.IsMine(); + + InsertLine(fNew, nIndex, hash, strSort, + strStatus, + nTime ? DateTimeStr(nTime) : "", + "", + FormatMoney(nNet, true), + ""); + } + } + + return true; +} + +void CMainFrame::RefreshListCtrl() +{ + fRefreshListCtrl = true; + ::wxWakeUpIdle(); +} + +void CMainFrame::OnIdle(wxIdleEvent& event) +{ + if (fRefreshListCtrl) + { + // Collect list of wallet transactions and sort newest first + bool fEntered = false; + vector<pair<unsigned int, uint256> > vSorted; + TRY_CRITICAL_BLOCK(cs_mapWallet) + { + printf("RefreshListCtrl starting\n"); + fEntered = true; + fRefreshListCtrl = false; + vWalletUpdated.clear(); + + // Do the newest transactions first + vSorted.reserve(mapWallet.size()); + for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx& wtx = (*it).second; + unsigned int nTime = UINT_MAX - wtx.GetTxTime(); + vSorted.push_back(make_pair(nTime, (*it).first)); + } + m_listCtrl->DeleteAllItems(); + } + if (!fEntered) + return; + + sort(vSorted.begin(), vSorted.end()); + + // Fill list control + for (int i = 0; i < vSorted.size();) + { + if (fShutdown) + return; + bool fEntered = false; + TRY_CRITICAL_BLOCK(cs_mapWallet) + { + fEntered = true; + uint256& hash = vSorted[i++].second; + map<uint256, CWalletTx>::iterator mi = mapWallet.find(hash); + if (mi != mapWallet.end()) + InsertTransaction((*mi).second, true); + } + if (!fEntered || i == 100 || i % 500 == 0) + wxYield(); + } + + printf("RefreshListCtrl done\n"); + + // Update transaction total display + MainFrameRepaint(); + } + else + { + // Check for time updates + static int64 nLastTime; + if (GetTime() > nLastTime + 30) + { + TRY_CRITICAL_BLOCK(cs_mapWallet) + { + nLastTime = GetTime(); + for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + CWalletTx& wtx = (*it).second; + if (wtx.nTimeDisplayed && wtx.nTimeDisplayed != wtx.GetTxTime()) + InsertTransaction(wtx, false); + } + } + } + } +} + +void CMainFrame::RefreshStatusColumn() +{ + static int nLastTop; + static CBlockIndex* pindexLastBest; + static unsigned int nLastRefreshed; + + int nTop = max((int)m_listCtrl->GetTopItem(), 0); + if (nTop == nLastTop && pindexLastBest == pindexBest) + return; + + TRY_CRITICAL_BLOCK(cs_mapWallet) + { + int nStart = nTop; + int nEnd = min(nStart + 100, m_listCtrl->GetItemCount()); + + if (pindexLastBest == pindexBest && nLastRefreshed == nListViewUpdated) + { + // If no updates, only need to do the part that moved onto the screen + if (nStart >= nLastTop && nStart < nLastTop + 100) + nStart = nLastTop + 100; + if (nEnd >= nLastTop && nEnd < nLastTop + 100) + nEnd = nLastTop; + } + nLastTop = nTop; + pindexLastBest = pindexBest; + nLastRefreshed = nListViewUpdated; + + for (int nIndex = nStart; nIndex < min(nEnd, m_listCtrl->GetItemCount()); nIndex++) + { + uint256 hash((string)GetItemText(m_listCtrl, nIndex, 1)); + map<uint256, CWalletTx>::iterator mi = mapWallet.find(hash); + if (mi == mapWallet.end()) + { + printf("CMainFrame::RefreshStatusColumn() : tx not found in mapWallet\n"); + continue; + } + CWalletTx& wtx = (*mi).second; + if (wtx.IsCoinBase() || wtx.GetTxTime() != wtx.nTimeDisplayed) + { + if (!InsertTransaction(wtx, false, nIndex)) + m_listCtrl->DeleteItem(nIndex--); + } + else + m_listCtrl->SetItem(nIndex, 2, FormatTxStatus(wtx)); + } + } +} + +void CMainFrame::OnPaint(wxPaintEvent& event) +{ + event.Skip(); + if (fRefresh) + { + fRefresh = false; + Refresh(); + } +} + + +unsigned int nNeedRepaint = 0; +unsigned int nLastRepaint = 0; +int64 nLastRepaintTime = 0; +int64 nRepaintInterval = 500; + +void ThreadDelayedRepaint(void* parg) +{ + while (!fShutdown) + { + if (nLastRepaint != nNeedRepaint && GetTimeMillis() - nLastRepaintTime >= nRepaintInterval) + { + nLastRepaint = nNeedRepaint; + if (pframeMain) + { + printf("DelayedRepaint\n"); + wxPaintEvent event; + pframeMain->fRefresh = true; + pframeMain->GetEventHandler()->AddPendingEvent(event); + } + } + Sleep(nRepaintInterval); + } +} + +void MainFrameRepaint() +{ + // This is called by network code that shouldn't access pframeMain + // directly because it could still be running after the UI is closed. + if (pframeMain) + { + // Don't repaint too often + static int64 nLastRepaintRequest; + if (GetTimeMillis() - nLastRepaintRequest < 100) + { + nNeedRepaint++; + return; + } + nLastRepaintRequest = GetTimeMillis(); + + printf("MainFrameRepaint\n"); + wxPaintEvent event; + pframeMain->fRefresh = true; + pframeMain->GetEventHandler()->AddPendingEvent(event); + } +} + +void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) +{ + // Skip lets the listctrl do the paint, we're just hooking the message + event.Skip(); + + if (ptaskbaricon) + ptaskbaricon->UpdateTooltip(); + + // + // Slower stuff + // + static int nTransactionCount; + bool fPaintedBalance = false; + if (GetTimeMillis() - nLastRepaintTime >= nRepaintInterval) + { + nLastRepaint = nNeedRepaint; + nLastRepaintTime = GetTimeMillis(); + + // Update listctrl contents + if (!vWalletUpdated.empty()) + { + TRY_CRITICAL_BLOCK(cs_mapWallet) + { + string strTop; + if (m_listCtrl->GetItemCount()) + strTop = (string)m_listCtrl->GetItemText(0); + foreach(uint256 hash, vWalletUpdated) + { + map<uint256, CWalletTx>::iterator mi = mapWallet.find(hash); + if (mi != mapWallet.end()) + InsertTransaction((*mi).second, false); + } + vWalletUpdated.clear(); + if (m_listCtrl->GetItemCount() && strTop != (string)m_listCtrl->GetItemText(0)) + m_listCtrl->ScrollList(0, INT_MIN/2); + } + } + + // Balance total + TRY_CRITICAL_BLOCK(cs_mapWallet) + { + fPaintedBalance = true; + m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); + + // Count hidden and multi-line transactions + nTransactionCount = 0; + for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + CWalletTx& wtx = (*it).second; + nTransactionCount += wtx.nLinesDisplayed; + } + } + } + if (!vWalletUpdated.empty() || !fPaintedBalance) + nNeedRepaint++; + + // Update status column of visible items only + RefreshStatusColumn(); + + // Update status bar + string strGen = ""; + if (fGenerateBitcoins) + strGen = _(" Generating"); + if (fGenerateBitcoins && vNodes.empty()) + strGen = _("(not connected)"); + m_statusBar->SetStatusText(strGen, 1); + + string strStatus = strprintf(_(" %d connections %d blocks %d transactions"), vNodes.size(), nBestHeight + 1, nTransactionCount); + m_statusBar->SetStatusText(strStatus, 2); + + if (fDebug && GetTime() - nThreadSocketHandlerHeartbeat > 60) + m_statusBar->SetStatusText(" ERROR: ThreadSocketHandler has stopped", 0); + + // Update receiving address + string strDefaultAddress = PubKeyToAddress(vchDefaultKey); + if (m_textCtrlAddress->GetValue() != strDefaultAddress) + m_textCtrlAddress->SetValue(strDefaultAddress); +} + + +void UIThreadCall(boost::function0<void> fn) +{ + // Call this with a function object created with bind. + // bind needs all parameters to match the function's expected types + // and all default parameters specified. Some examples: + // UIThreadCall(bind(wxBell)); + // UIThreadCall(bind(wxMessageBox, wxT("Message"), wxT("Title"), wxOK, (wxWindow*)NULL, -1, -1)); + // UIThreadCall(bind(&CMainFrame::OnMenuHelpAbout, pframeMain, event)); + if (pframeMain) + { + wxCommandEvent event(wxEVT_UITHREADCALL); + event.SetClientData((void*)new boost::function0<void>(fn)); + pframeMain->GetEventHandler()->AddPendingEvent(event); + } +} + +void CMainFrame::OnUIThreadCall(wxCommandEvent& event) +{ + boost::function0<void>* pfn = (boost::function0<void>*)event.GetClientData(); + (*pfn)(); + delete pfn; +} + +void CMainFrame::OnMenuFileExit(wxCommandEvent& event) +{ + // File->Exit + Close(true); +} + +void CMainFrame::OnMenuOptionsGenerate(wxCommandEvent& event) +{ + // Options->Generate Coins + GenerateBitcoins(event.IsChecked()); +} + +void CMainFrame::OnUpdateUIOptionsGenerate(wxUpdateUIEvent& event) +{ + event.Check(fGenerateBitcoins); +} + +void CMainFrame::OnMenuOptionsChangeYourAddress(wxCommandEvent& event) +{ + // Options->Your Receiving Addresses + CAddressBookDialog dialog(this, "", CAddressBookDialog::RECEIVING, false); + if (!dialog.ShowModal()) + return; +} + +void CMainFrame::OnMenuOptionsOptions(wxCommandEvent& event) +{ + // Options->Options + COptionsDialog dialog(this); + dialog.ShowModal(); +} + +void CMainFrame::OnMenuHelpAbout(wxCommandEvent& event) +{ + // Help->About + CAboutDialog dialog(this); + dialog.ShowModal(); +} + +void CMainFrame::OnButtonSend(wxCommandEvent& event) +{ + // Toolbar: Send + CSendDialog dialog(this); + dialog.ShowModal(); +} + +void CMainFrame::OnButtonAddressBook(wxCommandEvent& event) +{ + // Toolbar: Address Book + CAddressBookDialog dialogAddr(this, "", CAddressBookDialog::SENDING, false); + if (dialogAddr.ShowModal() == 2) + { + // Send + CSendDialog dialogSend(this, dialogAddr.GetSelectedAddress()); + dialogSend.ShowModal(); + } +} + +void CMainFrame::OnSetFocusAddress(wxFocusEvent& event) +{ + // Automatically select-all when entering window + event.Skip(); + m_textCtrlAddress->SetSelection(-1, -1); + fOnSetFocusAddress = true; +} + +void CMainFrame::OnMouseEventsAddress(wxMouseEvent& event) +{ + event.Skip(); + if (fOnSetFocusAddress) + m_textCtrlAddress->SetSelection(-1, -1); + fOnSetFocusAddress = false; +} + +void CMainFrame::OnButtonNew(wxCommandEvent& event) +{ + // Ask name + CGetTextFromUserDialog dialog(this, + _("New Receiving Address"), + _("It's good policy to use a new address for each payment you receive.\n\nLabel"), + ""); + if (!dialog.ShowModal()) + return; + string strName = dialog.GetValue(); + + // Generate new key + string strAddress = PubKeyToAddress(GenerateNewKey()); + + // Save + SetAddressBookName(strAddress, strName); + SetDefaultReceivingAddress(strAddress); +} + +void CMainFrame::OnButtonCopy(wxCommandEvent& event) +{ + // Copy address box to clipboard + if (wxTheClipboard->Open()) + { + wxTheClipboard->SetData(new wxTextDataObject(m_textCtrlAddress->GetValue())); + wxTheClipboard->Close(); + } +} + +void CMainFrame::OnListItemActivated(wxListEvent& event) +{ + uint256 hash((string)GetItemText(m_listCtrl, event.GetIndex(), 1)); + CWalletTx wtx; + CRITICAL_BLOCK(cs_mapWallet) + { + map<uint256, CWalletTx>::iterator mi = mapWallet.find(hash); + if (mi == mapWallet.end()) + { + printf("CMainFrame::OnListItemActivated() : tx not found in mapWallet\n"); + return; + } + wtx = (*mi).second; + } + CTxDetailsDialog dialog(this, wtx); + dialog.ShowModal(); + //CTxDetailsDialog* pdialog = new CTxDetailsDialog(this, wtx); + //pdialog->Show(); +} + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CTxDetailsDialog +// + +CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetailsDialogBase(parent) +{ + CRITICAL_BLOCK(cs_mapAddressBook) + { + string strHTML; + strHTML.reserve(4000); + strHTML += "<html><font face='verdana, arial, helvetica, sans-serif'>"; + + int64 nTime = wtx.GetTxTime(); + int64 nCredit = wtx.GetCredit(); + int64 nDebit = wtx.GetDebit(); + int64 nNet = nCredit - nDebit; + + + + strHTML += _("<b>Status:</b> ") + FormatTxStatus(wtx); + int nRequests = wtx.GetRequestCount(); + if (nRequests != -1) + { + if (nRequests == 0) + strHTML += _(", has not been successfully broadcast yet"); + else if (nRequests == 1) + strHTML += strprintf(_(", broadcast through %d node"), nRequests); + else + strHTML += strprintf(_(", broadcast through %d nodes"), nRequests); + } + strHTML += "<br>"; + + strHTML += _("<b>Date:</b> ") + (nTime ? DateTimeStr(nTime) : "") + "<br>"; + + + // + // From + // + if (wtx.IsCoinBase()) + { + strHTML += _("<b>Source:</b> Generated<br>"); + } + else if (!wtx.mapValue["from"].empty()) + { + // Online transaction + if (!wtx.mapValue["from"].empty()) + strHTML += _("<b>From:</b> ") + HtmlEscape(wtx.mapValue["from"]) + "<br>"; + } + else + { + // Offline transaction + if (nNet > 0) + { + // Credit + foreach(const CTxOut& txout, wtx.vout) + { + if (txout.IsMine()) + { + vector<unsigned char> vchPubKey; + if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey)) + { + string strAddress = PubKeyToAddress(vchPubKey); + if (mapAddressBook.count(strAddress)) + { + strHTML += string() + _("<b>From:</b> ") + _("unknown") + "<br>"; + strHTML += _("<b>To:</b> "); + strHTML += HtmlEscape(strAddress); + if (!mapAddressBook[strAddress].empty()) + strHTML += _(" (yours, label: ") + mapAddressBook[strAddress] + ")"; + else + strHTML += _(" (yours)"); + strHTML += "<br>"; + } + } + break; + } + } + } + } + + + // + // To + // + string strAddress; + if (!wtx.mapValue["to"].empty()) + { + // Online transaction + strAddress = wtx.mapValue["to"]; + strHTML += _("<b>To:</b> "); + if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty()) + strHTML += mapAddressBook[strAddress] + " "; + strHTML += HtmlEscape(strAddress) + "<br>"; + } + + + // + // Amount + // + if (wtx.IsCoinBase() && nCredit == 0) + { + // + // Coinbase + // + int64 nUnmatured = 0; + foreach(const CTxOut& txout, wtx.vout) + nUnmatured += txout.GetCredit(); + strHTML += _("<b>Credit:</b> "); + if (wtx.IsInMainChain()) + strHTML += strprintf(_("(%s matures in %d more blocks)"), FormatMoney(nUnmatured).c_str(), wtx.GetBlocksToMaturity()); + else + strHTML += _("(not accepted)"); + strHTML += "<br>"; + } + else if (nNet > 0) + { + // + // Credit + // + strHTML += _("<b>Credit:</b> ") + FormatMoney(nNet) + "<br>"; + } + else + { + bool fAllFromMe = true; + foreach(const CTxIn& txin, wtx.vin) + fAllFromMe = fAllFromMe && txin.IsMine(); + + bool fAllToMe = true; + foreach(const CTxOut& txout, wtx.vout) + fAllToMe = fAllToMe && txout.IsMine(); + + if (fAllFromMe) + { + // + // Debit + // + foreach(const CTxOut& txout, wtx.vout) + { + if (txout.IsMine()) + continue; + + if (wtx.mapValue["to"].empty()) + { + // Offline transaction + uint160 hash160; + if (ExtractHash160(txout.scriptPubKey, hash160)) + { + string strAddress = Hash160ToAddress(hash160); + strHTML += _("<b>To:</b> "); + if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty()) + strHTML += mapAddressBook[strAddress] + " "; + strHTML += strAddress; + strHTML += "<br>"; + } + } + + strHTML += _("<b>Debit:</b> ") + FormatMoney(-txout.nValue) + "<br>"; + } + + if (fAllToMe) + { + // Payment to self + /// issue: can't tell which is the payment and which is the change anymore + //int64 nValue = wtx.vout[0].nValue; + //strHTML += _("<b>Debit:</b> ") + FormatMoney(-nValue) + "<br>"; + //strHTML += _("<b>Credit:</b> ") + FormatMoney(nValue) + "<br>"; + } + + int64 nTxFee = nDebit - wtx.GetValueOut(); + if (nTxFee > 0) + strHTML += _("<b>Transaction fee:</b> ") + FormatMoney(-nTxFee) + "<br>"; + } + else + { + // + // Mixed debit transaction + // + foreach(const CTxIn& txin, wtx.vin) + if (txin.IsMine()) + strHTML += _("<b>Debit:</b> ") + FormatMoney(-txin.GetDebit()) + "<br>"; + foreach(const CTxOut& txout, wtx.vout) + if (txout.IsMine()) + strHTML += _("<b>Credit:</b> ") + FormatMoney(txout.GetCredit()) + "<br>"; + } + } + + strHTML += _("<b>Net amount:</b> ") + FormatMoney(nNet, true) + "<br>"; + + + // + // Message + // + if (!wtx.mapValue["message"].empty()) + strHTML += string() + "<br><b>" + _("Message:") + "</b><br>" + HtmlEscape(wtx.mapValue["message"], true) + "<br>"; + + if (wtx.IsCoinBase()) + strHTML += string() + "<br>" + _("Generated coins must wait 120 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, it will change to \"not accepted\" and not be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.") + "<br>"; + + + // + // Debug view + // + if (fDebug) + { + strHTML += "<hr><br>debug print<br><br>"; + foreach(const CTxIn& txin, wtx.vin) + if (txin.IsMine()) + strHTML += "<b>Debit:</b> " + FormatMoney(-txin.GetDebit()) + "<br>"; + foreach(const CTxOut& txout, wtx.vout) + if (txout.IsMine()) + strHTML += "<b>Credit:</b> " + FormatMoney(txout.GetCredit()) + "<br>"; + + strHTML += "<b>Inputs:</b><br>"; + CRITICAL_BLOCK(cs_mapWallet) + { + foreach(const CTxIn& txin, wtx.vin) + { + COutPoint prevout = txin.prevout; + map<uint256, CWalletTx>::iterator mi = mapWallet.find(prevout.hash); + if (mi != mapWallet.end()) + { + const CWalletTx& prev = (*mi).second; + if (prevout.n < prev.vout.size()) + { + strHTML += HtmlEscape(prev.ToString(), true); + strHTML += " " + FormatTxStatus(prev) + ", "; + strHTML = strHTML + "IsMine=" + (prev.vout[prevout.n].IsMine() ? "true" : "false") + "<br>"; + } + } + } + } + + strHTML += "<br><hr><br><b>Transaction:</b><br>"; + strHTML += HtmlEscape(wtx.ToString(), true); + } + + + + strHTML += "</font></html>"; + string(strHTML.begin(), strHTML.end()).swap(strHTML); + m_htmlWin->SetPage(strHTML); + m_buttonOK->SetFocus(); + } +} + +void CTxDetailsDialog::OnButtonOK(wxCommandEvent& event) +{ + Close(); + //Destroy(); +} + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// COptionsDialog +// + +COptionsDialog::COptionsDialog(wxWindow* parent) : COptionsDialogBase(parent) +{ + // Set up list box of page choices + m_listBox->Append(_("Main")); + //m_listBox->Append(_("Test 2")); + m_listBox->SetSelection(0); + SelectPage(0); +#ifdef __WXGTK__ + m_checkBoxStartOnSystemStartup->SetLabel(_("&Start Bitcoin on window system startup")); +#endif +#ifdef __WXMAC_OSX__ + m_checkBoxStartOnSystemStartup->Enable(false); // not implemented yet +#endif + + // Init values + m_textCtrlTransactionFee->SetValue(FormatMoney(nTransactionFee)); + m_checkBoxLimitProcessors->SetValue(fLimitProcessors); + m_spinCtrlLimitProcessors->Enable(fLimitProcessors); + m_spinCtrlLimitProcessors->SetValue(nLimitProcessors); + int nProcessors = wxThread::GetCPUCount(); + if (nProcessors < 1) + nProcessors = 999; + m_spinCtrlLimitProcessors->SetRange(1, nProcessors); + m_checkBoxStartOnSystemStartup->SetValue(fTmpStartOnSystemStartup = GetStartOnSystemStartup()); + m_checkBoxMinimizeToTray->SetValue(fMinimizeToTray); + m_checkBoxMinimizeOnClose->SetValue(fMinimizeOnClose); + m_checkBoxUseProxy->SetValue(fUseProxy); + m_textCtrlProxyIP->Enable(fUseProxy); + m_textCtrlProxyPort->Enable(fUseProxy); + m_staticTextProxyIP->Enable(fUseProxy); + m_staticTextProxyPort->Enable(fUseProxy); + m_textCtrlProxyIP->SetValue(addrProxy.ToStringIP()); + m_textCtrlProxyPort->SetValue(addrProxy.ToStringPort()); + + m_buttonOK->SetFocus(); +} + +void COptionsDialog::SelectPage(int nPage) +{ + m_panelMain->Show(nPage == 0); + m_panelTest2->Show(nPage == 1); + + m_scrolledWindow->Layout(); + m_scrolledWindow->SetScrollbars(0, 0, 0, 0, 0, 0); +} + +void COptionsDialog::OnListBox(wxCommandEvent& event) +{ + SelectPage(event.GetSelection()); +} + +void COptionsDialog::OnKillFocusTransactionFee(wxFocusEvent& event) +{ + event.Skip(); + int64 nTmp = nTransactionFee; + ParseMoney(m_textCtrlTransactionFee->GetValue(), nTmp); + m_textCtrlTransactionFee->SetValue(FormatMoney(nTmp)); +} + +void COptionsDialog::OnCheckBoxLimitProcessors(wxCommandEvent& event) +{ + m_spinCtrlLimitProcessors->Enable(event.IsChecked()); +} + +void COptionsDialog::OnCheckBoxUseProxy(wxCommandEvent& event) +{ + m_textCtrlProxyIP->Enable(event.IsChecked()); + m_textCtrlProxyPort->Enable(event.IsChecked()); + m_staticTextProxyIP->Enable(event.IsChecked()); + m_staticTextProxyPort->Enable(event.IsChecked()); +} + +CAddress COptionsDialog::GetProxyAddr() +{ + // Be careful about byte order, addr.ip and addr.port are big endian + CAddress addr(m_textCtrlProxyIP->GetValue() + ":" + m_textCtrlProxyPort->GetValue()); + if (addr.ip == INADDR_NONE) + addr.ip = addrProxy.ip; + int nPort = atoi(m_textCtrlProxyPort->GetValue()); + addr.port = htons(nPort); + if (nPort <= 0 || nPort > USHRT_MAX) + addr.port = addrProxy.port; + return addr; +} + +void COptionsDialog::OnKillFocusProxy(wxFocusEvent& event) +{ + event.Skip(); + m_textCtrlProxyIP->SetValue(GetProxyAddr().ToStringIP()); + m_textCtrlProxyPort->SetValue(GetProxyAddr().ToStringPort()); +} + + +void COptionsDialog::OnButtonOK(wxCommandEvent& event) +{ + OnButtonApply(event); + Close(); +} + +void COptionsDialog::OnButtonCancel(wxCommandEvent& event) +{ + Close(); +} + +void COptionsDialog::OnButtonApply(wxCommandEvent& event) +{ + CWalletDB walletdb; + + int64 nPrevTransactionFee = nTransactionFee; + if (ParseMoney(m_textCtrlTransactionFee->GetValue(), nTransactionFee) && nTransactionFee != nPrevTransactionFee) + walletdb.WriteSetting("nTransactionFee", nTransactionFee); + + int nPrevMaxProc = (fLimitProcessors ? nLimitProcessors : INT_MAX); + if (fLimitProcessors != m_checkBoxLimitProcessors->GetValue()) + { + fLimitProcessors = m_checkBoxLimitProcessors->GetValue(); + walletdb.WriteSetting("fLimitProcessors", fLimitProcessors); + } + if (nLimitProcessors != m_spinCtrlLimitProcessors->GetValue()) + { + nLimitProcessors = m_spinCtrlLimitProcessors->GetValue(); + walletdb.WriteSetting("nLimitProcessors", nLimitProcessors); + } + if (fGenerateBitcoins && (fLimitProcessors ? nLimitProcessors : INT_MAX) > nPrevMaxProc) + GenerateBitcoins(fGenerateBitcoins); + + if (fTmpStartOnSystemStartup != m_checkBoxStartOnSystemStartup->GetValue()) + { + fTmpStartOnSystemStartup = m_checkBoxStartOnSystemStartup->GetValue(); + SetStartOnSystemStartup(fTmpStartOnSystemStartup); + } + + if (fMinimizeToTray != m_checkBoxMinimizeToTray->GetValue()) + { + fMinimizeToTray = m_checkBoxMinimizeToTray->GetValue(); + walletdb.WriteSetting("fMinimizeToTray", fMinimizeToTray); + ptaskbaricon->Show(fMinimizeToTray || fClosedToTray); + } + + if (fMinimizeOnClose != m_checkBoxMinimizeOnClose->GetValue()) + { + fMinimizeOnClose = m_checkBoxMinimizeOnClose->GetValue(); + walletdb.WriteSetting("fMinimizeOnClose", fMinimizeOnClose); + } + + fUseProxy = m_checkBoxUseProxy->GetValue(); + walletdb.WriteSetting("fUseProxy", fUseProxy); + + addrProxy = GetProxyAddr(); + walletdb.WriteSetting("addrProxy", addrProxy); +} + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CAboutDialog +// + +CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent) +{ + m_staticTextVersion->SetLabel(strprintf(_("version %d.%d.%d beta"), VERSION/10000, (VERSION/100)%100, VERSION%100)); + + // Change (c) into UTF-8 or ANSI copyright symbol + wxString str = m_staticTextMain->GetLabel(); +#if wxUSE_UNICODE + str.Replace("(c)", wxString::FromUTF8("\xC2\xA9")); +#else + str.Replace("(c)", "\xA9"); +#endif + m_staticTextMain->SetLabel(str); +#ifndef __WXMSW__ + // Resize on Linux to make the window fit the text. + // The text was wrapped manually rather than using the Wrap setting because + // the wrap would be too small on Linux and it can't be changed at this point. + wxFont fontTmp = m_staticTextMain->GetFont(); + if (fontTmp.GetPointSize() > 8); + fontTmp.SetPointSize(8); + m_staticTextMain->SetFont(fontTmp); + SetSize(GetSize().GetWidth() + 44, GetSize().GetHeight() + 10); +#endif +} + +void CAboutDialog::OnButtonOK(wxCommandEvent& event) +{ + Close(); +} + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CSendDialog +// + +CSendDialog::CSendDialog(wxWindow* parent, const wxString& strAddress) : CSendDialogBase(parent) +{ + // Init + m_textCtrlAddress->SetValue(strAddress); + m_choiceTransferType->SetSelection(0); + m_bitmapCheckMark->Show(false); + fEnabledPrev = true; + m_textCtrlAddress->SetFocus(); + //// todo: should add a display of your balance for convenience +#ifndef __WXMSW__ + wxFont fontTmp = m_staticTextInstructions->GetFont(); + if (fontTmp.GetPointSize() > 9); + fontTmp.SetPointSize(9); + m_staticTextInstructions->SetFont(fontTmp); + SetSize(725, 380); +#endif + + // Set Icon + wxIcon iconSend; + iconSend.CopyFromBitmap(wxBitmap(send16noshadow_xpm)); + SetIcon(iconSend); + + wxCommandEvent event; + OnTextAddress(event); + + // Fixup the tab order + m_buttonPaste->MoveAfterInTabOrder(m_buttonCancel); + m_buttonAddress->MoveAfterInTabOrder(m_buttonPaste); + this->Layout(); +} + +void CSendDialog::OnTextAddress(wxCommandEvent& event) +{ + // Check mark + event.Skip(); + bool fBitcoinAddress = IsValidBitcoinAddress(m_textCtrlAddress->GetValue()); + m_bitmapCheckMark->Show(fBitcoinAddress); + + // Grey out message if bitcoin address + bool fEnable = !fBitcoinAddress; + m_staticTextFrom->Enable(fEnable); + m_textCtrlFrom->Enable(fEnable); + m_staticTextMessage->Enable(fEnable); + m_textCtrlMessage->Enable(fEnable); + m_textCtrlMessage->SetBackgroundColour(wxSystemSettings::GetColour(fEnable ? wxSYS_COLOUR_WINDOW : wxSYS_COLOUR_BTNFACE)); + if (!fEnable && fEnabledPrev) + { + strFromSave = m_textCtrlFrom->GetValue(); + strMessageSave = m_textCtrlMessage->GetValue(); + m_textCtrlFrom->SetValue(_("Will appear as \"From: Unknown\"")); + m_textCtrlMessage->SetValue(_("Can't include a message when sending to a Bitcoin address")); + } + else if (fEnable && !fEnabledPrev) + { + m_textCtrlFrom->SetValue(strFromSave); + m_textCtrlMessage->SetValue(strMessageSave); + } + fEnabledPrev = fEnable; +} + +void CSendDialog::OnKillFocusAmount(wxFocusEvent& event) +{ + // Reformat the amount + event.Skip(); + if (m_textCtrlAmount->GetValue().Trim().empty()) + return; + int64 nTmp; + if (ParseMoney(m_textCtrlAmount->GetValue(), nTmp)) + m_textCtrlAmount->SetValue(FormatMoney(nTmp)); +} + +void CSendDialog::OnButtonAddressBook(wxCommandEvent& event) +{ + // Open address book + CAddressBookDialog dialog(this, m_textCtrlAddress->GetValue(), CAddressBookDialog::SENDING, true); + if (dialog.ShowModal()) + m_textCtrlAddress->SetValue(dialog.GetSelectedAddress()); +} + +void CSendDialog::OnButtonPaste(wxCommandEvent& event) +{ + // Copy clipboard to address box + if (wxTheClipboard->Open()) + { + if (wxTheClipboard->IsSupported(wxDF_TEXT)) + { + wxTextDataObject data; + wxTheClipboard->GetData(data); + m_textCtrlAddress->SetValue(data.GetText()); + } + wxTheClipboard->Close(); + } +} + +void CSendDialog::OnButtonSend(wxCommandEvent& event) +{ + CWalletTx wtx; + string strAddress = (string)m_textCtrlAddress->GetValue(); + + // Parse amount + int64 nValue = 0; + if (!ParseMoney(m_textCtrlAmount->GetValue(), nValue) || nValue <= 0) + { + wxMessageBox(_("Error in amount "), _("Send Coins")); + return; + } + if (nValue > GetBalance()) + { + wxMessageBox(_("Amount exceeds your balance "), _("Send Coins")); + return; + } + if (nValue + nTransactionFee > GetBalance()) + { + wxMessageBox(string(_("Total exceeds your balance when the ")) + FormatMoney(nTransactionFee) + _(" transaction fee is included "), _("Send Coins")); + return; + } + + // Parse bitcoin address + uint160 hash160; + bool fBitcoinAddress = AddressToHash160(strAddress, hash160); + + if (fBitcoinAddress) + { + // Send to bitcoin address + CScript scriptPubKey; + scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG; + + string strError = SendMoney(scriptPubKey, nValue, wtx, true); + if (strError == "") + wxMessageBox(_("Payment sent "), _("Sending...")); + else if (strError != "ABORTED") + wxMessageBox(strError + " ", _("Sending...")); + } + else + { + // Parse IP address + CAddress addr(strAddress); + if (!addr.IsValid()) + { + wxMessageBox(_("Invalid address "), _("Send Coins")); + return; + } + + // Message + wtx.mapValue["to"] = strAddress; + wtx.mapValue["from"] = m_textCtrlFrom->GetValue(); + wtx.mapValue["message"] = m_textCtrlMessage->GetValue(); + + // Send to IP address + CSendingDialog* pdialog = new CSendingDialog(this, addr, nValue, wtx); + if (!pdialog->ShowModal()) + return; + } + + CRITICAL_BLOCK(cs_mapAddressBook) + if (!mapAddressBook.count(strAddress)) + SetAddressBookName(strAddress, ""); + + EndModal(true); +} + +void CSendDialog::OnButtonCancel(wxCommandEvent& event) +{ + // Cancel + EndModal(false); +} + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CSendingDialog +// + +CSendingDialog::CSendingDialog(wxWindow* parent, const CAddress& addrIn, int64 nPriceIn, const CWalletTx& wtxIn) : CSendingDialogBase(NULL) // we have to give null so parent can't destroy us +{ + addr = addrIn; + nPrice = nPriceIn; + wtx = wtxIn; + start = wxDateTime::UNow(); + memset(pszStatus, 0, sizeof(pszStatus)); + fCanCancel = true; + fAbort = false; + fSuccess = false; + fUIDone = false; + fWorkDone = false; +#ifndef __WXMSW__ + SetSize(1.2 * GetSize().GetWidth(), 1.08 * GetSize().GetHeight()); +#endif + + SetTitle(strprintf(_("Sending %s to %s"), FormatMoney(nPrice).c_str(), wtx.mapValue["to"].c_str())); + m_textCtrlStatus->SetValue(""); + + CreateThread(SendingDialogStartTransfer, this); +} + +CSendingDialog::~CSendingDialog() +{ + printf("~CSendingDialog()\n"); +} + +void CSendingDialog::Close() +{ + // Last one out turn out the lights. + // fWorkDone signals that work side is done and UI thread should call destroy. + // fUIDone signals that UI window has closed and work thread should call destroy. + // This allows the window to disappear and end modality when cancelled + // without making the user wait for ConnectNode to return. The dialog object + // hangs around in the background until the work thread exits. + if (IsModal()) + EndModal(fSuccess); + else + Show(false); + if (fWorkDone) + Destroy(); + else + fUIDone = true; +} + +void CSendingDialog::OnClose(wxCloseEvent& event) +{ + if (!event.CanVeto() || fWorkDone || fAbort || !fCanCancel) + { + Close(); + } + else + { + event.Veto(); + wxCommandEvent cmdevent; + OnButtonCancel(cmdevent); + } +} + +void CSendingDialog::OnButtonOK(wxCommandEvent& event) +{ + if (fWorkDone) + Close(); +} + +void CSendingDialog::OnButtonCancel(wxCommandEvent& event) +{ + if (fCanCancel) + fAbort = true; +} + +void CSendingDialog::OnPaint(wxPaintEvent& event) +{ + event.Skip(); + if (strlen(pszStatus) > 130) + m_textCtrlStatus->SetValue(string("\n") + pszStatus); + else + m_textCtrlStatus->SetValue(string("\n\n") + pszStatus); + m_staticTextSending->SetFocus(); + if (!fCanCancel) + m_buttonCancel->Enable(false); + if (fWorkDone) + { + m_buttonOK->Enable(true); + m_buttonOK->SetFocus(); + m_buttonCancel->Enable(false); + } + if (fAbort && fCanCancel && IsShown()) + { + strcpy(pszStatus, _("CANCELLED")); + m_buttonOK->Enable(true); + m_buttonOK->SetFocus(); + m_buttonCancel->Enable(false); + m_buttonCancel->SetLabel(_("Cancelled")); + Close(); + wxMessageBox(_("Transfer cancelled "), _("Sending..."), wxOK, this); + } +} + + +// +// Everything from here on is not in the UI thread and must only communicate +// with the rest of the dialog through variables and calling repaint. +// + +void CSendingDialog::Repaint() +{ + Refresh(); + wxPaintEvent event; + GetEventHandler()->AddPendingEvent(event); +} + +bool CSendingDialog::Status() +{ + if (fUIDone) + { + Destroy(); + return false; + } + if (fAbort && fCanCancel) + { + memset(pszStatus, 0, 10); + strcpy(pszStatus, _("CANCELLED")); + Repaint(); + fWorkDone = true; + return false; + } + return true; +} + +bool CSendingDialog::Status(const string& str) +{ + if (!Status()) + return false; + + // This can be read by the UI thread at any time, + // so copy in a way that can be read cleanly at all times. + memset(pszStatus, 0, min(str.size()+1, sizeof(pszStatus))); + strlcpy(pszStatus, str.c_str(), sizeof(pszStatus)); + + Repaint(); + return true; +} + +bool CSendingDialog::Error(const string& str) +{ + fCanCancel = false; + fWorkDone = true; + Status(string(_("Error: ")) + str); + return false; +} + +void SendingDialogStartTransfer(void* parg) +{ + ((CSendingDialog*)parg)->StartTransfer(); +} + +void CSendingDialog::StartTransfer() +{ + // Make sure we have enough money + if (nPrice + nTransactionFee > GetBalance()) + { + Error(_("Insufficient funds")); + return; + } + + // We may have connected already for product details + if (!Status(_("Connecting..."))) + return; + CNode* pnode = ConnectNode(addr, 15 * 60); + if (!pnode) + { + Error(_("Unable to connect")); + return; + } + + // Send order to seller, with response going to OnReply2 via event handler + if (!Status(_("Requesting public key..."))) + return; + pnode->PushRequest("checkorder", wtx, SendingDialogOnReply2, this); +} + +void SendingDialogOnReply2(void* parg, CDataStream& vRecv) +{ + ((CSendingDialog*)parg)->OnReply2(vRecv); +} + +void CSendingDialog::OnReply2(CDataStream& vRecv) +{ + if (!Status(_("Received public key..."))) + return; + + CScript scriptPubKey; + int nRet; + try + { + vRecv >> nRet; + if (nRet > 0) + { + string strMessage; + vRecv >> strMessage; + Error(_("Transfer was not accepted")); + //// todo: enlarge the window and enable a hidden white box to put seller's message + return; + } + vRecv >> scriptPubKey; + } + catch (...) + { + //// what do we want to do about this? + Error(_("Invalid response received")); + return; + } + + // Pause to give the user a chance to cancel + while (wxDateTime::UNow() < start + wxTimeSpan(0, 0, 0, 2 * 1000)) + { + Sleep(200); + if (!Status()) + return; + } + + CRITICAL_BLOCK(cs_main) + { + // Pay + if (!Status(_("Creating transaction..."))) + return; + if (nPrice + nTransactionFee > GetBalance()) + { + Error(_("Insufficient funds")); + return; + } + CKey key; + int64 nFeeRequired; + if (!CreateTransaction(scriptPubKey, nPrice, wtx, key, nFeeRequired)) + { + if (nPrice + nFeeRequired > GetBalance()) + Error(strprintf(_("This is an oversized transaction that requires a transaction fee of %s"), FormatMoney(nFeeRequired).c_str())); + else + Error(_("Transaction creation failed")); + return; + } + + // Transaction fee + if (!ThreadSafeAskFee(nFeeRequired, _("Sending..."), this)) + { + Error(_("Transaction aborted")); + return; + } + + // Make sure we're still connected + CNode* pnode = ConnectNode(addr, 2 * 60 * 60); + if (!pnode) + { + Error(_("Lost connection, transaction cancelled")); + return; + } + + // Last chance to cancel + Sleep(50); + if (!Status()) + return; + fCanCancel = false; + if (fAbort) + { + fCanCancel = true; + if (!Status()) + return; + fCanCancel = false; + } + if (!Status(_("Sending payment..."))) + return; + + // Commit + if (!CommitTransaction(wtx, key)) + { + Error(_("The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.")); + return; + } + + // Send payment tx to seller, with response going to OnReply3 via event handler + CWalletTx wtxSend = wtx; + wtxSend.fFromMe = false; + pnode->PushRequest("submitorder", wtxSend, SendingDialogOnReply3, this); + + Status(_("Waiting for confirmation...")); + MainFrameRepaint(); + } +} + +void SendingDialogOnReply3(void* parg, CDataStream& vRecv) +{ + ((CSendingDialog*)parg)->OnReply3(vRecv); +} + +void CSendingDialog::OnReply3(CDataStream& vRecv) +{ + int nRet; + try + { + vRecv >> nRet; + if (nRet > 0) + { + Error(_("The payment was sent, but the recipient was unable to verify it.\n" + "The transaction is recorded and will credit to the recipient,\n" + "but the comment information will be blank.")); + return; + } + } + catch (...) + { + //// what do we want to do about this? + Error(_("Payment was sent, but an invalid response was received")); + return; + } + + fSuccess = true; + fWorkDone = true; + Status(_("Payment completed")); +} + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CAddressBookDialog +// + +CAddressBookDialog::CAddressBookDialog(wxWindow* parent, const wxString& strInitSelected, int nPageIn, bool fDuringSendIn) : CAddressBookDialogBase(parent) +{ + // Set initially selected page + wxNotebookEvent event; + event.SetSelection(nPageIn); + OnNotebookPageChanged(event); + m_notebook->ChangeSelection(nPageIn); + + fDuringSend = fDuringSendIn; + if (!fDuringSend) + m_buttonCancel->Show(false); + + // Set Icon + wxIcon iconAddressBook; + iconAddressBook.CopyFromBitmap(wxBitmap(addressbook16_xpm)); + SetIcon(iconAddressBook); + + // Init column headers + m_listCtrlSending->InsertColumn(0, _("Name"), wxLIST_FORMAT_LEFT, 200); + m_listCtrlSending->InsertColumn(1, _("Address"), wxLIST_FORMAT_LEFT, 350); + m_listCtrlSending->SetFocus(); + m_listCtrlReceiving->InsertColumn(0, _("Label"), wxLIST_FORMAT_LEFT, 200); + m_listCtrlReceiving->InsertColumn(1, _("Bitcoin Address"), wxLIST_FORMAT_LEFT, 350); + m_listCtrlReceiving->SetFocus(); + + // Fill listctrl with address book data + CRITICAL_BLOCK(cs_mapKeys) + CRITICAL_BLOCK(cs_mapAddressBook) + { + string strDefaultReceiving = (string)pframeMain->m_textCtrlAddress->GetValue(); + foreach(const PAIRTYPE(string, string)& item, mapAddressBook) + { + string strAddress = item.first; + string strName = item.second; + uint160 hash160; + bool fMine = (AddressToHash160(strAddress, hash160) && mapPubKeys.count(hash160)); + wxListCtrl* plistCtrl = fMine ? m_listCtrlReceiving : m_listCtrlSending; + int nIndex = InsertLine(plistCtrl, strName, strAddress); + if (strAddress == (fMine ? strDefaultReceiving : string(strInitSelected))) + plistCtrl->SetItemState(nIndex, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED); + } + } +} + +wxString CAddressBookDialog::GetSelectedAddress() +{ + int nIndex = GetSelection(m_listCtrl); + if (nIndex == -1) + return ""; + return GetItemText(m_listCtrl, nIndex, 1); +} + +wxString CAddressBookDialog::GetSelectedSendingAddress() +{ + int nIndex = GetSelection(m_listCtrlSending); + if (nIndex == -1) + return ""; + return GetItemText(m_listCtrlSending, nIndex, 1); +} + +wxString CAddressBookDialog::GetSelectedReceivingAddress() +{ + int nIndex = GetSelection(m_listCtrlReceiving); + if (nIndex == -1) + return ""; + return GetItemText(m_listCtrlReceiving, nIndex, 1); +} + +void CAddressBookDialog::OnNotebookPageChanged(wxNotebookEvent& event) +{ + event.Skip(); + nPage = event.GetSelection(); + if (nPage == SENDING) + m_listCtrl = m_listCtrlSending; + else if (nPage == RECEIVING) + m_listCtrl = m_listCtrlReceiving; + m_buttonDelete->Show(nPage == SENDING); + m_buttonCopy->Show(nPage == RECEIVING); + this->Layout(); + m_listCtrl->SetFocus(); +} + +void CAddressBookDialog::OnListEndLabelEdit(wxListEvent& event) +{ + // Update address book with edited name + event.Skip(); + if (event.IsEditCancelled()) + return; + string strAddress = (string)GetItemText(m_listCtrl, event.GetIndex(), 1); + SetAddressBookName(strAddress, string(event.GetText())); + pframeMain->RefreshListCtrl(); +} + +void CAddressBookDialog::OnListItemSelected(wxListEvent& event) +{ + event.Skip(); + if (nPage == RECEIVING) + SetDefaultReceivingAddress((string)GetSelectedReceivingAddress()); +} + +void CAddressBookDialog::OnListItemActivated(wxListEvent& event) +{ + event.Skip(); + if (fDuringSend) + { + // Doubleclick returns selection + EndModal(GetSelectedAddress() != "" ? 2 : 0); + return; + } + + // Doubleclick edits item + wxCommandEvent event2; + OnButtonEdit(event2); +} + +void CAddressBookDialog::OnButtonDelete(wxCommandEvent& event) +{ + if (nPage != SENDING) + return; + for (int nIndex = m_listCtrl->GetItemCount()-1; nIndex >= 0; nIndex--) + { + if (m_listCtrl->GetItemState(nIndex, wxLIST_STATE_SELECTED)) + { + string strAddress = (string)GetItemText(m_listCtrl, nIndex, 1); + CWalletDB().EraseName(strAddress); + m_listCtrl->DeleteItem(nIndex); + } + } + pframeMain->RefreshListCtrl(); +} + +void CAddressBookDialog::OnButtonCopy(wxCommandEvent& event) +{ + // Copy address box to clipboard + if (wxTheClipboard->Open()) + { + wxTheClipboard->SetData(new wxTextDataObject(GetSelectedAddress())); + wxTheClipboard->Close(); + } +} + +bool CAddressBookDialog::CheckIfMine(const string& strAddress, const string& strTitle) +{ + uint160 hash160; + bool fMine = (AddressToHash160(strAddress, hash160) && mapPubKeys.count(hash160)); + if (fMine) + wxMessageBox(_("This is one of your own addresses for receiving payments and cannot be entered in the address book. "), strTitle); + return fMine; +} + +void CAddressBookDialog::OnButtonEdit(wxCommandEvent& event) +{ + int nIndex = GetSelection(m_listCtrl); + if (nIndex == -1) + return; + string strName = (string)m_listCtrl->GetItemText(nIndex); + string strAddress = (string)GetItemText(m_listCtrl, nIndex, 1); + string strAddressOrg = strAddress; + + if (nPage == SENDING) + { + // Ask name and address + do + { + CGetTextFromUserDialog dialog(this, _("Edit Address"), _("Name"), strName, _("Address"), strAddress); + if (!dialog.ShowModal()) + return; + strName = dialog.GetValue1(); + strAddress = dialog.GetValue2(); + } + while (CheckIfMine(strAddress, _("Edit Address"))); + + } + else if (nPage == RECEIVING) + { + // Ask name + CGetTextFromUserDialog dialog(this, _("Edit Address Label"), _("Label"), strName); + if (!dialog.ShowModal()) + return; + strName = dialog.GetValue(); + } + + // Write back + if (strAddress != strAddressOrg) + CWalletDB().EraseName(strAddressOrg); + SetAddressBookName(strAddress, strName); + m_listCtrl->SetItem(nIndex, 1, strAddress); + m_listCtrl->SetItemText(nIndex, strName); + pframeMain->RefreshListCtrl(); +} + +void CAddressBookDialog::OnButtonNew(wxCommandEvent& event) +{ + string strName; + string strAddress; + + if (nPage == SENDING) + { + // Ask name and address + do + { + CGetTextFromUserDialog dialog(this, _("Add Address"), _("Name"), strName, _("Address"), strAddress); + if (!dialog.ShowModal()) + return; + strName = dialog.GetValue1(); + strAddress = dialog.GetValue2(); + } + while (CheckIfMine(strAddress, _("Add Address"))); + } + else if (nPage == RECEIVING) + { + // Ask name + CGetTextFromUserDialog dialog(this, + _("New Receiving Address"), + _("It's good policy to use a new address for each payment you receive.\n\nLabel"), + ""); + if (!dialog.ShowModal()) + return; + strName = dialog.GetValue(); + + // Generate new key + strAddress = PubKeyToAddress(GenerateNewKey()); + } + + // Add to list and select it + SetAddressBookName(strAddress, strName); + int nIndex = InsertLine(m_listCtrl, strName, strAddress); + SetSelection(m_listCtrl, nIndex); + m_listCtrl->SetFocus(); + if (nPage == SENDING) + pframeMain->RefreshListCtrl(); +} + +void CAddressBookDialog::OnButtonOK(wxCommandEvent& event) +{ + // OK + EndModal(GetSelectedAddress() != "" ? 1 : 0); +} + +void CAddressBookDialog::OnButtonCancel(wxCommandEvent& event) +{ + // Cancel + EndModal(0); +} + +void CAddressBookDialog::OnClose(wxCloseEvent& event) +{ + // Close + EndModal(0); +} + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CMyTaskBarIcon +// + +enum +{ + ID_TASKBAR_RESTORE = 10001, + ID_TASKBAR_OPTIONS, + ID_TASKBAR_GENERATE, + ID_TASKBAR_EXIT, +}; + +BEGIN_EVENT_TABLE(CMyTaskBarIcon, wxTaskBarIcon) + EVT_TASKBAR_LEFT_DCLICK(CMyTaskBarIcon::OnLeftButtonDClick) + EVT_MENU(ID_TASKBAR_RESTORE, CMyTaskBarIcon::OnMenuRestore) + EVT_MENU(ID_TASKBAR_OPTIONS, CMyTaskBarIcon::OnMenuOptions) + EVT_MENU(ID_TASKBAR_GENERATE, CMyTaskBarIcon::OnMenuGenerate) + EVT_UPDATE_UI(ID_TASKBAR_GENERATE, CMyTaskBarIcon::OnUpdateUIGenerate) + EVT_MENU(ID_TASKBAR_EXIT, CMyTaskBarIcon::OnMenuExit) +END_EVENT_TABLE() + +void CMyTaskBarIcon::Show(bool fShow) +{ + static char pszPrevTip[200]; + if (fShow) + { + string strTooltip = _("Bitcoin"); + if (fGenerateBitcoins) + strTooltip = _("Bitcoin - Generating"); + if (fGenerateBitcoins && vNodes.empty()) + strTooltip = _("Bitcoin - (not connected)"); + + // Optimization, only update when changed, using char array to be reentrant + if (strncmp(pszPrevTip, strTooltip.c_str(), sizeof(pszPrevTip)-1) != 0) + { + strlcpy(pszPrevTip, strTooltip.c_str(), sizeof(pszPrevTip)); +#ifdef __WXMSW__ + // somehow it'll choose the wrong size and scale it down if + // we use the main icon, so we hand it one with only 16x16 + SetIcon(wxICON(favicon), strTooltip); +#else + SetIcon(bitcoin80_xpm, strTooltip); +#endif + } + } + else + { + strlcpy(pszPrevTip, "", sizeof(pszPrevTip)); + RemoveIcon(); + } +} + +void CMyTaskBarIcon::Hide() +{ + Show(false); +} + +void CMyTaskBarIcon::OnLeftButtonDClick(wxTaskBarIconEvent& event) +{ + Restore(); +} + +void CMyTaskBarIcon::OnMenuRestore(wxCommandEvent& event) +{ + Restore(); +} + +void CMyTaskBarIcon::OnMenuOptions(wxCommandEvent& event) +{ + // Since it's modal, get the main window to do it + wxCommandEvent event2(wxEVT_COMMAND_MENU_SELECTED, wxID_PREFERENCES); + pframeMain->GetEventHandler()->AddPendingEvent(event2); +} + +void CMyTaskBarIcon::Restore() +{ + pframeMain->Show(); + wxIconizeEvent event(0, false); + pframeMain->GetEventHandler()->AddPendingEvent(event); + pframeMain->Iconize(false); + pframeMain->Raise(); +} + +void CMyTaskBarIcon::OnMenuGenerate(wxCommandEvent& event) +{ + GenerateBitcoins(event.IsChecked()); +} + +void CMyTaskBarIcon::OnUpdateUIGenerate(wxUpdateUIEvent& event) +{ + event.Check(fGenerateBitcoins); +} + +void CMyTaskBarIcon::OnMenuExit(wxCommandEvent& event) +{ + pframeMain->Close(true); +} + +void CMyTaskBarIcon::UpdateTooltip() +{ + if (IsIconInstalled()) + Show(true); +} + +wxMenu* CMyTaskBarIcon::CreatePopupMenu() +{ + wxMenu* pmenu = new wxMenu; + pmenu->Append(ID_TASKBAR_RESTORE, _("&Open Bitcoin")); + pmenu->Append(ID_TASKBAR_OPTIONS, _("O&ptions...")); + pmenu->AppendCheckItem(ID_TASKBAR_GENERATE, _("&Generate Coins"))->Check(fGenerateBitcoins); +#ifndef __WXMAC_OSX__ // Mac has built-in quit menu + pmenu->AppendSeparator(); + pmenu->Append(ID_TASKBAR_EXIT, _("E&xit")); +#endif + return pmenu; +} + + + + + + + + + + + + + +void CreateMainWindow() +{ + pframeMain = new CMainFrame(NULL); + if (mapArgs.count("-min")) + pframeMain->Iconize(true); + pframeMain->Show(true); // have to show first to get taskbar button to hide + if (fMinimizeToTray && pframeMain->IsIconized()) + fClosedToTray = true; + pframeMain->Show(!fClosedToTray); + ptaskbaricon->Show(fMinimizeToTray || fClosedToTray); + CreateThread(ThreadDelayedRepaint, NULL); +} @@ -1,379 +1,379 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
-
-DECLARE_EVENT_TYPE(wxEVT_UITHREADCALL, -1)
-
-#if wxUSE_GUI
-static const bool fGUI=true;
-#else
-static const bool fGUI=false;
-#endif
-
-inline int MyMessageBox(const wxString& message, const wxString& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1)
-{
-#if wxUSE_GUI
- if (!fDaemon)
- return wxMessageBox(message, caption, style, parent, x, y);
-#endif
- printf("wxMessageBox %s: %s\n", string(caption).c_str(), string(message).c_str());
- fprintf(stderr, "%s: %s\n", string(caption).c_str(), string(message).c_str());
- return wxOK;
-}
-#define wxMessageBox MyMessageBox
-
-
-
-
-void HandleCtrlA(wxKeyEvent& event);
-string FormatTxStatus(const CWalletTx& wtx);
-void UIThreadCall(boost::function0<void>);
-int ThreadSafeMessageBox(const string& message, const string& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1);
-bool ThreadSafeAskFee(int64 nFeeRequired, const string& strCaption, wxWindow* parent);
-void CalledSetStatusBar(const string& strText, int nField);
-void MainFrameRepaint();
-void CreateMainWindow();
-
-
-
-
-
-#if !wxUSE_GUI
-inline int ThreadSafeMessageBox(const string& message, const string& caption, int style, wxWindow* parent, int x, int y)
-{
- return MyMessageBox(message, caption, style, parent, x, y);
-}
-
-inline bool ThreadSafeAskFee(int64 nFeeRequired, const string& strCaption, wxWindow* parent)
-{
- return true;
-}
-
-inline void CalledSetStatusBar(const string& strText, int nField)
-{
-}
-
-inline void UIThreadCall(boost::function0<void> fn)
-{
-}
-
-inline void MainFrameRepaint()
-{
-}
-
-inline void CreateMainWindow()
-{
-}
-#else // wxUSE_GUI
-
-
-
-
-
-class CMainFrame : public CMainFrameBase
-{
-protected:
- // Event handlers
- void OnNotebookPageChanged(wxNotebookEvent& event);
- void OnClose(wxCloseEvent& event);
- void OnIconize(wxIconizeEvent& event);
- void OnMouseEvents(wxMouseEvent& event);
- void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); }
- void OnIdle(wxIdleEvent& event);
- void OnPaint(wxPaintEvent& event);
- void OnPaintListCtrl(wxPaintEvent& event);
- void OnMenuFileExit(wxCommandEvent& event);
- void OnMenuOptionsGenerate(wxCommandEvent& event);
- void OnUpdateUIOptionsGenerate(wxUpdateUIEvent& event);
- void OnMenuOptionsChangeYourAddress(wxCommandEvent& event);
- void OnMenuOptionsOptions(wxCommandEvent& event);
- void OnMenuHelpAbout(wxCommandEvent& event);
- void OnButtonSend(wxCommandEvent& event);
- void OnButtonAddressBook(wxCommandEvent& event);
- void OnSetFocusAddress(wxFocusEvent& event);
- void OnMouseEventsAddress(wxMouseEvent& event);
- void OnButtonNew(wxCommandEvent& event);
- void OnButtonCopy(wxCommandEvent& event);
- void OnListColBeginDrag(wxListEvent& event);
- void OnListItemActivated(wxListEvent& event);
- void OnListItemActivatedProductsSent(wxListEvent& event);
- void OnListItemActivatedOrdersSent(wxListEvent& event);
- void OnListItemActivatedOrdersReceived(wxListEvent& event);
-
-public:
- /** Constructor */
- CMainFrame(wxWindow* parent);
- ~CMainFrame();
-
- // Custom
- enum
- {
- ALL = 0,
- SENTRECEIVED = 1,
- SENT = 2,
- RECEIVED = 3,
- };
- int nPage;
- wxListCtrl* m_listCtrl;
- bool fShowGenerated;
- bool fShowSent;
- bool fShowReceived;
- bool fRefreshListCtrl;
- bool fRefreshListCtrlRunning;
- bool fOnSetFocusAddress;
- unsigned int nListViewUpdated;
- bool fRefresh;
-
- void OnUIThreadCall(wxCommandEvent& event);
- int GetSortIndex(const string& strSort);
- void InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxString& str1, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5);
- bool DeleteLine(uint256 hashKey);
- bool InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex=-1);
- void RefreshListCtrl();
- void RefreshStatusColumn();
-};
-
-
-
-
-class CTxDetailsDialog : public CTxDetailsDialogBase
-{
-protected:
- // Event handlers
- void OnButtonOK(wxCommandEvent& event);
-
-public:
- /** Constructor */
- CTxDetailsDialog(wxWindow* parent, CWalletTx wtx);
-
- // State
- CWalletTx wtx;
-};
-
-
-
-class COptionsDialog : public COptionsDialogBase
-{
-protected:
- // Event handlers
- void OnListBox(wxCommandEvent& event);
- void OnKillFocusTransactionFee(wxFocusEvent& event);
- void OnCheckBoxLimitProcessors(wxCommandEvent& event);
- void OnCheckBoxUseProxy(wxCommandEvent& event);
- void OnKillFocusProxy(wxFocusEvent& event);
-
- void OnButtonOK(wxCommandEvent& event);
- void OnButtonCancel(wxCommandEvent& event);
- void OnButtonApply(wxCommandEvent& event);
-
-public:
- /** Constructor */
- COptionsDialog(wxWindow* parent);
-
- // Custom
- bool fTmpStartOnSystemStartup;
- bool fTmpMinimizeOnClose;
- void SelectPage(int nPage);
- CAddress GetProxyAddr();
-};
-
-
-
-class CAboutDialog : public CAboutDialogBase
-{
-protected:
- // Event handlers
- void OnButtonOK(wxCommandEvent& event);
-
-public:
- /** Constructor */
- CAboutDialog(wxWindow* parent);
-};
-
-
-
-class CSendDialog : public CSendDialogBase
-{
-protected:
- // Event handlers
- void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); }
- void OnTextAddress(wxCommandEvent& event);
- void OnKillFocusAmount(wxFocusEvent& event);
- void OnButtonAddressBook(wxCommandEvent& event);
- void OnButtonPaste(wxCommandEvent& event);
- void OnButtonSend(wxCommandEvent& event);
- void OnButtonCancel(wxCommandEvent& event);
-
-public:
- /** Constructor */
- CSendDialog(wxWindow* parent, const wxString& strAddress="");
-
- // Custom
- bool fEnabledPrev;
- string strFromSave;
- string strMessageSave;
-};
-
-
-
-class CSendingDialog : public CSendingDialogBase
-{
-public:
- // Event handlers
- void OnClose(wxCloseEvent& event);
- void OnButtonOK(wxCommandEvent& event);
- void OnButtonCancel(wxCommandEvent& event);
- void OnPaint(wxPaintEvent& event);
-
-public:
- /** Constructor */
- CSendingDialog(wxWindow* parent, const CAddress& addrIn, int64 nPriceIn, const CWalletTx& wtxIn);
- ~CSendingDialog();
-
- // State
- CAddress addr;
- int64 nPrice;
- CWalletTx wtx;
- wxDateTime start;
- char pszStatus[10000];
- bool fCanCancel;
- bool fAbort;
- bool fSuccess;
- bool fUIDone;
- bool fWorkDone;
-
- void Close();
- void Repaint();
- bool Status();
- bool Status(const string& str);
- bool Error(const string& str);
- void StartTransfer();
- void OnReply2(CDataStream& vRecv);
- void OnReply3(CDataStream& vRecv);
-};
-
-void SendingDialogStartTransfer(void* parg);
-void SendingDialogOnReply2(void* parg, CDataStream& vRecv);
-void SendingDialogOnReply3(void* parg, CDataStream& vRecv);
-
-
-
-class CAddressBookDialog : public CAddressBookDialogBase
-{
-protected:
- // Event handlers
- void OnNotebookPageChanged(wxNotebookEvent& event);
- void OnListEndLabelEdit(wxListEvent& event);
- void OnListItemSelected(wxListEvent& event);
- void OnListItemActivated(wxListEvent& event);
- void OnButtonDelete(wxCommandEvent& event);
- void OnButtonCopy(wxCommandEvent& event);
- void OnButtonEdit(wxCommandEvent& event);
- void OnButtonNew(wxCommandEvent& event);
- void OnButtonOK(wxCommandEvent& event);
- void OnButtonCancel(wxCommandEvent& event);
- void OnClose(wxCloseEvent& event);
-
-public:
- /** Constructor */
- CAddressBookDialog(wxWindow* parent, const wxString& strInitSelected, int nPageIn, bool fDuringSendIn);
-
- // Custom
- enum
- {
- SENDING = 0,
- RECEIVING = 1,
- };
- int nPage;
- wxListCtrl* m_listCtrl;
- bool fDuringSend;
- wxString GetAddress();
- wxString GetSelectedAddress();
- wxString GetSelectedSendingAddress();
- wxString GetSelectedReceivingAddress();
- bool CheckIfMine(const string& strAddress, const string& strTitle);
-};
-
-
-
-class CGetTextFromUserDialog : public CGetTextFromUserDialogBase
-{
-protected:
- // Event handlers
- void OnButtonOK(wxCommandEvent& event) { EndModal(true); }
- void OnButtonCancel(wxCommandEvent& event) { EndModal(false); }
- void OnClose(wxCloseEvent& event) { EndModal(false); }
-
- void OnKeyDown(wxKeyEvent& event)
- {
- if (event.GetKeyCode() == '\r' || event.GetKeyCode() == WXK_NUMPAD_ENTER)
- EndModal(true);
- else
- HandleCtrlA(event);
- }
-
-public:
- /** Constructor */
- CGetTextFromUserDialog(wxWindow* parent,
- const string& strCaption,
- const string& strMessage1,
- const string& strValue1="",
- const string& strMessage2="",
- const string& strValue2="") : CGetTextFromUserDialogBase(parent, wxID_ANY, strCaption)
- {
- int x = GetSize().GetWidth();
- int y = GetSize().GetHeight();
- m_staticTextMessage1->SetLabel(strMessage1);
- m_textCtrl1->SetValue(strValue1);
- y += wxString(strMessage1).Freq('\n') * 14;
- if (!strMessage2.empty())
- {
- m_staticTextMessage2->Show(true);
- m_staticTextMessage2->SetLabel(strMessage2);
- m_textCtrl2->Show(true);
- m_textCtrl2->SetValue(strValue2);
- y += 46 + wxString(strMessage2).Freq('\n') * 14;
- }
- if (!fWindows)
- {
- x *= 1.14;
- y *= 1.14;
- }
- SetSize(x, y);
- }
-
- // Custom
- string GetValue() { return (string)m_textCtrl1->GetValue(); }
- string GetValue1() { return (string)m_textCtrl1->GetValue(); }
- string GetValue2() { return (string)m_textCtrl2->GetValue(); }
-};
-
-
-
-class CMyTaskBarIcon : public wxTaskBarIcon
-{
-protected:
- // Event handlers
- void OnLeftButtonDClick(wxTaskBarIconEvent& event);
- void OnMenuRestore(wxCommandEvent& event);
- void OnMenuOptions(wxCommandEvent& event);
- void OnUpdateUIGenerate(wxUpdateUIEvent& event);
- void OnMenuGenerate(wxCommandEvent& event);
- void OnMenuExit(wxCommandEvent& event);
-
-public:
- CMyTaskBarIcon() : wxTaskBarIcon()
- {
- Show(true);
- }
-
- void Show(bool fShow=true);
- void Hide();
- void Restore();
- void UpdateTooltip();
- virtual wxMenu* CreatePopupMenu();
-
-DECLARE_EVENT_TABLE()
-};
-
-#endif // wxUSE_GUI
+// Copyright (c) 2009-2010 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +DECLARE_EVENT_TYPE(wxEVT_UITHREADCALL, -1) + +#if wxUSE_GUI +static const bool fGUI=true; +#else +static const bool fGUI=false; +#endif + +inline int MyMessageBox(const wxString& message, const wxString& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1) +{ +#if wxUSE_GUI + if (!fDaemon) + return wxMessageBox(message, caption, style, parent, x, y); +#endif + printf("wxMessageBox %s: %s\n", string(caption).c_str(), string(message).c_str()); + fprintf(stderr, "%s: %s\n", string(caption).c_str(), string(message).c_str()); + return wxOK; +} +#define wxMessageBox MyMessageBox + + + + +void HandleCtrlA(wxKeyEvent& event); +string FormatTxStatus(const CWalletTx& wtx); +void UIThreadCall(boost::function0<void>); +int ThreadSafeMessageBox(const string& message, const string& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1); +bool ThreadSafeAskFee(int64 nFeeRequired, const string& strCaption, wxWindow* parent); +void CalledSetStatusBar(const string& strText, int nField); +void MainFrameRepaint(); +void CreateMainWindow(); + + + + + +#if !wxUSE_GUI +inline int ThreadSafeMessageBox(const string& message, const string& caption, int style, wxWindow* parent, int x, int y) +{ + return MyMessageBox(message, caption, style, parent, x, y); +} + +inline bool ThreadSafeAskFee(int64 nFeeRequired, const string& strCaption, wxWindow* parent) +{ + return true; +} + +inline void CalledSetStatusBar(const string& strText, int nField) +{ +} + +inline void UIThreadCall(boost::function0<void> fn) +{ +} + +inline void MainFrameRepaint() +{ +} + +inline void CreateMainWindow() +{ +} +#else // wxUSE_GUI + + + + + +class CMainFrame : public CMainFrameBase +{ +protected: + // Event handlers + void OnNotebookPageChanged(wxNotebookEvent& event); + void OnClose(wxCloseEvent& event); + void OnIconize(wxIconizeEvent& event); + void OnMouseEvents(wxMouseEvent& event); + void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); } + void OnIdle(wxIdleEvent& event); + void OnPaint(wxPaintEvent& event); + void OnPaintListCtrl(wxPaintEvent& event); + void OnMenuFileExit(wxCommandEvent& event); + void OnMenuOptionsGenerate(wxCommandEvent& event); + void OnUpdateUIOptionsGenerate(wxUpdateUIEvent& event); + void OnMenuOptionsChangeYourAddress(wxCommandEvent& event); + void OnMenuOptionsOptions(wxCommandEvent& event); + void OnMenuHelpAbout(wxCommandEvent& event); + void OnButtonSend(wxCommandEvent& event); + void OnButtonAddressBook(wxCommandEvent& event); + void OnSetFocusAddress(wxFocusEvent& event); + void OnMouseEventsAddress(wxMouseEvent& event); + void OnButtonNew(wxCommandEvent& event); + void OnButtonCopy(wxCommandEvent& event); + void OnListColBeginDrag(wxListEvent& event); + void OnListItemActivated(wxListEvent& event); + void OnListItemActivatedProductsSent(wxListEvent& event); + void OnListItemActivatedOrdersSent(wxListEvent& event); + void OnListItemActivatedOrdersReceived(wxListEvent& event); + +public: + /** Constructor */ + CMainFrame(wxWindow* parent); + ~CMainFrame(); + + // Custom + enum + { + ALL = 0, + SENTRECEIVED = 1, + SENT = 2, + RECEIVED = 3, + }; + int nPage; + wxListCtrl* m_listCtrl; + bool fShowGenerated; + bool fShowSent; + bool fShowReceived; + bool fRefreshListCtrl; + bool fRefreshListCtrlRunning; + bool fOnSetFocusAddress; + unsigned int nListViewUpdated; + bool fRefresh; + + void OnUIThreadCall(wxCommandEvent& event); + int GetSortIndex(const string& strSort); + void InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxString& str1, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5); + bool DeleteLine(uint256 hashKey); + bool InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex=-1); + void RefreshListCtrl(); + void RefreshStatusColumn(); +}; + + + + +class CTxDetailsDialog : public CTxDetailsDialogBase +{ +protected: + // Event handlers + void OnButtonOK(wxCommandEvent& event); + +public: + /** Constructor */ + CTxDetailsDialog(wxWindow* parent, CWalletTx wtx); + + // State + CWalletTx wtx; +}; + + + +class COptionsDialog : public COptionsDialogBase +{ +protected: + // Event handlers + void OnListBox(wxCommandEvent& event); + void OnKillFocusTransactionFee(wxFocusEvent& event); + void OnCheckBoxLimitProcessors(wxCommandEvent& event); + void OnCheckBoxUseProxy(wxCommandEvent& event); + void OnKillFocusProxy(wxFocusEvent& event); + + void OnButtonOK(wxCommandEvent& event); + void OnButtonCancel(wxCommandEvent& event); + void OnButtonApply(wxCommandEvent& event); + +public: + /** Constructor */ + COptionsDialog(wxWindow* parent); + + // Custom + bool fTmpStartOnSystemStartup; + bool fTmpMinimizeOnClose; + void SelectPage(int nPage); + CAddress GetProxyAddr(); +}; + + + +class CAboutDialog : public CAboutDialogBase +{ +protected: + // Event handlers + void OnButtonOK(wxCommandEvent& event); + +public: + /** Constructor */ + CAboutDialog(wxWindow* parent); +}; + + + +class CSendDialog : public CSendDialogBase +{ +protected: + // Event handlers + void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); } + void OnTextAddress(wxCommandEvent& event); + void OnKillFocusAmount(wxFocusEvent& event); + void OnButtonAddressBook(wxCommandEvent& event); + void OnButtonPaste(wxCommandEvent& event); + void OnButtonSend(wxCommandEvent& event); + void OnButtonCancel(wxCommandEvent& event); + +public: + /** Constructor */ + CSendDialog(wxWindow* parent, const wxString& strAddress=""); + + // Custom + bool fEnabledPrev; + string strFromSave; + string strMessageSave; +}; + + + +class CSendingDialog : public CSendingDialogBase +{ +public: + // Event handlers + void OnClose(wxCloseEvent& event); + void OnButtonOK(wxCommandEvent& event); + void OnButtonCancel(wxCommandEvent& event); + void OnPaint(wxPaintEvent& event); + +public: + /** Constructor */ + CSendingDialog(wxWindow* parent, const CAddress& addrIn, int64 nPriceIn, const CWalletTx& wtxIn); + ~CSendingDialog(); + + // State + CAddress addr; + int64 nPrice; + CWalletTx wtx; + wxDateTime start; + char pszStatus[10000]; + bool fCanCancel; + bool fAbort; + bool fSuccess; + bool fUIDone; + bool fWorkDone; + + void Close(); + void Repaint(); + bool Status(); + bool Status(const string& str); + bool Error(const string& str); + void StartTransfer(); + void OnReply2(CDataStream& vRecv); + void OnReply3(CDataStream& vRecv); +}; + +void SendingDialogStartTransfer(void* parg); +void SendingDialogOnReply2(void* parg, CDataStream& vRecv); +void SendingDialogOnReply3(void* parg, CDataStream& vRecv); + + + +class CAddressBookDialog : public CAddressBookDialogBase +{ +protected: + // Event handlers + void OnNotebookPageChanged(wxNotebookEvent& event); + void OnListEndLabelEdit(wxListEvent& event); + void OnListItemSelected(wxListEvent& event); + void OnListItemActivated(wxListEvent& event); + void OnButtonDelete(wxCommandEvent& event); + void OnButtonCopy(wxCommandEvent& event); + void OnButtonEdit(wxCommandEvent& event); + void OnButtonNew(wxCommandEvent& event); + void OnButtonOK(wxCommandEvent& event); + void OnButtonCancel(wxCommandEvent& event); + void OnClose(wxCloseEvent& event); + +public: + /** Constructor */ + CAddressBookDialog(wxWindow* parent, const wxString& strInitSelected, int nPageIn, bool fDuringSendIn); + + // Custom + enum + { + SENDING = 0, + RECEIVING = 1, + }; + int nPage; + wxListCtrl* m_listCtrl; + bool fDuringSend; + wxString GetAddress(); + wxString GetSelectedAddress(); + wxString GetSelectedSendingAddress(); + wxString GetSelectedReceivingAddress(); + bool CheckIfMine(const string& strAddress, const string& strTitle); +}; + + + +class CGetTextFromUserDialog : public CGetTextFromUserDialogBase +{ +protected: + // Event handlers + void OnButtonOK(wxCommandEvent& event) { EndModal(true); } + void OnButtonCancel(wxCommandEvent& event) { EndModal(false); } + void OnClose(wxCloseEvent& event) { EndModal(false); } + + void OnKeyDown(wxKeyEvent& event) + { + if (event.GetKeyCode() == '\r' || event.GetKeyCode() == WXK_NUMPAD_ENTER) + EndModal(true); + else + HandleCtrlA(event); + } + +public: + /** Constructor */ + CGetTextFromUserDialog(wxWindow* parent, + const string& strCaption, + const string& strMessage1, + const string& strValue1="", + const string& strMessage2="", + const string& strValue2="") : CGetTextFromUserDialogBase(parent, wxID_ANY, strCaption) + { + int x = GetSize().GetWidth(); + int y = GetSize().GetHeight(); + m_staticTextMessage1->SetLabel(strMessage1); + m_textCtrl1->SetValue(strValue1); + y += wxString(strMessage1).Freq('\n') * 14; + if (!strMessage2.empty()) + { + m_staticTextMessage2->Show(true); + m_staticTextMessage2->SetLabel(strMessage2); + m_textCtrl2->Show(true); + m_textCtrl2->SetValue(strValue2); + y += 46 + wxString(strMessage2).Freq('\n') * 14; + } + if (!fWindows) + { + x *= 1.14; + y *= 1.14; + } + SetSize(x, y); + } + + // Custom + string GetValue() { return (string)m_textCtrl1->GetValue(); } + string GetValue1() { return (string)m_textCtrl1->GetValue(); } + string GetValue2() { return (string)m_textCtrl2->GetValue(); } +}; + + + +class CMyTaskBarIcon : public wxTaskBarIcon +{ +protected: + // Event handlers + void OnLeftButtonDClick(wxTaskBarIconEvent& event); + void OnMenuRestore(wxCommandEvent& event); + void OnMenuOptions(wxCommandEvent& event); + void OnUpdateUIGenerate(wxUpdateUIEvent& event); + void OnMenuGenerate(wxCommandEvent& event); + void OnMenuExit(wxCommandEvent& event); + +public: + CMyTaskBarIcon() : wxTaskBarIcon() + { + Show(true); + } + + void Show(bool fShow=true); + void Hide(); + void Restore(); + void UpdateTooltip(); + virtual wxMenu* CreatePopupMenu(); + +DECLARE_EVENT_TABLE() +}; + +#endif // wxUSE_GUI @@ -1,15 +1,15 @@ -bitcoin ICON "rc/bitcoin.ico"
-
-#include "wx/msw/wx.rc"
-
-check ICON "rc/check.ico"
-send16 BITMAP "rc/send16.bmp"
-send16mask BITMAP "rc/send16mask.bmp"
-send16masknoshadow BITMAP "rc/send16masknoshadow.bmp"
-send20 BITMAP "rc/send20.bmp"
-send20mask BITMAP "rc/send20mask.bmp"
-addressbook16 BITMAP "rc/addressbook16.bmp"
-addressbook16mask BITMAP "rc/addressbook16mask.bmp"
-addressbook20 BITMAP "rc/addressbook20.bmp"
-addressbook20mask BITMAP "rc/addressbook20mask.bmp"
-favicon ICON "rc/favicon.ico"
+bitcoin ICON "rc/bitcoin.ico" + +#include "wx/msw/wx.rc" + +check ICON "rc/check.ico" +send16 BITMAP "rc/send16.bmp" +send16mask BITMAP "rc/send16mask.bmp" +send16masknoshadow BITMAP "rc/send16masknoshadow.bmp" +send20 BITMAP "rc/send20.bmp" +send20mask BITMAP "rc/send20mask.bmp" +addressbook16 BITMAP "rc/addressbook16.bmp" +addressbook16mask BITMAP "rc/addressbook16mask.bmp" +addressbook20 BITMAP "rc/addressbook20.bmp" +addressbook20mask BITMAP "rc/addressbook20mask.bmp" +favicon ICON "rc/favicon.ico" diff --git a/uibase.cpp b/uibase.cpp index 4209377d57..9ce5093e80 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -1,1073 +1,1073 @@ -///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version Apr 16 2008)
-// http://www.wxformbuilder.org/
-//
-// PLEASE DO "NOT" EDIT THIS FILE!
-///////////////////////////////////////////////////////////////////////////
-
-#include "uibase.h"
-
-#include "xpm/about.xpm"
-#include "xpm/addressbook20.xpm"
-#include "xpm/check.xpm"
-#include "xpm/send20.xpm"
-
-///////////////////////////////////////////////////////////////////////////
-
-CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame( parent, id, title, pos, size, style )
-{
- this->SetSizeHints( wxDefaultSize, wxDefaultSize );
- this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) );
-
- m_menubar = new wxMenuBar( 0 );
- m_menuFile = new wxMenu();
- wxMenuItem* m_menuFileExit;
- m_menuFileExit = new wxMenuItem( m_menuFile, wxID_EXIT, wxString( _("E&xit") ) , wxEmptyString, wxITEM_NORMAL );
- m_menuFile->Append( m_menuFileExit );
-
- m_menubar->Append( m_menuFile, _("&File") );
-
- m_menuOptions = new wxMenu();
- wxMenuItem* m_menuOptionsGenerateBitcoins;
- m_menuOptionsGenerateBitcoins = new wxMenuItem( m_menuOptions, wxID_OPTIONSGENERATEBITCOINS, wxString( _("&Generate Coins") ) , wxEmptyString, wxITEM_CHECK );
- m_menuOptions->Append( m_menuOptionsGenerateBitcoins );
-
- wxMenuItem* m_menuOptionsChangeYourAddress;
- m_menuOptionsChangeYourAddress = new wxMenuItem( m_menuOptions, wxID_ANY, wxString( _("&Your Receiving Addresses...") ) , wxEmptyString, wxITEM_NORMAL );
- m_menuOptions->Append( m_menuOptionsChangeYourAddress );
-
- wxMenuItem* m_menuOptionsOptions;
- m_menuOptionsOptions = new wxMenuItem( m_menuOptions, wxID_PREFERENCES, wxString( _("&Options...") ) , wxEmptyString, wxITEM_NORMAL );
- m_menuOptions->Append( m_menuOptionsOptions );
-
- m_menubar->Append( m_menuOptions, _("&Settings") );
-
- m_menuHelp = new wxMenu();
- wxMenuItem* m_menuHelpAbout;
- m_menuHelpAbout = new wxMenuItem( m_menuHelp, wxID_ABOUT, wxString( _("&About...") ) , wxEmptyString, wxITEM_NORMAL );
- m_menuHelp->Append( m_menuHelpAbout );
-
- m_menubar->Append( m_menuHelp, _("&Help") );
-
- this->SetMenuBar( m_menubar );
-
- m_toolBar = this->CreateToolBar( wxTB_FLAT|wxTB_HORZ_TEXT, wxID_ANY );
- m_toolBar->SetToolBitmapSize( wxSize( 20,20 ) );
- m_toolBar->SetToolSeparation( 1 );
- m_toolBar->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxEmptyString ) );
-
- m_toolBar->AddTool( wxID_BUTTONSEND, _("Send Coins"), wxBitmap( send20_xpm ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString );
- m_toolBar->AddTool( wxID_BUTTONRECEIVE, _("Address Book"), wxBitmap( addressbook20_xpm ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString );
- m_toolBar->Realize();
-
- m_statusBar = this->CreateStatusBar( 1, wxST_SIZEGRIP, wxID_ANY );
- m_statusBar->SetBackgroundColour( wxColour( 240, 240, 240 ) );
-
- wxBoxSizer* bSizer2;
- bSizer2 = new wxBoxSizer( wxVERTICAL );
-
-
- bSizer2->Add( 0, 2, 0, wxEXPAND, 5 );
-
- wxBoxSizer* bSizer85;
- bSizer85 = new wxBoxSizer( wxHORIZONTAL );
-
- m_staticText32 = new wxStaticText( this, wxID_ANY, _("Your Bitcoin Address:"), wxDefaultPosition, wxDefaultSize, 0 );
- m_staticText32->Wrap( -1 );
- bSizer85->Add( m_staticText32, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
-
- m_textCtrlAddress = new wxTextCtrl( this, wxID_TEXTCTRLADDRESS, wxEmptyString, wxDefaultPosition, wxSize( 340,-1 ), wxTE_READONLY );
- bSizer85->Add( m_textCtrlAddress, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
-
- m_buttonNew = new wxButton( this, wxID_BUTTONNEW, _(" &New... "), wxDefaultPosition, wxSize( -1,-1 ), wxBU_EXACTFIT );
- bSizer85->Add( m_buttonNew, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 );
-
- m_buttonCopy = new wxButton( this, wxID_BUTTONCOPY, _(" &Copy to Clipboard "), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT );
- bSizer85->Add( m_buttonCopy, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
-
-
- bSizer85->Add( 0, 0, 0, wxEXPAND, 5 );
-
- bSizer2->Add( bSizer85, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 );
-
- wxBoxSizer* bSizer3;
- bSizer3 = new wxBoxSizer( wxHORIZONTAL );
-
- wxBoxSizer* bSizer66;
- bSizer66 = new wxBoxSizer( wxHORIZONTAL );
-
- m_staticText41 = new wxStaticText( this, wxID_ANY, _("Balance:"), wxDefaultPosition, wxSize( -1,15 ), 0 );
- m_staticText41->Wrap( -1 );
- bSizer66->Add( m_staticText41, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
-
- m_staticTextBalance = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 120,15 ), wxALIGN_RIGHT|wxST_NO_AUTORESIZE );
- m_staticTextBalance->Wrap( -1 );
- m_staticTextBalance->SetFont( wxFont( 8, 70, 90, 90, false, wxEmptyString ) );
- m_staticTextBalance->SetBackgroundColour( wxColour( 255, 255, 255 ) );
-
- bSizer66->Add( m_staticTextBalance, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
-
- bSizer3->Add( bSizer66, 1, wxEXPAND|wxALL, 5 );
-
-
- bSizer3->Add( 0, 0, 0, wxEXPAND, 5 );
-
- wxString m_choiceFilterChoices[] = { _(" All"), _(" Sent"), _(" Received"), _(" In Progress") };
- int m_choiceFilterNChoices = sizeof( m_choiceFilterChoices ) / sizeof( wxString );
- m_choiceFilter = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxSize( 110,-1 ), m_choiceFilterNChoices, m_choiceFilterChoices, 0 );
- m_choiceFilter->SetSelection( 0 );
- m_choiceFilter->Hide();
-
- bSizer3->Add( m_choiceFilter, 0, wxALIGN_BOTTOM|wxTOP|wxRIGHT|wxLEFT, 5 );
-
- bSizer2->Add( bSizer3, 0, wxEXPAND, 5 );
-
- m_notebook = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
- m_panel9 = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
- wxBoxSizer* bSizer11;
- bSizer11 = new wxBoxSizer( wxVERTICAL );
-
- m_listCtrlAll = new wxListCtrl( m_panel9, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING );
- bSizer11->Add( m_listCtrlAll, 1, wxEXPAND, 5 );
-
- m_panel9->SetSizer( bSizer11 );
- m_panel9->Layout();
- bSizer11->Fit( m_panel9 );
- m_notebook->AddPage( m_panel9, _("All Transactions"), true );
- m_panel91 = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
- wxBoxSizer* bSizer111;
- bSizer111 = new wxBoxSizer( wxVERTICAL );
-
- m_listCtrlSentReceived = new wxListCtrl( m_panel91, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING );
- bSizer111->Add( m_listCtrlSentReceived, 1, wxEXPAND, 5 );
-
- m_panel91->SetSizer( bSizer111 );
- m_panel91->Layout();
- bSizer111->Fit( m_panel91 );
- m_notebook->AddPage( m_panel91, _("Sent/Received"), false );
- m_panel92 = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
- wxBoxSizer* bSizer112;
- bSizer112 = new wxBoxSizer( wxVERTICAL );
-
- m_listCtrlSent = new wxListCtrl( m_panel92, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING );
- bSizer112->Add( m_listCtrlSent, 1, wxEXPAND, 5 );
-
- m_panel92->SetSizer( bSizer112 );
- m_panel92->Layout();
- bSizer112->Fit( m_panel92 );
- m_notebook->AddPage( m_panel92, _("Sent"), false );
- m_panel93 = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
- wxBoxSizer* bSizer113;
- bSizer113 = new wxBoxSizer( wxVERTICAL );
-
- m_listCtrlReceived = new wxListCtrl( m_panel93, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING );
- bSizer113->Add( m_listCtrlReceived, 1, wxEXPAND, 5 );
-
- m_panel93->SetSizer( bSizer113 );
- m_panel93->Layout();
- bSizer113->Fit( m_panel93 );
- m_notebook->AddPage( m_panel93, _("Received"), false );
-
- bSizer2->Add( m_notebook, 1, wxEXPAND, 5 );
-
- this->SetSizer( bSizer2 );
- this->Layout();
-
- // Connect Events
- this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CMainFrameBase::OnClose ) );
- this->Connect( wxEVT_ICONIZE, wxIconizeEventHandler( CMainFrameBase::OnIconize ) );
- this->Connect( wxEVT_IDLE, wxIdleEventHandler( CMainFrameBase::OnIdle ) );
- this->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) );
- this->Connect( wxEVT_LEFT_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) );
- this->Connect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) );
- this->Connect( wxEVT_MIDDLE_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) );
- this->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) );
- this->Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) );
- this->Connect( wxEVT_MOTION, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) );
- this->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) );
- this->Connect( wxEVT_MIDDLE_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) );
- this->Connect( wxEVT_RIGHT_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) );
- this->Connect( wxEVT_LEAVE_WINDOW, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) );
- this->Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) );
- this->Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) );
- this->Connect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaint ) );
- this->Connect( m_menuFileExit->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuFileExit ) );
- this->Connect( m_menuOptionsGenerateBitcoins->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsGenerate ) );
- this->Connect( m_menuOptionsGenerateBitcoins->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateUIOptionsGenerate ) );
- this->Connect( m_menuOptionsChangeYourAddress->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsChangeYourAddress ) );
- this->Connect( m_menuOptionsOptions->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsOptions ) );
- this->Connect( m_menuHelpAbout->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuHelpAbout ) );
- this->Connect( wxID_BUTTONSEND, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonSend ) );
- this->Connect( wxID_BUTTONRECEIVE, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonAddressBook ) );
- m_textCtrlAddress->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CMainFrameBase::OnKeyDown ), NULL, this );
- m_textCtrlAddress->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this );
- m_textCtrlAddress->Connect( wxEVT_LEFT_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this );
- m_textCtrlAddress->Connect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this );
- m_textCtrlAddress->Connect( wxEVT_MIDDLE_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this );
- m_textCtrlAddress->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this );
- m_textCtrlAddress->Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this );
- m_textCtrlAddress->Connect( wxEVT_MOTION, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this );
- m_textCtrlAddress->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this );
- m_textCtrlAddress->Connect( wxEVT_MIDDLE_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this );
- m_textCtrlAddress->Connect( wxEVT_RIGHT_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this );
- m_textCtrlAddress->Connect( wxEVT_LEAVE_WINDOW, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this );
- m_textCtrlAddress->Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this );
- m_textCtrlAddress->Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this );
- m_textCtrlAddress->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( CMainFrameBase::OnSetFocusAddress ), NULL, this );
- m_buttonNew->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonNew ), NULL, this );
- m_buttonCopy->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonCopy ), NULL, this );
- m_notebook->Connect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( CMainFrameBase::OnNotebookPageChanged ), NULL, this );
- m_listCtrlAll->Connect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this );
- m_listCtrlAll->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this );
- m_listCtrlAll->Connect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this );
- m_listCtrlSentReceived->Connect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this );
- m_listCtrlSentReceived->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this );
- m_listCtrlSentReceived->Connect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this );
- m_listCtrlSent->Connect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this );
- m_listCtrlSent->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this );
- m_listCtrlSent->Connect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this );
- m_listCtrlReceived->Connect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this );
- m_listCtrlReceived->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this );
- m_listCtrlReceived->Connect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this );
-}
-
-CMainFrameBase::~CMainFrameBase()
-{
- // Disconnect Events
- this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CMainFrameBase::OnClose ) );
- this->Disconnect( wxEVT_ICONIZE, wxIconizeEventHandler( CMainFrameBase::OnIconize ) );
- this->Disconnect( wxEVT_IDLE, wxIdleEventHandler( CMainFrameBase::OnIdle ) );
- this->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) );
- this->Disconnect( wxEVT_LEFT_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) );
- this->Disconnect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) );
- this->Disconnect( wxEVT_MIDDLE_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) );
- this->Disconnect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) );
- this->Disconnect( wxEVT_RIGHT_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) );
- this->Disconnect( wxEVT_MOTION, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) );
- this->Disconnect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) );
- this->Disconnect( wxEVT_MIDDLE_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) );
- this->Disconnect( wxEVT_RIGHT_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) );
- this->Disconnect( wxEVT_LEAVE_WINDOW, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) );
- this->Disconnect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) );
- this->Disconnect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) );
- this->Disconnect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaint ) );
- this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuFileExit ) );
- this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsGenerate ) );
- this->Disconnect( wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateUIOptionsGenerate ) );
- this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsChangeYourAddress ) );
- this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsOptions ) );
- this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuHelpAbout ) );
- this->Disconnect( wxID_BUTTONSEND, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonSend ) );
- this->Disconnect( wxID_BUTTONRECEIVE, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonAddressBook ) );
- m_textCtrlAddress->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CMainFrameBase::OnKeyDown ), NULL, this );
- m_textCtrlAddress->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this );
- m_textCtrlAddress->Disconnect( wxEVT_LEFT_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this );
- m_textCtrlAddress->Disconnect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this );
- m_textCtrlAddress->Disconnect( wxEVT_MIDDLE_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this );
- m_textCtrlAddress->Disconnect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this );
- m_textCtrlAddress->Disconnect( wxEVT_RIGHT_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this );
- m_textCtrlAddress->Disconnect( wxEVT_MOTION, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this );
- m_textCtrlAddress->Disconnect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this );
- m_textCtrlAddress->Disconnect( wxEVT_MIDDLE_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this );
- m_textCtrlAddress->Disconnect( wxEVT_RIGHT_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this );
- m_textCtrlAddress->Disconnect( wxEVT_LEAVE_WINDOW, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this );
- m_textCtrlAddress->Disconnect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this );
- m_textCtrlAddress->Disconnect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this );
- m_textCtrlAddress->Disconnect( wxEVT_SET_FOCUS, wxFocusEventHandler( CMainFrameBase::OnSetFocusAddress ), NULL, this );
- m_buttonNew->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonNew ), NULL, this );
- m_buttonCopy->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonCopy ), NULL, this );
- m_notebook->Disconnect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( CMainFrameBase::OnNotebookPageChanged ), NULL, this );
- m_listCtrlAll->Disconnect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this );
- m_listCtrlAll->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this );
- m_listCtrlAll->Disconnect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this );
- m_listCtrlSentReceived->Disconnect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this );
- m_listCtrlSentReceived->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this );
- m_listCtrlSentReceived->Disconnect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this );
- m_listCtrlSent->Disconnect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this );
- m_listCtrlSent->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this );
- m_listCtrlSent->Disconnect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this );
- m_listCtrlReceived->Disconnect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this );
- m_listCtrlReceived->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this );
- m_listCtrlReceived->Disconnect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this );
-}
-
-CTxDetailsDialogBase::CTxDetailsDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
-{
- this->SetSizeHints( wxDefaultSize, wxDefaultSize );
-
- wxBoxSizer* bSizer64;
- bSizer64 = new wxBoxSizer( wxVERTICAL );
-
- wxBoxSizer* bSizer66;
- bSizer66 = new wxBoxSizer( wxVERTICAL );
-
- m_htmlWin = new wxHtmlWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO );
- bSizer66->Add( m_htmlWin, 1, wxALL|wxEXPAND, 5 );
-
- bSizer64->Add( bSizer66, 1, wxEXPAND, 5 );
-
- wxBoxSizer* bSizer65;
- bSizer65 = new wxBoxSizer( wxHORIZONTAL );
-
- m_buttonOK = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 );
- bSizer65->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
-
- bSizer64->Add( bSizer65, 0, wxALIGN_RIGHT, 5 );
-
- this->SetSizer( bSizer64 );
- this->Layout();
-
- // Connect Events
- m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CTxDetailsDialogBase::OnButtonOK ), NULL, this );
-}
-
-CTxDetailsDialogBase::~CTxDetailsDialogBase()
-{
- // Disconnect Events
- m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CTxDetailsDialogBase::OnButtonOK ), NULL, this );
-}
-
-COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
-{
- this->SetSizeHints( wxDefaultSize, wxDefaultSize );
-
- wxBoxSizer* bSizer55;
- bSizer55 = new wxBoxSizer( wxVERTICAL );
-
- wxBoxSizer* bSizer66;
- bSizer66 = new wxBoxSizer( wxHORIZONTAL );
-
- m_listBox = new wxListBox( this, wxID_ANY, wxDefaultPosition, wxSize( 110,-1 ), 0, NULL, wxLB_NEEDED_SB|wxLB_SINGLE );
- bSizer66->Add( m_listBox, 0, wxEXPAND|wxRIGHT, 5 );
-
- m_scrolledWindow = new wxScrolledWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
- m_scrolledWindow->SetScrollRate( 5, 5 );
- wxBoxSizer* bSizer63;
- bSizer63 = new wxBoxSizer( wxVERTICAL );
-
- m_panelMain = new wxPanel( m_scrolledWindow, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
- wxBoxSizer* bSizer69;
- bSizer69 = new wxBoxSizer( wxVERTICAL );
-
-
- bSizer69->Add( 0, 16, 0, wxEXPAND, 5 );
-
- m_staticText32 = new wxStaticText( m_panelMain, wxID_ANY, _("Optional transaction fee you give to the nodes that process your transactions."), wxDefaultPosition, wxDefaultSize, 0 );
- m_staticText32->Wrap( -1 );
- m_staticText32->Hide();
-
- bSizer69->Add( m_staticText32, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
-
- wxBoxSizer* bSizer56;
- bSizer56 = new wxBoxSizer( wxHORIZONTAL );
-
- m_staticText31 = new wxStaticText( m_panelMain, wxID_ANY, _("Transaction fee:"), wxDefaultPosition, wxDefaultSize, 0 );
- m_staticText31->Wrap( -1 );
- m_staticText31->Hide();
-
- bSizer56->Add( m_staticText31, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
-
- m_textCtrlTransactionFee = new wxTextCtrl( m_panelMain, wxID_TRANSACTIONFEE, wxEmptyString, wxDefaultPosition, wxSize( 70,-1 ), 0 );
- m_textCtrlTransactionFee->Hide();
-
- bSizer56->Add( m_textCtrlTransactionFee, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
-
- bSizer69->Add( bSizer56, 0, wxEXPAND, 5 );
-
- wxBoxSizer* bSizer71;
- bSizer71 = new wxBoxSizer( wxHORIZONTAL );
-
- m_checkBoxLimitProcessors = new wxCheckBox( m_panelMain, wxID_ANY, _("&Limit coin generation to"), wxDefaultPosition, wxDefaultSize, 0 );
-
- bSizer71->Add( m_checkBoxLimitProcessors, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
-
- m_spinCtrlLimitProcessors = new wxSpinCtrl( m_panelMain, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 48,-1 ), wxSP_ARROW_KEYS, 1, 999, 1 );
- bSizer71->Add( m_spinCtrlLimitProcessors, 0, wxALIGN_CENTER_VERTICAL, 5 );
-
- m_staticText35 = new wxStaticText( m_panelMain, wxID_ANY, _("processors"), wxDefaultPosition, wxDefaultSize, 0 );
- m_staticText35->Wrap( -1 );
- bSizer71->Add( m_staticText35, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
-
- bSizer69->Add( bSizer71, 0, 0, 5 );
-
- m_checkBoxStartOnSystemStartup = new wxCheckBox( m_panelMain, wxID_ANY, _("&Start Bitcoin on system startup"), wxDefaultPosition, wxDefaultSize, 0 );
-
- bSizer69->Add( m_checkBoxStartOnSystemStartup, 0, wxALL, 5 );
-
- m_checkBoxMinimizeToTray = new wxCheckBox( m_panelMain, wxID_ANY, _("&Minimize to the tray instead of the taskbar"), wxDefaultPosition, wxDefaultSize, 0 );
-
- bSizer69->Add( m_checkBoxMinimizeToTray, 0, wxALL, 5 );
-
- m_checkBoxMinimizeOnClose = new wxCheckBox( m_panelMain, wxID_ANY, _("M&inimize to the tray on close"), wxDefaultPosition, wxDefaultSize, 0 );
-
- bSizer69->Add( m_checkBoxMinimizeOnClose, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
-
- wxBoxSizer* bSizer102;
- bSizer102 = new wxBoxSizer( wxHORIZONTAL );
-
- m_checkBoxUseProxy = new wxCheckBox( m_panelMain, wxID_ANY, _("&Connect through socks4 proxy: "), wxDefaultPosition, wxDefaultSize, 0 );
-
- bSizer102->Add( m_checkBoxUseProxy, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
-
- bSizer69->Add( bSizer102, 1, wxEXPAND, 5 );
-
- wxBoxSizer* bSizer103;
- bSizer103 = new wxBoxSizer( wxHORIZONTAL );
-
-
- bSizer103->Add( 18, 0, 0, 0, 5 );
-
- m_staticTextProxyIP = new wxStaticText( m_panelMain, wxID_ANY, _("Proxy &IP:"), wxDefaultPosition, wxDefaultSize, 0 );
- m_staticTextProxyIP->Wrap( -1 );
- bSizer103->Add( m_staticTextProxyIP, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
-
- m_textCtrlProxyIP = new wxTextCtrl( m_panelMain, wxID_PROXYIP, wxEmptyString, wxDefaultPosition, wxSize( 140,-1 ), 0 );
- m_textCtrlProxyIP->SetMaxLength( 15 );
- bSizer103->Add( m_textCtrlProxyIP, 0, wxALIGN_CENTER_VERTICAL, 5 );
-
- m_staticTextProxyPort = new wxStaticText( m_panelMain, wxID_ANY, _(" &Port:"), wxDefaultPosition, wxDefaultSize, 0 );
- m_staticTextProxyPort->Wrap( -1 );
- bSizer103->Add( m_staticTextProxyPort, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
-
- m_textCtrlProxyPort = new wxTextCtrl( m_panelMain, wxID_PROXYPORT, wxEmptyString, wxDefaultPosition, wxSize( 55,-1 ), 0 );
- m_textCtrlProxyPort->SetMaxLength( 5 );
- bSizer103->Add( m_textCtrlProxyPort, 0, wxALIGN_CENTER_VERTICAL, 5 );
-
- bSizer69->Add( bSizer103, 1, wxEXPAND, 5 );
-
- m_panelMain->SetSizer( bSizer69 );
- m_panelMain->Layout();
- bSizer69->Fit( m_panelMain );
- bSizer63->Add( m_panelMain, 0, wxEXPAND, 5 );
-
- m_panelTest2 = new wxPanel( m_scrolledWindow, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
- wxBoxSizer* bSizer64;
- bSizer64 = new wxBoxSizer( wxVERTICAL );
-
-
- bSizer64->Add( 0, 16, 0, wxEXPAND, 5 );
-
- m_staticText321 = new wxStaticText( m_panelTest2, wxID_ANY, _("// [don't translate] Test panel 2 for future expansion"), wxDefaultPosition, wxDefaultSize, 0 );
- m_staticText321->Wrap( -1 );
- bSizer64->Add( m_staticText321, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
-
- m_staticText69 = new wxStaticText( m_panelTest2, wxID_ANY, _("// [don't translate] Let's not start multiple pages until the first page is filled up"), wxDefaultPosition, wxDefaultSize, 0 );
- m_staticText69->Wrap( -1 );
- bSizer64->Add( m_staticText69, 0, wxALL, 5 );
-
- m_panelTest2->SetSizer( bSizer64 );
- m_panelTest2->Layout();
- bSizer64->Fit( m_panelTest2 );
- bSizer63->Add( m_panelTest2, 0, wxEXPAND, 5 );
-
- m_scrolledWindow->SetSizer( bSizer63 );
- m_scrolledWindow->Layout();
- bSizer63->Fit( m_scrolledWindow );
- bSizer66->Add( m_scrolledWindow, 1, wxEXPAND|wxLEFT, 5 );
-
- bSizer55->Add( bSizer66, 1, wxEXPAND|wxALL, 9 );
-
- wxBoxSizer* bSizer58;
- bSizer58 = new wxBoxSizer( wxHORIZONTAL );
-
- m_buttonOK = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 );
- bSizer58->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
-
- m_buttonCancel = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 );
- bSizer58->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
-
- m_buttonApply = new wxButton( this, wxID_APPLY, _("&Apply"), wxDefaultPosition, wxSize( -1,-1 ), 0 );
- bSizer58->Add( m_buttonApply, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
-
- bSizer55->Add( bSizer58, 0, wxALIGN_RIGHT, 5 );
-
- this->SetSizer( bSizer55 );
- this->Layout();
-
- // Connect Events
- m_listBox->Connect( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( COptionsDialogBase::OnListBox ), NULL, this );
- m_textCtrlTransactionFee->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusTransactionFee ), NULL, this );
- m_checkBoxLimitProcessors->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxLimitProcessors ), NULL, this );
- m_checkBoxMinimizeToTray->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxMinimizeToTray ), NULL, this );
- m_checkBoxUseProxy->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxUseProxy ), NULL, this );
- m_textCtrlProxyIP->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusProxy ), NULL, this );
- m_textCtrlProxyPort->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusProxy ), NULL, this );
- m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonOK ), NULL, this );
- m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonCancel ), NULL, this );
- m_buttonApply->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonApply ), NULL, this );
-}
-
-COptionsDialogBase::~COptionsDialogBase()
-{
- // Disconnect Events
- m_listBox->Disconnect( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( COptionsDialogBase::OnListBox ), NULL, this );
- m_textCtrlTransactionFee->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusTransactionFee ), NULL, this );
- m_checkBoxLimitProcessors->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxLimitProcessors ), NULL, this );
- m_checkBoxMinimizeToTray->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxMinimizeToTray ), NULL, this );
- m_checkBoxUseProxy->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxUseProxy ), NULL, this );
- m_textCtrlProxyIP->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusProxy ), NULL, this );
- m_textCtrlProxyPort->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusProxy ), NULL, this );
- m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonOK ), NULL, this );
- m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonCancel ), NULL, this );
- m_buttonApply->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonApply ), NULL, this );
-}
-
-CAboutDialogBase::CAboutDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
-{
- this->SetSizeHints( wxDefaultSize, wxDefaultSize );
-
- wxBoxSizer* bSizer63;
- bSizer63 = new wxBoxSizer( wxHORIZONTAL );
-
- m_bitmap = new wxStaticBitmap( this, wxID_ANY, wxBitmap( about_xpm ), wxDefaultPosition, wxDefaultSize, 0 );
- bSizer63->Add( m_bitmap, 0, 0, 5 );
-
- wxBoxSizer* bSizer60;
- bSizer60 = new wxBoxSizer( wxVERTICAL );
-
- wxBoxSizer* bSizer62;
- bSizer62 = new wxBoxSizer( wxHORIZONTAL );
-
- wxBoxSizer* bSizer631;
- bSizer631 = new wxBoxSizer( wxVERTICAL );
-
-
- bSizer631->Add( 0, 65, 0, wxEXPAND, 5 );
-
- wxBoxSizer* bSizer64;
- bSizer64 = new wxBoxSizer( wxHORIZONTAL );
-
- m_staticText40 = new wxStaticText( this, wxID_ANY, _("Bitcoin "), wxDefaultPosition, wxDefaultSize, 0 );
- m_staticText40->Wrap( -1 );
- m_staticText40->SetFont( wxFont( 10, 74, 90, 92, false, wxT("Tahoma") ) );
-
- bSizer64->Add( m_staticText40, 0, wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxLEFT, 5 );
-
- m_staticTextVersion = new wxStaticText( this, wxID_ANY, _("version"), wxDefaultPosition, wxDefaultSize, 0 );
- m_staticTextVersion->Wrap( -1 );
- m_staticTextVersion->SetFont( wxFont( 10, 74, 90, 90, false, wxT("Tahoma") ) );
-
- bSizer64->Add( m_staticTextVersion, 0, wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxRIGHT, 5 );
-
- bSizer631->Add( bSizer64, 0, wxEXPAND, 5 );
-
-
- bSizer631->Add( 0, 4, 0, wxEXPAND, 5 );
-
- m_staticTextMain = new wxStaticText( this, wxID_ANY, _("Copyright (c) 2009-2010 Satoshi Nakamoto.\n\nThis is experimental software.\n\nDistributed under the MIT/X11 software license, see the accompanying file \nlicense.txt or http://www.opensource.org/licenses/mit-license.php.\n\nThis product includes software developed by the OpenSSL Project for use in the \nOpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by \nEric Young (eay@cryptsoft.com)."), wxDefaultPosition, wxDefaultSize, 0 );
- m_staticTextMain->Wrap( -1 );
- bSizer631->Add( m_staticTextMain, 0, wxALL, 5 );
-
-
- bSizer631->Add( 0, 0, 0, wxEXPAND, 5 );
-
- bSizer62->Add( bSizer631, 1, wxEXPAND, 5 );
-
- bSizer60->Add( bSizer62, 1, wxEXPAND, 5 );
-
- wxBoxSizer* bSizer61;
- bSizer61 = new wxBoxSizer( wxHORIZONTAL );
-
-
- bSizer61->Add( 0, 0, 1, wxEXPAND, 5 );
-
- m_buttonOK = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 );
- bSizer61->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 6 );
-
- bSizer60->Add( bSizer61, 0, wxALIGN_RIGHT|wxEXPAND|wxRIGHT, 2 );
-
- bSizer63->Add( bSizer60, 1, wxEXPAND|wxLEFT, 5 );
-
- this->SetSizer( bSizer63 );
- this->Layout();
-
- // Connect Events
- m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAboutDialogBase::OnButtonOK ), NULL, this );
-}
-
-CAboutDialogBase::~CAboutDialogBase()
-{
- // Disconnect Events
- m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAboutDialogBase::OnButtonOK ), NULL, this );
-}
-
-CSendDialogBase::CSendDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
-{
- this->SetSizeHints( wxDefaultSize, wxDefaultSize );
-
- wxBoxSizer* bSizer21;
- bSizer21 = new wxBoxSizer( wxVERTICAL );
-
-
- bSizer21->Add( 0, 5, 0, wxEXPAND, 5 );
-
- wxFlexGridSizer* fgSizer1;
- fgSizer1 = new wxFlexGridSizer( 0, 2, 0, 0 );
- fgSizer1->AddGrowableCol( 1 );
- fgSizer1->SetFlexibleDirection( wxBOTH );
- fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
-
-
- fgSizer1->Add( 0, 0, 0, wxEXPAND, 5 );
-
- m_staticTextInstructions = new wxStaticText( this, wxID_ANY, _("Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJED9L) or IP address (e.g. 123.45.6.7)"), wxDefaultPosition, wxDefaultSize, 0 );
- m_staticTextInstructions->Wrap( -1 );
- fgSizer1->Add( m_staticTextInstructions, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
-
- wxBoxSizer* bSizer47;
- bSizer47 = new wxBoxSizer( wxHORIZONTAL );
-
- bSizer47->SetMinSize( wxSize( 70,-1 ) );
-
- bSizer47->Add( 0, 0, 1, wxEXPAND, 5 );
-
- m_bitmapCheckMark = new wxStaticBitmap( this, wxID_ANY, wxBitmap( check_xpm ), wxDefaultPosition, wxSize( 16,16 ), 0 );
- bSizer47->Add( m_bitmapCheckMark, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
-
- m_staticText36 = new wxStaticText( this, wxID_ANY, _("Pay &To:"), wxDefaultPosition, wxSize( -1,-1 ), wxALIGN_RIGHT );
- m_staticText36->Wrap( -1 );
- bSizer47->Add( m_staticText36, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
-
- fgSizer1->Add( bSizer47, 1, wxEXPAND|wxLEFT, 5 );
-
- wxBoxSizer* bSizer19;
- bSizer19 = new wxBoxSizer( wxHORIZONTAL );
-
- m_textCtrlAddress = new wxTextCtrl( this, wxID_TEXTCTRLPAYTO, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
- bSizer19->Add( m_textCtrlAddress, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
-
- wxBoxSizer* bSizer66;
- bSizer66 = new wxBoxSizer( wxHORIZONTAL );
-
- m_buttonPaste = new wxButton( this, wxID_BUTTONPASTE, _("&Paste"), wxDefaultPosition, wxSize( -1,-1 ), wxBU_EXACTFIT );
- bSizer66->Add( m_buttonPaste, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxEXPAND, 5 );
-
- m_buttonAddress = new wxButton( this, wxID_BUTTONADDRESSBOOK, _(" Address &Book..."), wxDefaultPosition, wxDefaultSize, 0 );
- bSizer66->Add( m_buttonAddress, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxEXPAND, 5 );
-
- bSizer19->Add( bSizer66, 0, wxALIGN_CENTER_VERTICAL, 5 );
-
- fgSizer1->Add( bSizer19, 1, wxEXPAND|wxRIGHT, 5 );
-
- m_staticText19 = new wxStaticText( this, wxID_ANY, _("&Amount:"), wxDefaultPosition, wxSize( -1,-1 ), wxALIGN_RIGHT );
- m_staticText19->Wrap( -1 );
- fgSizer1->Add( m_staticText19, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT|wxALIGN_RIGHT, 5 );
-
- m_textCtrlAmount = new wxTextCtrl( this, wxID_TEXTCTRLAMOUNT, wxEmptyString, wxDefaultPosition, wxSize( 145,-1 ), 0 );
- m_textCtrlAmount->SetMaxLength( 20 );
- m_textCtrlAmount->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxEmptyString ) );
-
- fgSizer1->Add( m_textCtrlAmount, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
-
- m_staticText20 = new wxStaticText( this, wxID_ANY, _("T&ransfer:"), wxDefaultPosition, wxSize( -1,-1 ), wxALIGN_RIGHT );
- m_staticText20->Wrap( -1 );
- m_staticText20->Hide();
-
- fgSizer1->Add( m_staticText20, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5 );
-
- wxString m_choiceTransferTypeChoices[] = { _(" Standard") };
- int m_choiceTransferTypeNChoices = sizeof( m_choiceTransferTypeChoices ) / sizeof( wxString );
- m_choiceTransferType = new wxChoice( this, wxID_CHOICETRANSFERTYPE, wxDefaultPosition, wxDefaultSize, m_choiceTransferTypeNChoices, m_choiceTransferTypeChoices, 0 );
- m_choiceTransferType->SetSelection( 0 );
- m_choiceTransferType->Hide();
-
- fgSizer1->Add( m_choiceTransferType, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
-
-
- fgSizer1->Add( 0, 3, 0, wxEXPAND, 5 );
-
-
- fgSizer1->Add( 0, 0, 0, wxEXPAND, 5 );
-
- bSizer21->Add( fgSizer1, 0, wxEXPAND|wxLEFT, 5 );
-
- wxBoxSizer* bSizer672;
- bSizer672 = new wxBoxSizer( wxHORIZONTAL );
-
- wxBoxSizer* bSizer681;
- bSizer681 = new wxBoxSizer( wxVERTICAL );
-
- m_staticTextFrom = new wxStaticText( this, wxID_ANY, _("&From:"), wxDefaultPosition, wxDefaultSize, 0 );
- m_staticTextFrom->Wrap( -1 );
- bSizer681->Add( m_staticTextFrom, 0, wxBOTTOM|wxLEFT, 5 );
-
- m_textCtrlFrom = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 );
- bSizer681->Add( m_textCtrlFrom, 0, wxLEFT|wxEXPAND, 5 );
-
- bSizer672->Add( bSizer681, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
-
- bSizer21->Add( bSizer672, 0, wxEXPAND, 5 );
-
- wxBoxSizer* bSizer67;
- bSizer67 = new wxBoxSizer( wxHORIZONTAL );
-
- wxBoxSizer* bSizer68;
- bSizer68 = new wxBoxSizer( wxVERTICAL );
-
- m_staticTextMessage = new wxStaticText( this, wxID_ANY, _("&Message:"), wxDefaultPosition, wxDefaultSize, 0 );
- m_staticTextMessage->Wrap( -1 );
- bSizer68->Add( m_staticTextMessage, 0, wxTOP|wxBOTTOM|wxLEFT, 5 );
-
- m_textCtrlMessage = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE );
- bSizer68->Add( m_textCtrlMessage, 1, wxEXPAND|wxLEFT, 5 );
-
- bSizer67->Add( bSizer68, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
-
- bSizer21->Add( bSizer67, 1, wxEXPAND, 5 );
-
- wxBoxSizer* bSizer23;
- bSizer23 = new wxBoxSizer( wxHORIZONTAL );
-
-
- bSizer23->Add( 0, 0, 1, wxEXPAND, 5 );
-
- m_buttonSend = new wxButton( this, wxID_BUTTONSEND, _("&Send"), wxDefaultPosition, wxSize( -1,-1 ), 0 );
- m_buttonSend->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxEmptyString ) );
-
- bSizer23->Add( m_buttonSend, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
-
- m_buttonCancel = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 );
- bSizer23->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
-
- bSizer21->Add( bSizer23, 0, wxEXPAND, 5 );
-
- this->SetSizer( bSizer21 );
- this->Layout();
-
- // Connect Events
- m_textCtrlAddress->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CSendDialogBase::OnKeyDown ), NULL, this );
- m_textCtrlAddress->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( CSendDialogBase::OnTextAddress ), NULL, this );
- m_buttonPaste->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendDialogBase::OnButtonPaste ), NULL, this );
- m_buttonAddress->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendDialogBase::OnButtonAddressBook ), NULL, this );
- m_textCtrlAmount->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CSendDialogBase::OnKeyDown ), NULL, this );
- m_textCtrlAmount->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( CSendDialogBase::OnKillFocusAmount ), NULL, this );
- m_textCtrlFrom->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CSendDialogBase::OnKeyDown ), NULL, this );
- m_textCtrlMessage->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CSendDialogBase::OnKeyDown ), NULL, this );
- m_buttonSend->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendDialogBase::OnButtonSend ), NULL, this );
- m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendDialogBase::OnButtonCancel ), NULL, this );
-}
-
-CSendDialogBase::~CSendDialogBase()
-{
- // Disconnect Events
- m_textCtrlAddress->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CSendDialogBase::OnKeyDown ), NULL, this );
- m_textCtrlAddress->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( CSendDialogBase::OnTextAddress ), NULL, this );
- m_buttonPaste->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendDialogBase::OnButtonPaste ), NULL, this );
- m_buttonAddress->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendDialogBase::OnButtonAddressBook ), NULL, this );
- m_textCtrlAmount->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CSendDialogBase::OnKeyDown ), NULL, this );
- m_textCtrlAmount->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( CSendDialogBase::OnKillFocusAmount ), NULL, this );
- m_textCtrlFrom->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CSendDialogBase::OnKeyDown ), NULL, this );
- m_textCtrlMessage->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CSendDialogBase::OnKeyDown ), NULL, this );
- m_buttonSend->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendDialogBase::OnButtonSend ), NULL, this );
- m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendDialogBase::OnButtonCancel ), NULL, this );
-}
-
-CSendingDialogBase::CSendingDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
-{
- this->SetSizeHints( wxDefaultSize, wxDefaultSize );
-
- wxBoxSizer* bSizer68;
- bSizer68 = new wxBoxSizer( wxVERTICAL );
-
- m_staticTextSending = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,14 ), 0 );
- m_staticTextSending->Wrap( -1 );
- bSizer68->Add( m_staticTextSending, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 8 );
-
- m_textCtrlStatus = new wxTextCtrl( this, wxID_ANY, _("\n\nConnecting..."), wxDefaultPosition, wxDefaultSize, wxTE_CENTRE|wxTE_MULTILINE|wxTE_NO_VSCROLL|wxTE_READONLY|wxNO_BORDER );
- m_textCtrlStatus->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) );
-
- bSizer68->Add( m_textCtrlStatus, 1, wxEXPAND|wxRIGHT|wxLEFT, 10 );
-
- wxBoxSizer* bSizer69;
- bSizer69 = new wxBoxSizer( wxHORIZONTAL );
-
-
- bSizer69->Add( 0, 0, 1, wxEXPAND, 5 );
-
- m_buttonOK = new wxButton( this, wxID_ANY, _("OK"), wxDefaultPosition, wxDefaultSize, 0 );
- m_buttonOK->Enable( false );
-
- bSizer69->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
-
- m_buttonCancel = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 );
- bSizer69->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
-
- bSizer68->Add( bSizer69, 0, wxEXPAND, 5 );
-
- this->SetSizer( bSizer68 );
- this->Layout();
-
- // Connect Events
- this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CSendingDialogBase::OnClose ) );
- this->Connect( wxEVT_PAINT, wxPaintEventHandler( CSendingDialogBase::OnPaint ) );
- m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendingDialogBase::OnButtonOK ), NULL, this );
- m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendingDialogBase::OnButtonCancel ), NULL, this );
-}
-
-CSendingDialogBase::~CSendingDialogBase()
-{
- // Disconnect Events
- this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CSendingDialogBase::OnClose ) );
- this->Disconnect( wxEVT_PAINT, wxPaintEventHandler( CSendingDialogBase::OnPaint ) );
- m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendingDialogBase::OnButtonOK ), NULL, this );
- m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendingDialogBase::OnButtonCancel ), NULL, this );
-}
-
-CYourAddressDialogBase::CYourAddressDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
-{
- this->SetSizeHints( wxDefaultSize, wxDefaultSize );
-
- wxBoxSizer* bSizer68;
- bSizer68 = new wxBoxSizer( wxVERTICAL );
-
-
- bSizer68->Add( 0, 5, 0, wxEXPAND, 5 );
-
- m_staticText45 = new wxStaticText( this, wxID_ANY, _("These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. The highlighted address is displayed in the main window."), wxDefaultPosition, wxDefaultSize, 0 );
- m_staticText45->Wrap( 590 );
- bSizer68->Add( m_staticText45, 0, wxALL, 5 );
-
- m_listCtrl = new wxListCtrl( this, wxID_LISTCTRL, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING );
- bSizer68->Add( m_listCtrl, 1, wxALL|wxEXPAND, 5 );
-
- wxBoxSizer* bSizer69;
- bSizer69 = new wxBoxSizer( wxHORIZONTAL );
-
-
- bSizer69->Add( 0, 0, 1, wxEXPAND, 5 );
-
- m_buttonRename = new wxButton( this, wxID_BUTTONRENAME, _("&Edit..."), wxDefaultPosition, wxDefaultSize, 0 );
- bSizer69->Add( m_buttonRename, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
-
- m_buttonNew = new wxButton( this, wxID_BUTTONNEW, _(" &New Address... "), wxDefaultPosition, wxSize( -1,-1 ), 0 );
- bSizer69->Add( m_buttonNew, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
-
- m_buttonCopy = new wxButton( this, wxID_BUTTONCOPY, _(" &Copy to Clipboard "), wxDefaultPosition, wxSize( -1,-1 ), 0 );
- bSizer69->Add( m_buttonCopy, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
-
- m_buttonOK = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxDefaultSize, 0 );
- bSizer69->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
-
- m_buttonCancel = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 );
- m_buttonCancel->Hide();
-
- bSizer69->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
-
- bSizer68->Add( bSizer69, 0, wxEXPAND, 5 );
-
- this->SetSizer( bSizer68 );
- this->Layout();
-
- // Connect Events
- this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CYourAddressDialogBase::OnClose ) );
- m_listCtrl->Connect( wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler( CYourAddressDialogBase::OnListEndLabelEdit ), NULL, this );
- m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CYourAddressDialogBase::OnListItemActivated ), NULL, this );
- m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CYourAddressDialogBase::OnListItemSelected ), NULL, this );
- m_buttonRename->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CYourAddressDialogBase::OnButtonRename ), NULL, this );
- m_buttonNew->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CYourAddressDialogBase::OnButtonNew ), NULL, this );
- m_buttonCopy->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CYourAddressDialogBase::OnButtonCopy ), NULL, this );
- m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CYourAddressDialogBase::OnButtonOK ), NULL, this );
- m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CYourAddressDialogBase::OnButtonCancel ), NULL, this );
-}
-
-CYourAddressDialogBase::~CYourAddressDialogBase()
-{
- // Disconnect Events
- this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CYourAddressDialogBase::OnClose ) );
- m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler( CYourAddressDialogBase::OnListEndLabelEdit ), NULL, this );
- m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CYourAddressDialogBase::OnListItemActivated ), NULL, this );
- m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CYourAddressDialogBase::OnListItemSelected ), NULL, this );
- m_buttonRename->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CYourAddressDialogBase::OnButtonRename ), NULL, this );
- m_buttonNew->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CYourAddressDialogBase::OnButtonNew ), NULL, this );
- m_buttonCopy->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CYourAddressDialogBase::OnButtonCopy ), NULL, this );
- m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CYourAddressDialogBase::OnButtonOK ), NULL, this );
- m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CYourAddressDialogBase::OnButtonCancel ), NULL, this );
-}
-
-CAddressBookDialogBase::CAddressBookDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
-{
- this->SetSizeHints( wxDefaultSize, wxDefaultSize );
-
- wxBoxSizer* bSizer58;
- bSizer58 = new wxBoxSizer( wxVERTICAL );
-
- m_notebook = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
- m_panelSending = new wxPanel( m_notebook, wxID_PANELSENDING, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
- wxBoxSizer* bSizer68;
- bSizer68 = new wxBoxSizer( wxVERTICAL );
-
-
- bSizer68->Add( 0, 0, 0, wxEXPAND, 5 );
-
- m_staticText55 = new wxStaticText( m_panelSending, wxID_ANY, _("Bitcoin Address"), wxDefaultPosition, wxDefaultSize, 0 );
- m_staticText55->Wrap( -1 );
- m_staticText55->Hide();
-
- bSizer68->Add( m_staticText55, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
-
- m_listCtrlSending = new wxListCtrl( m_panelSending, wxID_LISTCTRLSENDING, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING );
- bSizer68->Add( m_listCtrlSending, 1, wxALL|wxEXPAND, 5 );
-
- m_panelSending->SetSizer( bSizer68 );
- m_panelSending->Layout();
- bSizer68->Fit( m_panelSending );
- m_notebook->AddPage( m_panelSending, _("Sending"), false );
- m_panelReceiving = new wxPanel( m_notebook, wxID_PANELRECEIVING, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
- wxBoxSizer* bSizer681;
- bSizer681 = new wxBoxSizer( wxVERTICAL );
-
-
- bSizer681->Add( 0, 0, 0, wxEXPAND, 5 );
-
- m_staticText45 = new wxStaticText( m_panelReceiving, wxID_ANY, _("These are your Bitcoin addresses for receiving payments. You can give a different one to each sender to keep track of who is paying you. The highlighted address will be displayed in the main window."), wxDefaultPosition, wxDefaultSize, 0 );
- m_staticText45->Wrap( 570 );
- bSizer681->Add( m_staticText45, 0, wxTOP|wxRIGHT|wxLEFT, 6 );
-
-
- bSizer681->Add( 0, 2, 0, wxEXPAND, 5 );
-
- m_listCtrlReceiving = new wxListCtrl( m_panelReceiving, wxID_LISTCTRLRECEIVING, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING );
- bSizer681->Add( m_listCtrlReceiving, 1, wxALL|wxEXPAND, 5 );
-
- m_panelReceiving->SetSizer( bSizer681 );
- m_panelReceiving->Layout();
- bSizer681->Fit( m_panelReceiving );
- m_notebook->AddPage( m_panelReceiving, _("Receiving"), true );
-
- bSizer58->Add( m_notebook, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
-
- wxBoxSizer* bSizer69;
- bSizer69 = new wxBoxSizer( wxHORIZONTAL );
-
-
- bSizer69->Add( 0, 0, 1, wxEXPAND, 5 );
-
- m_buttonDelete = new wxButton( this, wxID_BUTTONDELETE, _("&Delete"), wxDefaultPosition, wxDefaultSize, 0 );
- bSizer69->Add( m_buttonDelete, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
-
- m_buttonCopy = new wxButton( this, wxID_BUTTONCOPY, _(" &Copy to Clipboard "), wxDefaultPosition, wxSize( -1,-1 ), 0 );
- bSizer69->Add( m_buttonCopy, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
-
- m_buttonEdit = new wxButton( this, wxID_BUTTONEDIT, _("&Edit..."), wxDefaultPosition, wxDefaultSize, 0 );
- bSizer69->Add( m_buttonEdit, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
-
- m_buttonNew = new wxButton( this, wxID_BUTTONNEW, _(" &New Address... "), wxDefaultPosition, wxDefaultSize, 0 );
- bSizer69->Add( m_buttonNew, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
-
- m_buttonOK = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 );
- bSizer69->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
-
- m_buttonCancel = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 );
- bSizer69->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
-
- bSizer58->Add( bSizer69, 0, wxEXPAND, 5 );
-
- this->SetSizer( bSizer58 );
- this->Layout();
-
- // Connect Events
- this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CAddressBookDialogBase::OnClose ) );
- m_notebook->Connect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( CAddressBookDialogBase::OnNotebookPageChanged ), NULL, this );
- m_listCtrlSending->Connect( wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler( CAddressBookDialogBase::OnListEndLabelEdit ), NULL, this );
- m_listCtrlSending->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CAddressBookDialogBase::OnListItemActivated ), NULL, this );
- m_listCtrlSending->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CAddressBookDialogBase::OnListItemSelected ), NULL, this );
- m_listCtrlReceiving->Connect( wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler( CAddressBookDialogBase::OnListEndLabelEdit ), NULL, this );
- m_listCtrlReceiving->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CAddressBookDialogBase::OnListItemActivated ), NULL, this );
- m_listCtrlReceiving->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CAddressBookDialogBase::OnListItemSelected ), NULL, this );
- m_buttonDelete->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonDelete ), NULL, this );
- m_buttonCopy->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonCopy ), NULL, this );
- m_buttonEdit->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonEdit ), NULL, this );
- m_buttonNew->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonNew ), NULL, this );
- m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonOK ), NULL, this );
- m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonCancel ), NULL, this );
-}
-
-CAddressBookDialogBase::~CAddressBookDialogBase()
-{
- // Disconnect Events
- this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CAddressBookDialogBase::OnClose ) );
- m_notebook->Disconnect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( CAddressBookDialogBase::OnNotebookPageChanged ), NULL, this );
- m_listCtrlSending->Disconnect( wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler( CAddressBookDialogBase::OnListEndLabelEdit ), NULL, this );
- m_listCtrlSending->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CAddressBookDialogBase::OnListItemActivated ), NULL, this );
- m_listCtrlSending->Disconnect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CAddressBookDialogBase::OnListItemSelected ), NULL, this );
- m_listCtrlReceiving->Disconnect( wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler( CAddressBookDialogBase::OnListEndLabelEdit ), NULL, this );
- m_listCtrlReceiving->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CAddressBookDialogBase::OnListItemActivated ), NULL, this );
- m_listCtrlReceiving->Disconnect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CAddressBookDialogBase::OnListItemSelected ), NULL, this );
- m_buttonDelete->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonDelete ), NULL, this );
- m_buttonCopy->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonCopy ), NULL, this );
- m_buttonEdit->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonEdit ), NULL, this );
- m_buttonNew->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonNew ), NULL, this );
- m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonOK ), NULL, this );
- m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonCancel ), NULL, this );
-}
-
-CGetTextFromUserDialogBase::CGetTextFromUserDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
-{
- this->SetSizeHints( wxDefaultSize, wxDefaultSize );
-
- wxBoxSizer* bSizer79;
- bSizer79 = new wxBoxSizer( wxVERTICAL );
-
- wxBoxSizer* bSizer81;
- bSizer81 = new wxBoxSizer( wxVERTICAL );
-
-
- bSizer81->Add( 0, 0, 1, wxEXPAND, 5 );
-
- m_staticTextMessage1 = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
- m_staticTextMessage1->Wrap( -1 );
- bSizer81->Add( m_staticTextMessage1, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
-
- m_textCtrl1 = new wxTextCtrl( this, wxID_TEXTCTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER );
- bSizer81->Add( m_textCtrl1, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL, 5 );
-
- m_staticTextMessage2 = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
- m_staticTextMessage2->Wrap( -1 );
- m_staticTextMessage2->Hide();
-
- bSizer81->Add( m_staticTextMessage2, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
-
- m_textCtrl2 = new wxTextCtrl( this, wxID_TEXTCTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER );
- m_textCtrl2->Hide();
-
- bSizer81->Add( m_textCtrl2, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL, 5 );
-
-
- bSizer81->Add( 0, 0, 1, wxEXPAND, 5 );
-
- bSizer79->Add( bSizer81, 1, wxEXPAND|wxALL, 10 );
-
- wxBoxSizer* bSizer80;
- bSizer80 = new wxBoxSizer( wxHORIZONTAL );
-
-
- bSizer80->Add( 0, 0, 1, wxEXPAND, 5 );
-
- m_buttonOK = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 );
- bSizer80->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
-
- m_buttonCancel = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
- bSizer80->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
-
- bSizer79->Add( bSizer80, 0, wxEXPAND, 5 );
-
- this->SetSizer( bSizer79 );
- this->Layout();
-
- // Connect Events
- this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CGetTextFromUserDialogBase::OnClose ) );
- m_textCtrl1->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CGetTextFromUserDialogBase::OnKeyDown ), NULL, this );
- m_textCtrl2->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CGetTextFromUserDialogBase::OnKeyDown ), NULL, this );
- m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CGetTextFromUserDialogBase::OnButtonOK ), NULL, this );
- m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CGetTextFromUserDialogBase::OnButtonCancel ), NULL, this );
-}
-
-CGetTextFromUserDialogBase::~CGetTextFromUserDialogBase()
-{
- // Disconnect Events
- this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CGetTextFromUserDialogBase::OnClose ) );
- m_textCtrl1->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CGetTextFromUserDialogBase::OnKeyDown ), NULL, this );
- m_textCtrl2->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CGetTextFromUserDialogBase::OnKeyDown ), NULL, this );
- m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CGetTextFromUserDialogBase::OnButtonOK ), NULL, this );
- m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CGetTextFromUserDialogBase::OnButtonCancel ), NULL, this );
-}
+/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Apr 16 2008) +// http://www.wxformbuilder.org/ +// +// PLEASE DO "NOT" EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#include "uibase.h" + +#include "xpm/about.xpm" +#include "xpm/addressbook20.xpm" +#include "xpm/check.xpm" +#include "xpm/send20.xpm" + +/////////////////////////////////////////////////////////////////////////// + +CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) ); + + m_menubar = new wxMenuBar( 0 ); + m_menuFile = new wxMenu(); + wxMenuItem* m_menuFileExit; + m_menuFileExit = new wxMenuItem( m_menuFile, wxID_EXIT, wxString( _("E&xit") ) , wxEmptyString, wxITEM_NORMAL ); + m_menuFile->Append( m_menuFileExit ); + + m_menubar->Append( m_menuFile, _("&File") ); + + m_menuOptions = new wxMenu(); + wxMenuItem* m_menuOptionsGenerateBitcoins; + m_menuOptionsGenerateBitcoins = new wxMenuItem( m_menuOptions, wxID_OPTIONSGENERATEBITCOINS, wxString( _("&Generate Coins") ) , wxEmptyString, wxITEM_CHECK ); + m_menuOptions->Append( m_menuOptionsGenerateBitcoins ); + + wxMenuItem* m_menuOptionsChangeYourAddress; + m_menuOptionsChangeYourAddress = new wxMenuItem( m_menuOptions, wxID_ANY, wxString( _("&Your Receiving Addresses...") ) , wxEmptyString, wxITEM_NORMAL ); + m_menuOptions->Append( m_menuOptionsChangeYourAddress ); + + wxMenuItem* m_menuOptionsOptions; + m_menuOptionsOptions = new wxMenuItem( m_menuOptions, wxID_PREFERENCES, wxString( _("&Options...") ) , wxEmptyString, wxITEM_NORMAL ); + m_menuOptions->Append( m_menuOptionsOptions ); + + m_menubar->Append( m_menuOptions, _("&Settings") ); + + m_menuHelp = new wxMenu(); + wxMenuItem* m_menuHelpAbout; + m_menuHelpAbout = new wxMenuItem( m_menuHelp, wxID_ABOUT, wxString( _("&About...") ) , wxEmptyString, wxITEM_NORMAL ); + m_menuHelp->Append( m_menuHelpAbout ); + + m_menubar->Append( m_menuHelp, _("&Help") ); + + this->SetMenuBar( m_menubar ); + + m_toolBar = this->CreateToolBar( wxTB_FLAT|wxTB_HORZ_TEXT, wxID_ANY ); + m_toolBar->SetToolBitmapSize( wxSize( 20,20 ) ); + m_toolBar->SetToolSeparation( 1 ); + m_toolBar->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxEmptyString ) ); + + m_toolBar->AddTool( wxID_BUTTONSEND, _("Send Coins"), wxBitmap( send20_xpm ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString ); + m_toolBar->AddTool( wxID_BUTTONRECEIVE, _("Address Book"), wxBitmap( addressbook20_xpm ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString ); + m_toolBar->Realize(); + + m_statusBar = this->CreateStatusBar( 1, wxST_SIZEGRIP, wxID_ANY ); + m_statusBar->SetBackgroundColour( wxColour( 240, 240, 240 ) ); + + wxBoxSizer* bSizer2; + bSizer2 = new wxBoxSizer( wxVERTICAL ); + + + bSizer2->Add( 0, 2, 0, wxEXPAND, 5 ); + + wxBoxSizer* bSizer85; + bSizer85 = new wxBoxSizer( wxHORIZONTAL ); + + m_staticText32 = new wxStaticText( this, wxID_ANY, _("Your Bitcoin Address:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText32->Wrap( -1 ); + bSizer85->Add( m_staticText32, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); + + m_textCtrlAddress = new wxTextCtrl( this, wxID_TEXTCTRLADDRESS, wxEmptyString, wxDefaultPosition, wxSize( 340,-1 ), wxTE_READONLY ); + bSizer85->Add( m_textCtrlAddress, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_buttonNew = new wxButton( this, wxID_BUTTONNEW, _(" &New... "), wxDefaultPosition, wxSize( -1,-1 ), wxBU_EXACTFIT ); + bSizer85->Add( m_buttonNew, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonCopy = new wxButton( this, wxID_BUTTONCOPY, _(" &Copy to Clipboard "), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT ); + bSizer85->Add( m_buttonCopy, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + + + bSizer85->Add( 0, 0, 0, wxEXPAND, 5 ); + + bSizer2->Add( bSizer85, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 ); + + wxBoxSizer* bSizer3; + bSizer3 = new wxBoxSizer( wxHORIZONTAL ); + + wxBoxSizer* bSizer66; + bSizer66 = new wxBoxSizer( wxHORIZONTAL ); + + m_staticText41 = new wxStaticText( this, wxID_ANY, _("Balance:"), wxDefaultPosition, wxSize( -1,15 ), 0 ); + m_staticText41->Wrap( -1 ); + bSizer66->Add( m_staticText41, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 ); + + m_staticTextBalance = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 120,15 ), wxALIGN_RIGHT|wxST_NO_AUTORESIZE ); + m_staticTextBalance->Wrap( -1 ); + m_staticTextBalance->SetFont( wxFont( 8, 70, 90, 90, false, wxEmptyString ) ); + m_staticTextBalance->SetBackgroundColour( wxColour( 255, 255, 255 ) ); + + bSizer66->Add( m_staticTextBalance, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + bSizer3->Add( bSizer66, 1, wxEXPAND|wxALL, 5 ); + + + bSizer3->Add( 0, 0, 0, wxEXPAND, 5 ); + + wxString m_choiceFilterChoices[] = { _(" All"), _(" Sent"), _(" Received"), _(" In Progress") }; + int m_choiceFilterNChoices = sizeof( m_choiceFilterChoices ) / sizeof( wxString ); + m_choiceFilter = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxSize( 110,-1 ), m_choiceFilterNChoices, m_choiceFilterChoices, 0 ); + m_choiceFilter->SetSelection( 0 ); + m_choiceFilter->Hide(); + + bSizer3->Add( m_choiceFilter, 0, wxALIGN_BOTTOM|wxTOP|wxRIGHT|wxLEFT, 5 ); + + bSizer2->Add( bSizer3, 0, wxEXPAND, 5 ); + + m_notebook = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); + m_panel9 = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer11; + bSizer11 = new wxBoxSizer( wxVERTICAL ); + + m_listCtrlAll = new wxListCtrl( m_panel9, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING ); + bSizer11->Add( m_listCtrlAll, 1, wxEXPAND, 5 ); + + m_panel9->SetSizer( bSizer11 ); + m_panel9->Layout(); + bSizer11->Fit( m_panel9 ); + m_notebook->AddPage( m_panel9, _("All Transactions"), true ); + m_panel91 = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer111; + bSizer111 = new wxBoxSizer( wxVERTICAL ); + + m_listCtrlSentReceived = new wxListCtrl( m_panel91, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING ); + bSizer111->Add( m_listCtrlSentReceived, 1, wxEXPAND, 5 ); + + m_panel91->SetSizer( bSizer111 ); + m_panel91->Layout(); + bSizer111->Fit( m_panel91 ); + m_notebook->AddPage( m_panel91, _("Sent/Received"), false ); + m_panel92 = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer112; + bSizer112 = new wxBoxSizer( wxVERTICAL ); + + m_listCtrlSent = new wxListCtrl( m_panel92, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING ); + bSizer112->Add( m_listCtrlSent, 1, wxEXPAND, 5 ); + + m_panel92->SetSizer( bSizer112 ); + m_panel92->Layout(); + bSizer112->Fit( m_panel92 ); + m_notebook->AddPage( m_panel92, _("Sent"), false ); + m_panel93 = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer113; + bSizer113 = new wxBoxSizer( wxVERTICAL ); + + m_listCtrlReceived = new wxListCtrl( m_panel93, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING ); + bSizer113->Add( m_listCtrlReceived, 1, wxEXPAND, 5 ); + + m_panel93->SetSizer( bSizer113 ); + m_panel93->Layout(); + bSizer113->Fit( m_panel93 ); + m_notebook->AddPage( m_panel93, _("Received"), false ); + + bSizer2->Add( m_notebook, 1, wxEXPAND, 5 ); + + this->SetSizer( bSizer2 ); + this->Layout(); + + // Connect Events + this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CMainFrameBase::OnClose ) ); + this->Connect( wxEVT_ICONIZE, wxIconizeEventHandler( CMainFrameBase::OnIconize ) ); + this->Connect( wxEVT_IDLE, wxIdleEventHandler( CMainFrameBase::OnIdle ) ); + this->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); + this->Connect( wxEVT_LEFT_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); + this->Connect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); + this->Connect( wxEVT_MIDDLE_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); + this->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); + this->Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); + this->Connect( wxEVT_MOTION, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); + this->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); + this->Connect( wxEVT_MIDDLE_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); + this->Connect( wxEVT_RIGHT_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); + this->Connect( wxEVT_LEAVE_WINDOW, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); + this->Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); + this->Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); + this->Connect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaint ) ); + this->Connect( m_menuFileExit->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuFileExit ) ); + this->Connect( m_menuOptionsGenerateBitcoins->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsGenerate ) ); + this->Connect( m_menuOptionsGenerateBitcoins->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateUIOptionsGenerate ) ); + this->Connect( m_menuOptionsChangeYourAddress->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsChangeYourAddress ) ); + this->Connect( m_menuOptionsOptions->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsOptions ) ); + this->Connect( m_menuHelpAbout->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuHelpAbout ) ); + this->Connect( wxID_BUTTONSEND, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonSend ) ); + this->Connect( wxID_BUTTONRECEIVE, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonAddressBook ) ); + m_textCtrlAddress->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CMainFrameBase::OnKeyDown ), NULL, this ); + m_textCtrlAddress->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); + m_textCtrlAddress->Connect( wxEVT_LEFT_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); + m_textCtrlAddress->Connect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); + m_textCtrlAddress->Connect( wxEVT_MIDDLE_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); + m_textCtrlAddress->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); + m_textCtrlAddress->Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); + m_textCtrlAddress->Connect( wxEVT_MOTION, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); + m_textCtrlAddress->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); + m_textCtrlAddress->Connect( wxEVT_MIDDLE_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); + m_textCtrlAddress->Connect( wxEVT_RIGHT_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); + m_textCtrlAddress->Connect( wxEVT_LEAVE_WINDOW, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); + m_textCtrlAddress->Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); + m_textCtrlAddress->Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); + m_textCtrlAddress->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( CMainFrameBase::OnSetFocusAddress ), NULL, this ); + m_buttonNew->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonNew ), NULL, this ); + m_buttonCopy->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonCopy ), NULL, this ); + m_notebook->Connect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( CMainFrameBase::OnNotebookPageChanged ), NULL, this ); + m_listCtrlAll->Connect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); + m_listCtrlAll->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this ); + m_listCtrlAll->Connect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this ); + m_listCtrlSentReceived->Connect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); + m_listCtrlSentReceived->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this ); + m_listCtrlSentReceived->Connect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this ); + m_listCtrlSent->Connect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); + m_listCtrlSent->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this ); + m_listCtrlSent->Connect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this ); + m_listCtrlReceived->Connect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); + m_listCtrlReceived->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this ); + m_listCtrlReceived->Connect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this ); +} + +CMainFrameBase::~CMainFrameBase() +{ + // Disconnect Events + this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CMainFrameBase::OnClose ) ); + this->Disconnect( wxEVT_ICONIZE, wxIconizeEventHandler( CMainFrameBase::OnIconize ) ); + this->Disconnect( wxEVT_IDLE, wxIdleEventHandler( CMainFrameBase::OnIdle ) ); + this->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_LEFT_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_MIDDLE_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_RIGHT_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_MOTION, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_MIDDLE_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_RIGHT_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_LEAVE_WINDOW, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaint ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuFileExit ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsGenerate ) ); + this->Disconnect( wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateUIOptionsGenerate ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsChangeYourAddress ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsOptions ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuHelpAbout ) ); + this->Disconnect( wxID_BUTTONSEND, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonSend ) ); + this->Disconnect( wxID_BUTTONRECEIVE, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonAddressBook ) ); + m_textCtrlAddress->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CMainFrameBase::OnKeyDown ), NULL, this ); + m_textCtrlAddress->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); + m_textCtrlAddress->Disconnect( wxEVT_LEFT_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); + m_textCtrlAddress->Disconnect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); + m_textCtrlAddress->Disconnect( wxEVT_MIDDLE_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); + m_textCtrlAddress->Disconnect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); + m_textCtrlAddress->Disconnect( wxEVT_RIGHT_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); + m_textCtrlAddress->Disconnect( wxEVT_MOTION, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); + m_textCtrlAddress->Disconnect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); + m_textCtrlAddress->Disconnect( wxEVT_MIDDLE_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); + m_textCtrlAddress->Disconnect( wxEVT_RIGHT_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); + m_textCtrlAddress->Disconnect( wxEVT_LEAVE_WINDOW, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); + m_textCtrlAddress->Disconnect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); + m_textCtrlAddress->Disconnect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); + m_textCtrlAddress->Disconnect( wxEVT_SET_FOCUS, wxFocusEventHandler( CMainFrameBase::OnSetFocusAddress ), NULL, this ); + m_buttonNew->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonNew ), NULL, this ); + m_buttonCopy->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonCopy ), NULL, this ); + m_notebook->Disconnect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( CMainFrameBase::OnNotebookPageChanged ), NULL, this ); + m_listCtrlAll->Disconnect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); + m_listCtrlAll->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this ); + m_listCtrlAll->Disconnect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this ); + m_listCtrlSentReceived->Disconnect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); + m_listCtrlSentReceived->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this ); + m_listCtrlSentReceived->Disconnect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this ); + m_listCtrlSent->Disconnect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); + m_listCtrlSent->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this ); + m_listCtrlSent->Disconnect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this ); + m_listCtrlReceived->Disconnect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); + m_listCtrlReceived->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this ); + m_listCtrlReceived->Disconnect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this ); +} + +CTxDetailsDialogBase::CTxDetailsDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer64; + bSizer64 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer66; + bSizer66 = new wxBoxSizer( wxVERTICAL ); + + m_htmlWin = new wxHtmlWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO ); + bSizer66->Add( m_htmlWin, 1, wxALL|wxEXPAND, 5 ); + + bSizer64->Add( bSizer66, 1, wxEXPAND, 5 ); + + wxBoxSizer* bSizer65; + bSizer65 = new wxBoxSizer( wxHORIZONTAL ); + + m_buttonOK = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + bSizer65->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + bSizer64->Add( bSizer65, 0, wxALIGN_RIGHT, 5 ); + + this->SetSizer( bSizer64 ); + this->Layout(); + + // Connect Events + m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CTxDetailsDialogBase::OnButtonOK ), NULL, this ); +} + +CTxDetailsDialogBase::~CTxDetailsDialogBase() +{ + // Disconnect Events + m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CTxDetailsDialogBase::OnButtonOK ), NULL, this ); +} + +COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer55; + bSizer55 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer66; + bSizer66 = new wxBoxSizer( wxHORIZONTAL ); + + m_listBox = new wxListBox( this, wxID_ANY, wxDefaultPosition, wxSize( 110,-1 ), 0, NULL, wxLB_NEEDED_SB|wxLB_SINGLE ); + bSizer66->Add( m_listBox, 0, wxEXPAND|wxRIGHT, 5 ); + + m_scrolledWindow = new wxScrolledWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); + m_scrolledWindow->SetScrollRate( 5, 5 ); + wxBoxSizer* bSizer63; + bSizer63 = new wxBoxSizer( wxVERTICAL ); + + m_panelMain = new wxPanel( m_scrolledWindow, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer69; + bSizer69 = new wxBoxSizer( wxVERTICAL ); + + + bSizer69->Add( 0, 16, 0, wxEXPAND, 5 ); + + m_staticText32 = new wxStaticText( m_panelMain, wxID_ANY, _("Optional transaction fee you give to the nodes that process your transactions."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText32->Wrap( -1 ); + m_staticText32->Hide(); + + bSizer69->Add( m_staticText32, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxBoxSizer* bSizer56; + bSizer56 = new wxBoxSizer( wxHORIZONTAL ); + + m_staticText31 = new wxStaticText( m_panelMain, wxID_ANY, _("Transaction fee:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText31->Wrap( -1 ); + m_staticText31->Hide(); + + bSizer56->Add( m_staticText31, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 ); + + m_textCtrlTransactionFee = new wxTextCtrl( m_panelMain, wxID_TRANSACTIONFEE, wxEmptyString, wxDefaultPosition, wxSize( 70,-1 ), 0 ); + m_textCtrlTransactionFee->Hide(); + + bSizer56->Add( m_textCtrlTransactionFee, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + bSizer69->Add( bSizer56, 0, wxEXPAND, 5 ); + + wxBoxSizer* bSizer71; + bSizer71 = new wxBoxSizer( wxHORIZONTAL ); + + m_checkBoxLimitProcessors = new wxCheckBox( m_panelMain, wxID_ANY, _("&Limit coin generation to"), wxDefaultPosition, wxDefaultSize, 0 ); + + bSizer71->Add( m_checkBoxLimitProcessors, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + m_spinCtrlLimitProcessors = new wxSpinCtrl( m_panelMain, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 48,-1 ), wxSP_ARROW_KEYS, 1, 999, 1 ); + bSizer71->Add( m_spinCtrlLimitProcessors, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + m_staticText35 = new wxStaticText( m_panelMain, wxID_ANY, _("processors"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText35->Wrap( -1 ); + bSizer71->Add( m_staticText35, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + bSizer69->Add( bSizer71, 0, 0, 5 ); + + m_checkBoxStartOnSystemStartup = new wxCheckBox( m_panelMain, wxID_ANY, _("&Start Bitcoin on system startup"), wxDefaultPosition, wxDefaultSize, 0 ); + + bSizer69->Add( m_checkBoxStartOnSystemStartup, 0, wxALL, 5 ); + + m_checkBoxMinimizeToTray = new wxCheckBox( m_panelMain, wxID_ANY, _("&Minimize to the tray instead of the taskbar"), wxDefaultPosition, wxDefaultSize, 0 ); + + bSizer69->Add( m_checkBoxMinimizeToTray, 0, wxALL, 5 ); + + m_checkBoxMinimizeOnClose = new wxCheckBox( m_panelMain, wxID_ANY, _("M&inimize to the tray on close"), wxDefaultPosition, wxDefaultSize, 0 ); + + bSizer69->Add( m_checkBoxMinimizeOnClose, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + wxBoxSizer* bSizer102; + bSizer102 = new wxBoxSizer( wxHORIZONTAL ); + + m_checkBoxUseProxy = new wxCheckBox( m_panelMain, wxID_ANY, _("&Connect through socks4 proxy: "), wxDefaultPosition, wxDefaultSize, 0 ); + + bSizer102->Add( m_checkBoxUseProxy, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + bSizer69->Add( bSizer102, 1, wxEXPAND, 5 ); + + wxBoxSizer* bSizer103; + bSizer103 = new wxBoxSizer( wxHORIZONTAL ); + + + bSizer103->Add( 18, 0, 0, 0, 5 ); + + m_staticTextProxyIP = new wxStaticText( m_panelMain, wxID_ANY, _("Proxy &IP:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextProxyIP->Wrap( -1 ); + bSizer103->Add( m_staticTextProxyIP, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlProxyIP = new wxTextCtrl( m_panelMain, wxID_PROXYIP, wxEmptyString, wxDefaultPosition, wxSize( 140,-1 ), 0 ); + m_textCtrlProxyIP->SetMaxLength( 15 ); + bSizer103->Add( m_textCtrlProxyIP, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + m_staticTextProxyPort = new wxStaticText( m_panelMain, wxID_ANY, _(" &Port:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextProxyPort->Wrap( -1 ); + bSizer103->Add( m_staticTextProxyPort, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlProxyPort = new wxTextCtrl( m_panelMain, wxID_PROXYPORT, wxEmptyString, wxDefaultPosition, wxSize( 55,-1 ), 0 ); + m_textCtrlProxyPort->SetMaxLength( 5 ); + bSizer103->Add( m_textCtrlProxyPort, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + bSizer69->Add( bSizer103, 1, wxEXPAND, 5 ); + + m_panelMain->SetSizer( bSizer69 ); + m_panelMain->Layout(); + bSizer69->Fit( m_panelMain ); + bSizer63->Add( m_panelMain, 0, wxEXPAND, 5 ); + + m_panelTest2 = new wxPanel( m_scrolledWindow, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer64; + bSizer64 = new wxBoxSizer( wxVERTICAL ); + + + bSizer64->Add( 0, 16, 0, wxEXPAND, 5 ); + + m_staticText321 = new wxStaticText( m_panelTest2, wxID_ANY, _("// [don't translate] Test panel 2 for future expansion"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText321->Wrap( -1 ); + bSizer64->Add( m_staticText321, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + m_staticText69 = new wxStaticText( m_panelTest2, wxID_ANY, _("// [don't translate] Let's not start multiple pages until the first page is filled up"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText69->Wrap( -1 ); + bSizer64->Add( m_staticText69, 0, wxALL, 5 ); + + m_panelTest2->SetSizer( bSizer64 ); + m_panelTest2->Layout(); + bSizer64->Fit( m_panelTest2 ); + bSizer63->Add( m_panelTest2, 0, wxEXPAND, 5 ); + + m_scrolledWindow->SetSizer( bSizer63 ); + m_scrolledWindow->Layout(); + bSizer63->Fit( m_scrolledWindow ); + bSizer66->Add( m_scrolledWindow, 1, wxEXPAND|wxLEFT, 5 ); + + bSizer55->Add( bSizer66, 1, wxEXPAND|wxALL, 9 ); + + wxBoxSizer* bSizer58; + bSizer58 = new wxBoxSizer( wxHORIZONTAL ); + + m_buttonOK = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + bSizer58->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + m_buttonCancel = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + bSizer58->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + m_buttonApply = new wxButton( this, wxID_APPLY, _("&Apply"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + bSizer58->Add( m_buttonApply, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + bSizer55->Add( bSizer58, 0, wxALIGN_RIGHT, 5 ); + + this->SetSizer( bSizer55 ); + this->Layout(); + + // Connect Events + m_listBox->Connect( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( COptionsDialogBase::OnListBox ), NULL, this ); + m_textCtrlTransactionFee->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusTransactionFee ), NULL, this ); + m_checkBoxLimitProcessors->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxLimitProcessors ), NULL, this ); + m_checkBoxMinimizeToTray->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxMinimizeToTray ), NULL, this ); + m_checkBoxUseProxy->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxUseProxy ), NULL, this ); + m_textCtrlProxyIP->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusProxy ), NULL, this ); + m_textCtrlProxyPort->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusProxy ), NULL, this ); + m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonOK ), NULL, this ); + m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonCancel ), NULL, this ); + m_buttonApply->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonApply ), NULL, this ); +} + +COptionsDialogBase::~COptionsDialogBase() +{ + // Disconnect Events + m_listBox->Disconnect( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( COptionsDialogBase::OnListBox ), NULL, this ); + m_textCtrlTransactionFee->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusTransactionFee ), NULL, this ); + m_checkBoxLimitProcessors->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxLimitProcessors ), NULL, this ); + m_checkBoxMinimizeToTray->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxMinimizeToTray ), NULL, this ); + m_checkBoxUseProxy->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxUseProxy ), NULL, this ); + m_textCtrlProxyIP->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusProxy ), NULL, this ); + m_textCtrlProxyPort->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusProxy ), NULL, this ); + m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonOK ), NULL, this ); + m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonCancel ), NULL, this ); + m_buttonApply->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonApply ), NULL, this ); +} + +CAboutDialogBase::CAboutDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer63; + bSizer63 = new wxBoxSizer( wxHORIZONTAL ); + + m_bitmap = new wxStaticBitmap( this, wxID_ANY, wxBitmap( about_xpm ), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer63->Add( m_bitmap, 0, 0, 5 ); + + wxBoxSizer* bSizer60; + bSizer60 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer62; + bSizer62 = new wxBoxSizer( wxHORIZONTAL ); + + wxBoxSizer* bSizer631; + bSizer631 = new wxBoxSizer( wxVERTICAL ); + + + bSizer631->Add( 0, 65, 0, wxEXPAND, 5 ); + + wxBoxSizer* bSizer64; + bSizer64 = new wxBoxSizer( wxHORIZONTAL ); + + m_staticText40 = new wxStaticText( this, wxID_ANY, _("Bitcoin "), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText40->Wrap( -1 ); + m_staticText40->SetFont( wxFont( 10, 74, 90, 92, false, wxT("Tahoma") ) ); + + bSizer64->Add( m_staticText40, 0, wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxLEFT, 5 ); + + m_staticTextVersion = new wxStaticText( this, wxID_ANY, _("version"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextVersion->Wrap( -1 ); + m_staticTextVersion->SetFont( wxFont( 10, 74, 90, 90, false, wxT("Tahoma") ) ); + + bSizer64->Add( m_staticTextVersion, 0, wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxRIGHT, 5 ); + + bSizer631->Add( bSizer64, 0, wxEXPAND, 5 ); + + + bSizer631->Add( 0, 4, 0, wxEXPAND, 5 ); + + m_staticTextMain = new wxStaticText( this, wxID_ANY, _("Copyright (c) 2009-2010 Satoshi Nakamoto.\n\nThis is experimental software.\n\nDistributed under the MIT/X11 software license, see the accompanying file \nlicense.txt or http://www.opensource.org/licenses/mit-license.php.\n\nThis product includes software developed by the OpenSSL Project for use in the \nOpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by \nEric Young (eay@cryptsoft.com)."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextMain->Wrap( -1 ); + bSizer631->Add( m_staticTextMain, 0, wxALL, 5 ); + + + bSizer631->Add( 0, 0, 0, wxEXPAND, 5 ); + + bSizer62->Add( bSizer631, 1, wxEXPAND, 5 ); + + bSizer60->Add( bSizer62, 1, wxEXPAND, 5 ); + + wxBoxSizer* bSizer61; + bSizer61 = new wxBoxSizer( wxHORIZONTAL ); + + + bSizer61->Add( 0, 0, 1, wxEXPAND, 5 ); + + m_buttonOK = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + bSizer61->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 6 ); + + bSizer60->Add( bSizer61, 0, wxALIGN_RIGHT|wxEXPAND|wxRIGHT, 2 ); + + bSizer63->Add( bSizer60, 1, wxEXPAND|wxLEFT, 5 ); + + this->SetSizer( bSizer63 ); + this->Layout(); + + // Connect Events + m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAboutDialogBase::OnButtonOK ), NULL, this ); +} + +CAboutDialogBase::~CAboutDialogBase() +{ + // Disconnect Events + m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAboutDialogBase::OnButtonOK ), NULL, this ); +} + +CSendDialogBase::CSendDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer21; + bSizer21 = new wxBoxSizer( wxVERTICAL ); + + + bSizer21->Add( 0, 5, 0, wxEXPAND, 5 ); + + wxFlexGridSizer* fgSizer1; + fgSizer1 = new wxFlexGridSizer( 0, 2, 0, 0 ); + fgSizer1->AddGrowableCol( 1 ); + fgSizer1->SetFlexibleDirection( wxBOTH ); + fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + + + fgSizer1->Add( 0, 0, 0, wxEXPAND, 5 ); + + m_staticTextInstructions = new wxStaticText( this, wxID_ANY, _("Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJED9L) or IP address (e.g. 123.45.6.7)"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextInstructions->Wrap( -1 ); + fgSizer1->Add( m_staticTextInstructions, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + + wxBoxSizer* bSizer47; + bSizer47 = new wxBoxSizer( wxHORIZONTAL ); + + bSizer47->SetMinSize( wxSize( 70,-1 ) ); + + bSizer47->Add( 0, 0, 1, wxEXPAND, 5 ); + + m_bitmapCheckMark = new wxStaticBitmap( this, wxID_ANY, wxBitmap( check_xpm ), wxDefaultPosition, wxSize( 16,16 ), 0 ); + bSizer47->Add( m_bitmapCheckMark, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_staticText36 = new wxStaticText( this, wxID_ANY, _("Pay &To:"), wxDefaultPosition, wxSize( -1,-1 ), wxALIGN_RIGHT ); + m_staticText36->Wrap( -1 ); + bSizer47->Add( m_staticText36, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 ); + + fgSizer1->Add( bSizer47, 1, wxEXPAND|wxLEFT, 5 ); + + wxBoxSizer* bSizer19; + bSizer19 = new wxBoxSizer( wxHORIZONTAL ); + + m_textCtrlAddress = new wxTextCtrl( this, wxID_TEXTCTRLPAYTO, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + bSizer19->Add( m_textCtrlAddress, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxBoxSizer* bSizer66; + bSizer66 = new wxBoxSizer( wxHORIZONTAL ); + + m_buttonPaste = new wxButton( this, wxID_BUTTONPASTE, _("&Paste"), wxDefaultPosition, wxSize( -1,-1 ), wxBU_EXACTFIT ); + bSizer66->Add( m_buttonPaste, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxEXPAND, 5 ); + + m_buttonAddress = new wxButton( this, wxID_BUTTONADDRESSBOOK, _(" Address &Book..."), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer66->Add( m_buttonAddress, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxEXPAND, 5 ); + + bSizer19->Add( bSizer66, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + fgSizer1->Add( bSizer19, 1, wxEXPAND|wxRIGHT, 5 ); + + m_staticText19 = new wxStaticText( this, wxID_ANY, _("&Amount:"), wxDefaultPosition, wxSize( -1,-1 ), wxALIGN_RIGHT ); + m_staticText19->Wrap( -1 ); + fgSizer1->Add( m_staticText19, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT|wxALIGN_RIGHT, 5 ); + + m_textCtrlAmount = new wxTextCtrl( this, wxID_TEXTCTRLAMOUNT, wxEmptyString, wxDefaultPosition, wxSize( 145,-1 ), 0 ); + m_textCtrlAmount->SetMaxLength( 20 ); + m_textCtrlAmount->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxEmptyString ) ); + + fgSizer1->Add( m_textCtrlAmount, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + m_staticText20 = new wxStaticText( this, wxID_ANY, _("T&ransfer:"), wxDefaultPosition, wxSize( -1,-1 ), wxALIGN_RIGHT ); + m_staticText20->Wrap( -1 ); + m_staticText20->Hide(); + + fgSizer1->Add( m_staticText20, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5 ); + + wxString m_choiceTransferTypeChoices[] = { _(" Standard") }; + int m_choiceTransferTypeNChoices = sizeof( m_choiceTransferTypeChoices ) / sizeof( wxString ); + m_choiceTransferType = new wxChoice( this, wxID_CHOICETRANSFERTYPE, wxDefaultPosition, wxDefaultSize, m_choiceTransferTypeNChoices, m_choiceTransferTypeChoices, 0 ); + m_choiceTransferType->SetSelection( 0 ); + m_choiceTransferType->Hide(); + + fgSizer1->Add( m_choiceTransferType, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + + fgSizer1->Add( 0, 3, 0, wxEXPAND, 5 ); + + + fgSizer1->Add( 0, 0, 0, wxEXPAND, 5 ); + + bSizer21->Add( fgSizer1, 0, wxEXPAND|wxLEFT, 5 ); + + wxBoxSizer* bSizer672; + bSizer672 = new wxBoxSizer( wxHORIZONTAL ); + + wxBoxSizer* bSizer681; + bSizer681 = new wxBoxSizer( wxVERTICAL ); + + m_staticTextFrom = new wxStaticText( this, wxID_ANY, _("&From:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextFrom->Wrap( -1 ); + bSizer681->Add( m_staticTextFrom, 0, wxBOTTOM|wxLEFT, 5 ); + + m_textCtrlFrom = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + bSizer681->Add( m_textCtrlFrom, 0, wxLEFT|wxEXPAND, 5 ); + + bSizer672->Add( bSizer681, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + bSizer21->Add( bSizer672, 0, wxEXPAND, 5 ); + + wxBoxSizer* bSizer67; + bSizer67 = new wxBoxSizer( wxHORIZONTAL ); + + wxBoxSizer* bSizer68; + bSizer68 = new wxBoxSizer( wxVERTICAL ); + + m_staticTextMessage = new wxStaticText( this, wxID_ANY, _("&Message:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextMessage->Wrap( -1 ); + bSizer68->Add( m_staticTextMessage, 0, wxTOP|wxBOTTOM|wxLEFT, 5 ); + + m_textCtrlMessage = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE ); + bSizer68->Add( m_textCtrlMessage, 1, wxEXPAND|wxLEFT, 5 ); + + bSizer67->Add( bSizer68, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + bSizer21->Add( bSizer67, 1, wxEXPAND, 5 ); + + wxBoxSizer* bSizer23; + bSizer23 = new wxBoxSizer( wxHORIZONTAL ); + + + bSizer23->Add( 0, 0, 1, wxEXPAND, 5 ); + + m_buttonSend = new wxButton( this, wxID_BUTTONSEND, _("&Send"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + m_buttonSend->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxEmptyString ) ); + + bSizer23->Add( m_buttonSend, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + m_buttonCancel = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + bSizer23->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + bSizer21->Add( bSizer23, 0, wxEXPAND, 5 ); + + this->SetSizer( bSizer21 ); + this->Layout(); + + // Connect Events + m_textCtrlAddress->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CSendDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlAddress->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( CSendDialogBase::OnTextAddress ), NULL, this ); + m_buttonPaste->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendDialogBase::OnButtonPaste ), NULL, this ); + m_buttonAddress->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendDialogBase::OnButtonAddressBook ), NULL, this ); + m_textCtrlAmount->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CSendDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlAmount->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( CSendDialogBase::OnKillFocusAmount ), NULL, this ); + m_textCtrlFrom->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CSendDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlMessage->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CSendDialogBase::OnKeyDown ), NULL, this ); + m_buttonSend->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendDialogBase::OnButtonSend ), NULL, this ); + m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendDialogBase::OnButtonCancel ), NULL, this ); +} + +CSendDialogBase::~CSendDialogBase() +{ + // Disconnect Events + m_textCtrlAddress->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CSendDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlAddress->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( CSendDialogBase::OnTextAddress ), NULL, this ); + m_buttonPaste->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendDialogBase::OnButtonPaste ), NULL, this ); + m_buttonAddress->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendDialogBase::OnButtonAddressBook ), NULL, this ); + m_textCtrlAmount->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CSendDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlAmount->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( CSendDialogBase::OnKillFocusAmount ), NULL, this ); + m_textCtrlFrom->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CSendDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlMessage->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CSendDialogBase::OnKeyDown ), NULL, this ); + m_buttonSend->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendDialogBase::OnButtonSend ), NULL, this ); + m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendDialogBase::OnButtonCancel ), NULL, this ); +} + +CSendingDialogBase::CSendingDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer68; + bSizer68 = new wxBoxSizer( wxVERTICAL ); + + m_staticTextSending = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,14 ), 0 ); + m_staticTextSending->Wrap( -1 ); + bSizer68->Add( m_staticTextSending, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 8 ); + + m_textCtrlStatus = new wxTextCtrl( this, wxID_ANY, _("\n\nConnecting..."), wxDefaultPosition, wxDefaultSize, wxTE_CENTRE|wxTE_MULTILINE|wxTE_NO_VSCROLL|wxTE_READONLY|wxNO_BORDER ); + m_textCtrlStatus->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) ); + + bSizer68->Add( m_textCtrlStatus, 1, wxEXPAND|wxRIGHT|wxLEFT, 10 ); + + wxBoxSizer* bSizer69; + bSizer69 = new wxBoxSizer( wxHORIZONTAL ); + + + bSizer69->Add( 0, 0, 1, wxEXPAND, 5 ); + + m_buttonOK = new wxButton( this, wxID_ANY, _("OK"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonOK->Enable( false ); + + bSizer69->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + m_buttonCancel = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + bSizer69->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + bSizer68->Add( bSizer69, 0, wxEXPAND, 5 ); + + this->SetSizer( bSizer68 ); + this->Layout(); + + // Connect Events + this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CSendingDialogBase::OnClose ) ); + this->Connect( wxEVT_PAINT, wxPaintEventHandler( CSendingDialogBase::OnPaint ) ); + m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendingDialogBase::OnButtonOK ), NULL, this ); + m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendingDialogBase::OnButtonCancel ), NULL, this ); +} + +CSendingDialogBase::~CSendingDialogBase() +{ + // Disconnect Events + this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CSendingDialogBase::OnClose ) ); + this->Disconnect( wxEVT_PAINT, wxPaintEventHandler( CSendingDialogBase::OnPaint ) ); + m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendingDialogBase::OnButtonOK ), NULL, this ); + m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendingDialogBase::OnButtonCancel ), NULL, this ); +} + +CYourAddressDialogBase::CYourAddressDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer68; + bSizer68 = new wxBoxSizer( wxVERTICAL ); + + + bSizer68->Add( 0, 5, 0, wxEXPAND, 5 ); + + m_staticText45 = new wxStaticText( this, wxID_ANY, _("These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. The highlighted address is displayed in the main window."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText45->Wrap( 590 ); + bSizer68->Add( m_staticText45, 0, wxALL, 5 ); + + m_listCtrl = new wxListCtrl( this, wxID_LISTCTRL, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING ); + bSizer68->Add( m_listCtrl, 1, wxALL|wxEXPAND, 5 ); + + wxBoxSizer* bSizer69; + bSizer69 = new wxBoxSizer( wxHORIZONTAL ); + + + bSizer69->Add( 0, 0, 1, wxEXPAND, 5 ); + + m_buttonRename = new wxButton( this, wxID_BUTTONRENAME, _("&Edit..."), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer69->Add( m_buttonRename, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + m_buttonNew = new wxButton( this, wxID_BUTTONNEW, _(" &New Address... "), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + bSizer69->Add( m_buttonNew, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + m_buttonCopy = new wxButton( this, wxID_BUTTONCOPY, _(" &Copy to Clipboard "), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + bSizer69->Add( m_buttonCopy, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + m_buttonOK = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer69->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + m_buttonCancel = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + m_buttonCancel->Hide(); + + bSizer69->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + bSizer68->Add( bSizer69, 0, wxEXPAND, 5 ); + + this->SetSizer( bSizer68 ); + this->Layout(); + + // Connect Events + this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CYourAddressDialogBase::OnClose ) ); + m_listCtrl->Connect( wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler( CYourAddressDialogBase::OnListEndLabelEdit ), NULL, this ); + m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CYourAddressDialogBase::OnListItemActivated ), NULL, this ); + m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CYourAddressDialogBase::OnListItemSelected ), NULL, this ); + m_buttonRename->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CYourAddressDialogBase::OnButtonRename ), NULL, this ); + m_buttonNew->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CYourAddressDialogBase::OnButtonNew ), NULL, this ); + m_buttonCopy->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CYourAddressDialogBase::OnButtonCopy ), NULL, this ); + m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CYourAddressDialogBase::OnButtonOK ), NULL, this ); + m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CYourAddressDialogBase::OnButtonCancel ), NULL, this ); +} + +CYourAddressDialogBase::~CYourAddressDialogBase() +{ + // Disconnect Events + this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CYourAddressDialogBase::OnClose ) ); + m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler( CYourAddressDialogBase::OnListEndLabelEdit ), NULL, this ); + m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CYourAddressDialogBase::OnListItemActivated ), NULL, this ); + m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CYourAddressDialogBase::OnListItemSelected ), NULL, this ); + m_buttonRename->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CYourAddressDialogBase::OnButtonRename ), NULL, this ); + m_buttonNew->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CYourAddressDialogBase::OnButtonNew ), NULL, this ); + m_buttonCopy->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CYourAddressDialogBase::OnButtonCopy ), NULL, this ); + m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CYourAddressDialogBase::OnButtonOK ), NULL, this ); + m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CYourAddressDialogBase::OnButtonCancel ), NULL, this ); +} + +CAddressBookDialogBase::CAddressBookDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer58; + bSizer58 = new wxBoxSizer( wxVERTICAL ); + + m_notebook = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); + m_panelSending = new wxPanel( m_notebook, wxID_PANELSENDING, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer68; + bSizer68 = new wxBoxSizer( wxVERTICAL ); + + + bSizer68->Add( 0, 0, 0, wxEXPAND, 5 ); + + m_staticText55 = new wxStaticText( m_panelSending, wxID_ANY, _("Bitcoin Address"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText55->Wrap( -1 ); + m_staticText55->Hide(); + + bSizer68->Add( m_staticText55, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + + m_listCtrlSending = new wxListCtrl( m_panelSending, wxID_LISTCTRLSENDING, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING ); + bSizer68->Add( m_listCtrlSending, 1, wxALL|wxEXPAND, 5 ); + + m_panelSending->SetSizer( bSizer68 ); + m_panelSending->Layout(); + bSizer68->Fit( m_panelSending ); + m_notebook->AddPage( m_panelSending, _("Sending"), false ); + m_panelReceiving = new wxPanel( m_notebook, wxID_PANELRECEIVING, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer681; + bSizer681 = new wxBoxSizer( wxVERTICAL ); + + + bSizer681->Add( 0, 0, 0, wxEXPAND, 5 ); + + m_staticText45 = new wxStaticText( m_panelReceiving, wxID_ANY, _("These are your Bitcoin addresses for receiving payments. You can give a different one to each sender to keep track of who is paying you. The highlighted address will be displayed in the main window."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText45->Wrap( 570 ); + bSizer681->Add( m_staticText45, 0, wxTOP|wxRIGHT|wxLEFT, 6 ); + + + bSizer681->Add( 0, 2, 0, wxEXPAND, 5 ); + + m_listCtrlReceiving = new wxListCtrl( m_panelReceiving, wxID_LISTCTRLRECEIVING, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING ); + bSizer681->Add( m_listCtrlReceiving, 1, wxALL|wxEXPAND, 5 ); + + m_panelReceiving->SetSizer( bSizer681 ); + m_panelReceiving->Layout(); + bSizer681->Fit( m_panelReceiving ); + m_notebook->AddPage( m_panelReceiving, _("Receiving"), true ); + + bSizer58->Add( m_notebook, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); + + wxBoxSizer* bSizer69; + bSizer69 = new wxBoxSizer( wxHORIZONTAL ); + + + bSizer69->Add( 0, 0, 1, wxEXPAND, 5 ); + + m_buttonDelete = new wxButton( this, wxID_BUTTONDELETE, _("&Delete"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer69->Add( m_buttonDelete, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + m_buttonCopy = new wxButton( this, wxID_BUTTONCOPY, _(" &Copy to Clipboard "), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + bSizer69->Add( m_buttonCopy, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + m_buttonEdit = new wxButton( this, wxID_BUTTONEDIT, _("&Edit..."), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer69->Add( m_buttonEdit, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + m_buttonNew = new wxButton( this, wxID_BUTTONNEW, _(" &New Address... "), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer69->Add( m_buttonNew, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + m_buttonOK = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + bSizer69->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + m_buttonCancel = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + bSizer69->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + bSizer58->Add( bSizer69, 0, wxEXPAND, 5 ); + + this->SetSizer( bSizer58 ); + this->Layout(); + + // Connect Events + this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CAddressBookDialogBase::OnClose ) ); + m_notebook->Connect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( CAddressBookDialogBase::OnNotebookPageChanged ), NULL, this ); + m_listCtrlSending->Connect( wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler( CAddressBookDialogBase::OnListEndLabelEdit ), NULL, this ); + m_listCtrlSending->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CAddressBookDialogBase::OnListItemActivated ), NULL, this ); + m_listCtrlSending->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CAddressBookDialogBase::OnListItemSelected ), NULL, this ); + m_listCtrlReceiving->Connect( wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler( CAddressBookDialogBase::OnListEndLabelEdit ), NULL, this ); + m_listCtrlReceiving->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CAddressBookDialogBase::OnListItemActivated ), NULL, this ); + m_listCtrlReceiving->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CAddressBookDialogBase::OnListItemSelected ), NULL, this ); + m_buttonDelete->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonDelete ), NULL, this ); + m_buttonCopy->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonCopy ), NULL, this ); + m_buttonEdit->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonEdit ), NULL, this ); + m_buttonNew->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonNew ), NULL, this ); + m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonOK ), NULL, this ); + m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonCancel ), NULL, this ); +} + +CAddressBookDialogBase::~CAddressBookDialogBase() +{ + // Disconnect Events + this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CAddressBookDialogBase::OnClose ) ); + m_notebook->Disconnect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( CAddressBookDialogBase::OnNotebookPageChanged ), NULL, this ); + m_listCtrlSending->Disconnect( wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler( CAddressBookDialogBase::OnListEndLabelEdit ), NULL, this ); + m_listCtrlSending->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CAddressBookDialogBase::OnListItemActivated ), NULL, this ); + m_listCtrlSending->Disconnect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CAddressBookDialogBase::OnListItemSelected ), NULL, this ); + m_listCtrlReceiving->Disconnect( wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler( CAddressBookDialogBase::OnListEndLabelEdit ), NULL, this ); + m_listCtrlReceiving->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CAddressBookDialogBase::OnListItemActivated ), NULL, this ); + m_listCtrlReceiving->Disconnect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CAddressBookDialogBase::OnListItemSelected ), NULL, this ); + m_buttonDelete->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonDelete ), NULL, this ); + m_buttonCopy->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonCopy ), NULL, this ); + m_buttonEdit->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonEdit ), NULL, this ); + m_buttonNew->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonNew ), NULL, this ); + m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonOK ), NULL, this ); + m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonCancel ), NULL, this ); +} + +CGetTextFromUserDialogBase::CGetTextFromUserDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer79; + bSizer79 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer81; + bSizer81 = new wxBoxSizer( wxVERTICAL ); + + + bSizer81->Add( 0, 0, 1, wxEXPAND, 5 ); + + m_staticTextMessage1 = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextMessage1->Wrap( -1 ); + bSizer81->Add( m_staticTextMessage1, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + + m_textCtrl1 = new wxTextCtrl( this, wxID_TEXTCTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER ); + bSizer81->Add( m_textCtrl1, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL, 5 ); + + m_staticTextMessage2 = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextMessage2->Wrap( -1 ); + m_staticTextMessage2->Hide(); + + bSizer81->Add( m_staticTextMessage2, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + + m_textCtrl2 = new wxTextCtrl( this, wxID_TEXTCTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER ); + m_textCtrl2->Hide(); + + bSizer81->Add( m_textCtrl2, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL, 5 ); + + + bSizer81->Add( 0, 0, 1, wxEXPAND, 5 ); + + bSizer79->Add( bSizer81, 1, wxEXPAND|wxALL, 10 ); + + wxBoxSizer* bSizer80; + bSizer80 = new wxBoxSizer( wxHORIZONTAL ); + + + bSizer80->Add( 0, 0, 1, wxEXPAND, 5 ); + + m_buttonOK = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + bSizer80->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + m_buttonCancel = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer80->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + bSizer79->Add( bSizer80, 0, wxEXPAND, 5 ); + + this->SetSizer( bSizer79 ); + this->Layout(); + + // Connect Events + this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CGetTextFromUserDialogBase::OnClose ) ); + m_textCtrl1->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CGetTextFromUserDialogBase::OnKeyDown ), NULL, this ); + m_textCtrl2->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CGetTextFromUserDialogBase::OnKeyDown ), NULL, this ); + m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CGetTextFromUserDialogBase::OnButtonOK ), NULL, this ); + m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CGetTextFromUserDialogBase::OnButtonCancel ), NULL, this ); +} + +CGetTextFromUserDialogBase::~CGetTextFromUserDialogBase() +{ + // Disconnect Events + this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CGetTextFromUserDialogBase::OnClose ) ); + m_textCtrl1->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CGetTextFromUserDialogBase::OnKeyDown ), NULL, this ); + m_textCtrl2->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CGetTextFromUserDialogBase::OnKeyDown ), NULL, this ); + m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CGetTextFromUserDialogBase::OnButtonOK ), NULL, this ); + m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CGetTextFromUserDialogBase::OnButtonCancel ), NULL, this ); +} @@ -1,422 +1,422 @@ -///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version Apr 16 2008)
-// http://www.wxformbuilder.org/
-//
-// PLEASE DO "NOT" EDIT THIS FILE!
-///////////////////////////////////////////////////////////////////////////
-
-#ifndef __uibase__
-#define __uibase__
-
-#include <wx/intl.h>
-
-#include <wx/string.h>
-#include <wx/bitmap.h>
-#include <wx/image.h>
-#include <wx/icon.h>
-#include <wx/menu.h>
-#include <wx/gdicmn.h>
-#include <wx/font.h>
-#include <wx/colour.h>
-#include <wx/settings.h>
-#include <wx/toolbar.h>
-#include <wx/statusbr.h>
-#include <wx/stattext.h>
-#include <wx/textctrl.h>
-#include <wx/button.h>
-#include <wx/sizer.h>
-#include <wx/choice.h>
-#include <wx/listctrl.h>
-#include <wx/panel.h>
-#include <wx/notebook.h>
-#include <wx/frame.h>
-#include <wx/html/htmlwin.h>
-#include <wx/dialog.h>
-#include <wx/listbox.h>
-#include <wx/checkbox.h>
-#include <wx/spinctrl.h>
-#include <wx/scrolwin.h>
-#include <wx/statbmp.h>
-
-///////////////////////////////////////////////////////////////////////////
-
-#define wxID_MAINFRAME 1000
-#define wxID_OPTIONSGENERATEBITCOINS 1001
-#define wxID_BUTTONSEND 1002
-#define wxID_BUTTONRECEIVE 1003
-#define wxID_TEXTCTRLADDRESS 1004
-#define wxID_BUTTONNEW 1005
-#define wxID_BUTTONCOPY 1006
-#define wxID_TRANSACTIONFEE 1007
-#define wxID_PROXYIP 1008
-#define wxID_PROXYPORT 1009
-#define wxID_TEXTCTRLPAYTO 1010
-#define wxID_BUTTONPASTE 1011
-#define wxID_BUTTONADDRESSBOOK 1012
-#define wxID_TEXTCTRLAMOUNT 1013
-#define wxID_CHOICETRANSFERTYPE 1014
-#define wxID_LISTCTRL 1015
-#define wxID_BUTTONRENAME 1016
-#define wxID_PANELSENDING 1017
-#define wxID_LISTCTRLSENDING 1018
-#define wxID_PANELRECEIVING 1019
-#define wxID_LISTCTRLRECEIVING 1020
-#define wxID_BUTTONDELETE 1021
-#define wxID_BUTTONEDIT 1022
-#define wxID_TEXTCTRL 1023
-
-///////////////////////////////////////////////////////////////////////////////
-/// Class CMainFrameBase
-///////////////////////////////////////////////////////////////////////////////
-class CMainFrameBase : public wxFrame
-{
- private:
-
- protected:
- wxMenuBar* m_menubar;
- wxMenu* m_menuFile;
- wxMenu* m_menuHelp;
- wxToolBar* m_toolBar;
-
- wxStaticText* m_staticText32;
- wxButton* m_buttonNew;
- wxButton* m_buttonCopy;
-
- wxStaticText* m_staticText41;
- wxStaticText* m_staticTextBalance;
-
- wxChoice* m_choiceFilter;
- wxNotebook* m_notebook;
- wxPanel* m_panel9;
- wxPanel* m_panel91;
- wxPanel* m_panel92;
- wxPanel* m_panel93;
-
- // Virtual event handlers, overide them in your derived class
- virtual void OnClose( wxCloseEvent& event ){ event.Skip(); }
- virtual void OnIconize( wxIconizeEvent& event ){ event.Skip(); }
- virtual void OnIdle( wxIdleEvent& event ){ event.Skip(); }
- virtual void OnMouseEvents( wxMouseEvent& event ){ event.Skip(); }
- virtual void OnPaint( wxPaintEvent& event ){ event.Skip(); }
- virtual void OnMenuFileExit( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnMenuOptionsGenerate( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnUpdateUIOptionsGenerate( wxUpdateUIEvent& event ){ event.Skip(); }
- virtual void OnMenuOptionsChangeYourAddress( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnMenuOptionsOptions( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnMenuHelpAbout( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnButtonSend( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnButtonAddressBook( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnKeyDown( wxKeyEvent& event ){ event.Skip(); }
- virtual void OnMouseEventsAddress( wxMouseEvent& event ){ event.Skip(); }
- virtual void OnSetFocusAddress( wxFocusEvent& event ){ event.Skip(); }
- virtual void OnButtonNew( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnButtonCopy( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnNotebookPageChanged( wxNotebookEvent& event ){ event.Skip(); }
- virtual void OnListColBeginDrag( wxListEvent& event ){ event.Skip(); }
- virtual void OnListItemActivated( wxListEvent& event ){ event.Skip(); }
- virtual void OnPaintListCtrl( wxPaintEvent& event ){ event.Skip(); }
-
-
- public:
- wxMenu* m_menuOptions;
- wxStatusBar* m_statusBar;
- wxTextCtrl* m_textCtrlAddress;
- wxListCtrl* m_listCtrlAll;
- wxListCtrl* m_listCtrlSentReceived;
- wxListCtrl* m_listCtrlSent;
- wxListCtrl* m_listCtrlReceived;
- CMainFrameBase( wxWindow* parent, wxWindowID id = wxID_MAINFRAME, const wxString& title = _("Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 723,484 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL );
- ~CMainFrameBase();
-
-};
-
-///////////////////////////////////////////////////////////////////////////////
-/// Class CTxDetailsDialogBase
-///////////////////////////////////////////////////////////////////////////////
-class CTxDetailsDialogBase : public wxDialog
-{
- private:
-
- protected:
- wxHtmlWindow* m_htmlWin;
- wxButton* m_buttonOK;
-
- // Virtual event handlers, overide them in your derived class
- virtual void OnButtonOK( wxCommandEvent& event ){ event.Skip(); }
-
-
- public:
- CTxDetailsDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Transaction Details"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 620,450 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
- ~CTxDetailsDialogBase();
-
-};
-
-///////////////////////////////////////////////////////////////////////////////
-/// Class COptionsDialogBase
-///////////////////////////////////////////////////////////////////////////////
-class COptionsDialogBase : public wxDialog
-{
- private:
-
- protected:
- wxListBox* m_listBox;
- wxScrolledWindow* m_scrolledWindow;
- wxPanel* m_panelMain;
-
- wxStaticText* m_staticText32;
- wxStaticText* m_staticText31;
- wxTextCtrl* m_textCtrlTransactionFee;
- wxCheckBox* m_checkBoxLimitProcessors;
- wxSpinCtrl* m_spinCtrlLimitProcessors;
- wxStaticText* m_staticText35;
- wxCheckBox* m_checkBoxStartOnSystemStartup;
- wxCheckBox* m_checkBoxMinimizeToTray;
- wxCheckBox* m_checkBoxMinimizeOnClose;
- wxCheckBox* m_checkBoxUseProxy;
-
- wxStaticText* m_staticTextProxyIP;
- wxTextCtrl* m_textCtrlProxyIP;
- wxStaticText* m_staticTextProxyPort;
- wxTextCtrl* m_textCtrlProxyPort;
- wxPanel* m_panelTest2;
-
- wxStaticText* m_staticText321;
- wxStaticText* m_staticText69;
- wxButton* m_buttonOK;
- wxButton* m_buttonCancel;
- wxButton* m_buttonApply;
-
- // Virtual event handlers, overide them in your derived class
- virtual void OnListBox( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnKillFocusTransactionFee( wxFocusEvent& event ){ event.Skip(); }
- virtual void OnCheckBoxLimitProcessors( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnCheckBoxMinimizeToTray( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnCheckBoxUseProxy( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnKillFocusProxy( wxFocusEvent& event ){ event.Skip(); }
- virtual void OnButtonOK( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnButtonApply( wxCommandEvent& event ){ event.Skip(); }
-
-
- public:
- COptionsDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Options"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 540,360 ), long style = wxDEFAULT_DIALOG_STYLE );
- ~COptionsDialogBase();
-
-};
-
-///////////////////////////////////////////////////////////////////////////////
-/// Class CAboutDialogBase
-///////////////////////////////////////////////////////////////////////////////
-class CAboutDialogBase : public wxDialog
-{
- private:
-
- protected:
- wxStaticBitmap* m_bitmap;
-
- wxStaticText* m_staticText40;
-
- wxStaticText* m_staticTextMain;
-
-
- wxButton* m_buttonOK;
-
- // Virtual event handlers, overide them in your derived class
- virtual void OnButtonOK( wxCommandEvent& event ){ event.Skip(); }
-
-
- public:
- wxStaticText* m_staticTextVersion;
- CAboutDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("About Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 532,329 ), long style = wxDEFAULT_DIALOG_STYLE );
- ~CAboutDialogBase();
-
-};
-
-///////////////////////////////////////////////////////////////////////////////
-/// Class CSendDialogBase
-///////////////////////////////////////////////////////////////////////////////
-class CSendDialogBase : public wxDialog
-{
- private:
-
- protected:
-
-
- wxStaticText* m_staticTextInstructions;
-
- wxStaticBitmap* m_bitmapCheckMark;
- wxStaticText* m_staticText36;
- wxTextCtrl* m_textCtrlAddress;
- wxButton* m_buttonPaste;
- wxButton* m_buttonAddress;
- wxStaticText* m_staticText19;
- wxTextCtrl* m_textCtrlAmount;
- wxStaticText* m_staticText20;
- wxChoice* m_choiceTransferType;
-
-
- wxStaticText* m_staticTextFrom;
- wxTextCtrl* m_textCtrlFrom;
- wxStaticText* m_staticTextMessage;
- wxTextCtrl* m_textCtrlMessage;
-
- wxButton* m_buttonSend;
- wxButton* m_buttonCancel;
-
- // Virtual event handlers, overide them in your derived class
- virtual void OnKeyDown( wxKeyEvent& event ){ event.Skip(); }
- virtual void OnTextAddress( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnButtonPaste( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnButtonAddressBook( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnKillFocusAmount( wxFocusEvent& event ){ event.Skip(); }
- virtual void OnButtonSend( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); }
-
-
- public:
- CSendDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Send Coins"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 675,298 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
- ~CSendDialogBase();
-
-};
-
-///////////////////////////////////////////////////////////////////////////////
-/// Class CSendingDialogBase
-///////////////////////////////////////////////////////////////////////////////
-class CSendingDialogBase : public wxDialog
-{
- private:
-
- protected:
- wxStaticText* m_staticTextSending;
- wxTextCtrl* m_textCtrlStatus;
-
- wxButton* m_buttonOK;
- wxButton* m_buttonCancel;
-
- // Virtual event handlers, overide them in your derived class
- virtual void OnClose( wxCloseEvent& event ){ event.Skip(); }
- virtual void OnPaint( wxPaintEvent& event ){ event.Skip(); }
- virtual void OnButtonOK( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); }
-
-
- public:
- CSendingDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Sending..."), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 442,151 ), long style = wxDEFAULT_DIALOG_STYLE );
- ~CSendingDialogBase();
-
-};
-
-///////////////////////////////////////////////////////////////////////////////
-/// Class CYourAddressDialogBase
-///////////////////////////////////////////////////////////////////////////////
-class CYourAddressDialogBase : public wxDialog
-{
- private:
-
- protected:
-
- wxStaticText* m_staticText45;
- wxListCtrl* m_listCtrl;
-
- wxButton* m_buttonRename;
- wxButton* m_buttonNew;
- wxButton* m_buttonCopy;
- wxButton* m_buttonOK;
- wxButton* m_buttonCancel;
-
- // Virtual event handlers, overide them in your derived class
- virtual void OnClose( wxCloseEvent& event ){ event.Skip(); }
- virtual void OnListEndLabelEdit( wxListEvent& event ){ event.Skip(); }
- virtual void OnListItemActivated( wxListEvent& event ){ event.Skip(); }
- virtual void OnListItemSelected( wxListEvent& event ){ event.Skip(); }
- virtual void OnButtonRename( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnButtonNew( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnButtonCopy( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnButtonOK( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); }
-
-
- public:
- CYourAddressDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Your Bitcoin Addresses"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 610,390 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
- ~CYourAddressDialogBase();
-
-};
-
-///////////////////////////////////////////////////////////////////////////////
-/// Class CAddressBookDialogBase
-///////////////////////////////////////////////////////////////////////////////
-class CAddressBookDialogBase : public wxDialog
-{
- private:
-
- protected:
- wxNotebook* m_notebook;
- wxPanel* m_panelSending;
-
- wxStaticText* m_staticText55;
- wxListCtrl* m_listCtrlSending;
- wxPanel* m_panelReceiving;
-
- wxStaticText* m_staticText45;
-
- wxListCtrl* m_listCtrlReceiving;
-
- wxButton* m_buttonDelete;
- wxButton* m_buttonCopy;
- wxButton* m_buttonEdit;
- wxButton* m_buttonNew;
- wxButton* m_buttonOK;
-
- // Virtual event handlers, overide them in your derived class
- virtual void OnClose( wxCloseEvent& event ){ event.Skip(); }
- virtual void OnNotebookPageChanged( wxNotebookEvent& event ){ event.Skip(); }
- virtual void OnListEndLabelEdit( wxListEvent& event ){ event.Skip(); }
- virtual void OnListItemActivated( wxListEvent& event ){ event.Skip(); }
- virtual void OnListItemSelected( wxListEvent& event ){ event.Skip(); }
- virtual void OnButtonDelete( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnButtonCopy( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnButtonEdit( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnButtonNew( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnButtonOK( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); }
-
-
- public:
- wxButton* m_buttonCancel;
- CAddressBookDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Address Book"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 610,390 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
- ~CAddressBookDialogBase();
-
-};
-
-///////////////////////////////////////////////////////////////////////////////
-/// Class CGetTextFromUserDialogBase
-///////////////////////////////////////////////////////////////////////////////
-class CGetTextFromUserDialogBase : public wxDialog
-{
- private:
-
- protected:
-
- wxStaticText* m_staticTextMessage1;
- wxTextCtrl* m_textCtrl1;
- wxStaticText* m_staticTextMessage2;
- wxTextCtrl* m_textCtrl2;
-
-
- wxButton* m_buttonOK;
- wxButton* m_buttonCancel;
-
- // Virtual event handlers, overide them in your derived class
- virtual void OnClose( wxCloseEvent& event ){ event.Skip(); }
- virtual void OnKeyDown( wxKeyEvent& event ){ event.Skip(); }
- virtual void OnButtonOK( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); }
-
-
- public:
- CGetTextFromUserDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 440,138 ), long style = wxDEFAULT_DIALOG_STYLE );
- ~CGetTextFromUserDialogBase();
-
-};
-
-#endif //__uibase__
+/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Apr 16 2008) +// http://www.wxformbuilder.org/ +// +// PLEASE DO "NOT" EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#ifndef __uibase__ +#define __uibase__ + +#include <wx/intl.h> + +#include <wx/string.h> +#include <wx/bitmap.h> +#include <wx/image.h> +#include <wx/icon.h> +#include <wx/menu.h> +#include <wx/gdicmn.h> +#include <wx/font.h> +#include <wx/colour.h> +#include <wx/settings.h> +#include <wx/toolbar.h> +#include <wx/statusbr.h> +#include <wx/stattext.h> +#include <wx/textctrl.h> +#include <wx/button.h> +#include <wx/sizer.h> +#include <wx/choice.h> +#include <wx/listctrl.h> +#include <wx/panel.h> +#include <wx/notebook.h> +#include <wx/frame.h> +#include <wx/html/htmlwin.h> +#include <wx/dialog.h> +#include <wx/listbox.h> +#include <wx/checkbox.h> +#include <wx/spinctrl.h> +#include <wx/scrolwin.h> +#include <wx/statbmp.h> + +/////////////////////////////////////////////////////////////////////////// + +#define wxID_MAINFRAME 1000 +#define wxID_OPTIONSGENERATEBITCOINS 1001 +#define wxID_BUTTONSEND 1002 +#define wxID_BUTTONRECEIVE 1003 +#define wxID_TEXTCTRLADDRESS 1004 +#define wxID_BUTTONNEW 1005 +#define wxID_BUTTONCOPY 1006 +#define wxID_TRANSACTIONFEE 1007 +#define wxID_PROXYIP 1008 +#define wxID_PROXYPORT 1009 +#define wxID_TEXTCTRLPAYTO 1010 +#define wxID_BUTTONPASTE 1011 +#define wxID_BUTTONADDRESSBOOK 1012 +#define wxID_TEXTCTRLAMOUNT 1013 +#define wxID_CHOICETRANSFERTYPE 1014 +#define wxID_LISTCTRL 1015 +#define wxID_BUTTONRENAME 1016 +#define wxID_PANELSENDING 1017 +#define wxID_LISTCTRLSENDING 1018 +#define wxID_PANELRECEIVING 1019 +#define wxID_LISTCTRLRECEIVING 1020 +#define wxID_BUTTONDELETE 1021 +#define wxID_BUTTONEDIT 1022 +#define wxID_TEXTCTRL 1023 + +/////////////////////////////////////////////////////////////////////////////// +/// Class CMainFrameBase +/////////////////////////////////////////////////////////////////////////////// +class CMainFrameBase : public wxFrame +{ + private: + + protected: + wxMenuBar* m_menubar; + wxMenu* m_menuFile; + wxMenu* m_menuHelp; + wxToolBar* m_toolBar; + + wxStaticText* m_staticText32; + wxButton* m_buttonNew; + wxButton* m_buttonCopy; + + wxStaticText* m_staticText41; + wxStaticText* m_staticTextBalance; + + wxChoice* m_choiceFilter; + wxNotebook* m_notebook; + wxPanel* m_panel9; + wxPanel* m_panel91; + wxPanel* m_panel92; + wxPanel* m_panel93; + + // Virtual event handlers, overide them in your derived class + virtual void OnClose( wxCloseEvent& event ){ event.Skip(); } + virtual void OnIconize( wxIconizeEvent& event ){ event.Skip(); } + virtual void OnIdle( wxIdleEvent& event ){ event.Skip(); } + virtual void OnMouseEvents( wxMouseEvent& event ){ event.Skip(); } + virtual void OnPaint( wxPaintEvent& event ){ event.Skip(); } + virtual void OnMenuFileExit( wxCommandEvent& event ){ event.Skip(); } + virtual void OnMenuOptionsGenerate( wxCommandEvent& event ){ event.Skip(); } + virtual void OnUpdateUIOptionsGenerate( wxUpdateUIEvent& event ){ event.Skip(); } + virtual void OnMenuOptionsChangeYourAddress( wxCommandEvent& event ){ event.Skip(); } + virtual void OnMenuOptionsOptions( wxCommandEvent& event ){ event.Skip(); } + virtual void OnMenuHelpAbout( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonSend( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonAddressBook( wxCommandEvent& event ){ event.Skip(); } + virtual void OnKeyDown( wxKeyEvent& event ){ event.Skip(); } + virtual void OnMouseEventsAddress( wxMouseEvent& event ){ event.Skip(); } + virtual void OnSetFocusAddress( wxFocusEvent& event ){ event.Skip(); } + virtual void OnButtonNew( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonCopy( wxCommandEvent& event ){ event.Skip(); } + virtual void OnNotebookPageChanged( wxNotebookEvent& event ){ event.Skip(); } + virtual void OnListColBeginDrag( wxListEvent& event ){ event.Skip(); } + virtual void OnListItemActivated( wxListEvent& event ){ event.Skip(); } + virtual void OnPaintListCtrl( wxPaintEvent& event ){ event.Skip(); } + + + public: + wxMenu* m_menuOptions; + wxStatusBar* m_statusBar; + wxTextCtrl* m_textCtrlAddress; + wxListCtrl* m_listCtrlAll; + wxListCtrl* m_listCtrlSentReceived; + wxListCtrl* m_listCtrlSent; + wxListCtrl* m_listCtrlReceived; + CMainFrameBase( wxWindow* parent, wxWindowID id = wxID_MAINFRAME, const wxString& title = _("Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 723,484 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); + ~CMainFrameBase(); + +}; + +/////////////////////////////////////////////////////////////////////////////// +/// Class CTxDetailsDialogBase +/////////////////////////////////////////////////////////////////////////////// +class CTxDetailsDialogBase : public wxDialog +{ + private: + + protected: + wxHtmlWindow* m_htmlWin; + wxButton* m_buttonOK; + + // Virtual event handlers, overide them in your derived class + virtual void OnButtonOK( wxCommandEvent& event ){ event.Skip(); } + + + public: + CTxDetailsDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Transaction Details"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 620,450 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + ~CTxDetailsDialogBase(); + +}; + +/////////////////////////////////////////////////////////////////////////////// +/// Class COptionsDialogBase +/////////////////////////////////////////////////////////////////////////////// +class COptionsDialogBase : public wxDialog +{ + private: + + protected: + wxListBox* m_listBox; + wxScrolledWindow* m_scrolledWindow; + wxPanel* m_panelMain; + + wxStaticText* m_staticText32; + wxStaticText* m_staticText31; + wxTextCtrl* m_textCtrlTransactionFee; + wxCheckBox* m_checkBoxLimitProcessors; + wxSpinCtrl* m_spinCtrlLimitProcessors; + wxStaticText* m_staticText35; + wxCheckBox* m_checkBoxStartOnSystemStartup; + wxCheckBox* m_checkBoxMinimizeToTray; + wxCheckBox* m_checkBoxMinimizeOnClose; + wxCheckBox* m_checkBoxUseProxy; + + wxStaticText* m_staticTextProxyIP; + wxTextCtrl* m_textCtrlProxyIP; + wxStaticText* m_staticTextProxyPort; + wxTextCtrl* m_textCtrlProxyPort; + wxPanel* m_panelTest2; + + wxStaticText* m_staticText321; + wxStaticText* m_staticText69; + wxButton* m_buttonOK; + wxButton* m_buttonCancel; + wxButton* m_buttonApply; + + // Virtual event handlers, overide them in your derived class + virtual void OnListBox( wxCommandEvent& event ){ event.Skip(); } + virtual void OnKillFocusTransactionFee( wxFocusEvent& event ){ event.Skip(); } + virtual void OnCheckBoxLimitProcessors( wxCommandEvent& event ){ event.Skip(); } + virtual void OnCheckBoxMinimizeToTray( wxCommandEvent& event ){ event.Skip(); } + virtual void OnCheckBoxUseProxy( wxCommandEvent& event ){ event.Skip(); } + virtual void OnKillFocusProxy( wxFocusEvent& event ){ event.Skip(); } + virtual void OnButtonOK( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonApply( wxCommandEvent& event ){ event.Skip(); } + + + public: + COptionsDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Options"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 540,360 ), long style = wxDEFAULT_DIALOG_STYLE ); + ~COptionsDialogBase(); + +}; + +/////////////////////////////////////////////////////////////////////////////// +/// Class CAboutDialogBase +/////////////////////////////////////////////////////////////////////////////// +class CAboutDialogBase : public wxDialog +{ + private: + + protected: + wxStaticBitmap* m_bitmap; + + wxStaticText* m_staticText40; + + wxStaticText* m_staticTextMain; + + + wxButton* m_buttonOK; + + // Virtual event handlers, overide them in your derived class + virtual void OnButtonOK( wxCommandEvent& event ){ event.Skip(); } + + + public: + wxStaticText* m_staticTextVersion; + CAboutDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("About Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 532,329 ), long style = wxDEFAULT_DIALOG_STYLE ); + ~CAboutDialogBase(); + +}; + +/////////////////////////////////////////////////////////////////////////////// +/// Class CSendDialogBase +/////////////////////////////////////////////////////////////////////////////// +class CSendDialogBase : public wxDialog +{ + private: + + protected: + + + wxStaticText* m_staticTextInstructions; + + wxStaticBitmap* m_bitmapCheckMark; + wxStaticText* m_staticText36; + wxTextCtrl* m_textCtrlAddress; + wxButton* m_buttonPaste; + wxButton* m_buttonAddress; + wxStaticText* m_staticText19; + wxTextCtrl* m_textCtrlAmount; + wxStaticText* m_staticText20; + wxChoice* m_choiceTransferType; + + + wxStaticText* m_staticTextFrom; + wxTextCtrl* m_textCtrlFrom; + wxStaticText* m_staticTextMessage; + wxTextCtrl* m_textCtrlMessage; + + wxButton* m_buttonSend; + wxButton* m_buttonCancel; + + // Virtual event handlers, overide them in your derived class + virtual void OnKeyDown( wxKeyEvent& event ){ event.Skip(); } + virtual void OnTextAddress( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonPaste( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonAddressBook( wxCommandEvent& event ){ event.Skip(); } + virtual void OnKillFocusAmount( wxFocusEvent& event ){ event.Skip(); } + virtual void OnButtonSend( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); } + + + public: + CSendDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Send Coins"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 675,298 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + ~CSendDialogBase(); + +}; + +/////////////////////////////////////////////////////////////////////////////// +/// Class CSendingDialogBase +/////////////////////////////////////////////////////////////////////////////// +class CSendingDialogBase : public wxDialog +{ + private: + + protected: + wxStaticText* m_staticTextSending; + wxTextCtrl* m_textCtrlStatus; + + wxButton* m_buttonOK; + wxButton* m_buttonCancel; + + // Virtual event handlers, overide them in your derived class + virtual void OnClose( wxCloseEvent& event ){ event.Skip(); } + virtual void OnPaint( wxPaintEvent& event ){ event.Skip(); } + virtual void OnButtonOK( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); } + + + public: + CSendingDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Sending..."), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 442,151 ), long style = wxDEFAULT_DIALOG_STYLE ); + ~CSendingDialogBase(); + +}; + +/////////////////////////////////////////////////////////////////////////////// +/// Class CYourAddressDialogBase +/////////////////////////////////////////////////////////////////////////////// +class CYourAddressDialogBase : public wxDialog +{ + private: + + protected: + + wxStaticText* m_staticText45; + wxListCtrl* m_listCtrl; + + wxButton* m_buttonRename; + wxButton* m_buttonNew; + wxButton* m_buttonCopy; + wxButton* m_buttonOK; + wxButton* m_buttonCancel; + + // Virtual event handlers, overide them in your derived class + virtual void OnClose( wxCloseEvent& event ){ event.Skip(); } + virtual void OnListEndLabelEdit( wxListEvent& event ){ event.Skip(); } + virtual void OnListItemActivated( wxListEvent& event ){ event.Skip(); } + virtual void OnListItemSelected( wxListEvent& event ){ event.Skip(); } + virtual void OnButtonRename( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonNew( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonCopy( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonOK( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); } + + + public: + CYourAddressDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Your Bitcoin Addresses"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 610,390 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + ~CYourAddressDialogBase(); + +}; + +/////////////////////////////////////////////////////////////////////////////// +/// Class CAddressBookDialogBase +/////////////////////////////////////////////////////////////////////////////// +class CAddressBookDialogBase : public wxDialog +{ + private: + + protected: + wxNotebook* m_notebook; + wxPanel* m_panelSending; + + wxStaticText* m_staticText55; + wxListCtrl* m_listCtrlSending; + wxPanel* m_panelReceiving; + + wxStaticText* m_staticText45; + + wxListCtrl* m_listCtrlReceiving; + + wxButton* m_buttonDelete; + wxButton* m_buttonCopy; + wxButton* m_buttonEdit; + wxButton* m_buttonNew; + wxButton* m_buttonOK; + + // Virtual event handlers, overide them in your derived class + virtual void OnClose( wxCloseEvent& event ){ event.Skip(); } + virtual void OnNotebookPageChanged( wxNotebookEvent& event ){ event.Skip(); } + virtual void OnListEndLabelEdit( wxListEvent& event ){ event.Skip(); } + virtual void OnListItemActivated( wxListEvent& event ){ event.Skip(); } + virtual void OnListItemSelected( wxListEvent& event ){ event.Skip(); } + virtual void OnButtonDelete( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonCopy( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonEdit( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonNew( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonOK( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); } + + + public: + wxButton* m_buttonCancel; + CAddressBookDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Address Book"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 610,390 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + ~CAddressBookDialogBase(); + +}; + +/////////////////////////////////////////////////////////////////////////////// +/// Class CGetTextFromUserDialogBase +/////////////////////////////////////////////////////////////////////////////// +class CGetTextFromUserDialogBase : public wxDialog +{ + private: + + protected: + + wxStaticText* m_staticTextMessage1; + wxTextCtrl* m_textCtrl1; + wxStaticText* m_staticTextMessage2; + wxTextCtrl* m_textCtrl2; + + + wxButton* m_buttonOK; + wxButton* m_buttonCancel; + + // Virtual event handlers, overide them in your derived class + virtual void OnClose( wxCloseEvent& event ){ event.Skip(); } + virtual void OnKeyDown( wxKeyEvent& event ){ event.Skip(); } + virtual void OnButtonOK( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); } + + + public: + CGetTextFromUserDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 440,138 ), long style = wxDEFAULT_DIALOG_STYLE ); + ~CGetTextFromUserDialogBase(); + +}; + +#endif //__uibase__ @@ -1,757 +1,757 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
-
-#include <limits.h>
-#include <string>
-#if defined(_MSC_VER) || defined(__BORLANDC__)
-typedef __int64 int64;
-typedef unsigned __int64 uint64;
-#else
-typedef long long int64;
-typedef unsigned long long uint64;
-#endif
-#if defined(_MSC_VER) && _MSC_VER < 1300
-#define for if (false) ; else for
-#endif
-
-
-inline int Testuint256AdHoc(vector<string> vArg);
-
-
-
-// We have to keep a separate base class without constructors
-// so the compiler will let us use it in a union
-template<unsigned int BITS>
-class base_uint
-{
-protected:
- enum { WIDTH=BITS/32 };
- unsigned int pn[WIDTH];
-public:
-
- bool operator!() const
- {
- for (int i = 0; i < WIDTH; i++)
- if (pn[i] != 0)
- return false;
- return true;
- }
-
- const base_uint operator~() const
- {
- base_uint ret;
- for (int i = 0; i < WIDTH; i++)
- ret.pn[i] = ~pn[i];
- return ret;
- }
-
- const base_uint operator-() const
- {
- base_uint ret;
- for (int i = 0; i < WIDTH; i++)
- ret.pn[i] = ~pn[i];
- ret++;
- return ret;
- }
-
-
- base_uint& operator=(uint64 b)
- {
- pn[0] = (unsigned int)b;
- pn[1] = (unsigned int)(b >> 32);
- for (int i = 2; i < WIDTH; i++)
- pn[i] = 0;
- return *this;
- }
-
- base_uint& operator^=(const base_uint& b)
- {
- for (int i = 0; i < WIDTH; i++)
- pn[i] ^= b.pn[i];
- return *this;
- }
-
- base_uint& operator&=(const base_uint& b)
- {
- for (int i = 0; i < WIDTH; i++)
- pn[i] &= b.pn[i];
- return *this;
- }
-
- base_uint& operator|=(const base_uint& b)
- {
- for (int i = 0; i < WIDTH; i++)
- pn[i] |= b.pn[i];
- return *this;
- }
-
- base_uint& operator^=(uint64 b)
- {
- pn[0] ^= (unsigned int)b;
- pn[1] ^= (unsigned int)(b >> 32);
- return *this;
- }
-
- base_uint& operator&=(uint64 b)
- {
- pn[0] &= (unsigned int)b;
- pn[1] &= (unsigned int)(b >> 32);
- return *this;
- }
-
- base_uint& operator|=(uint64 b)
- {
- pn[0] |= (unsigned int)b;
- pn[1] |= (unsigned int)(b >> 32);
- return *this;
- }
-
- base_uint& operator<<=(unsigned int shift)
- {
- base_uint a(*this);
- for (int i = 0; i < WIDTH; i++)
- pn[i] = 0;
- 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);
- }
- return *this;
- }
-
- base_uint& operator>>=(unsigned int shift)
- {
- base_uint a(*this);
- for (int i = 0; i < WIDTH; i++)
- pn[i] = 0;
- 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);
- }
- return *this;
- }
-
- base_uint& operator+=(const base_uint& b)
- {
- uint64 carry = 0;
- for (int i = 0; i < WIDTH; i++)
- {
- uint64 n = carry + pn[i] + b.pn[i];
- pn[i] = n & 0xffffffff;
- carry = n >> 32;
- }
- return *this;
- }
-
- base_uint& operator-=(const base_uint& b)
- {
- *this += -b;
- return *this;
- }
-
- base_uint& operator+=(uint64 b64)
- {
- base_uint b;
- b = b64;
- *this += b;
- return *this;
- }
-
- base_uint& operator-=(uint64 b64)
- {
- base_uint b;
- b = b64;
- *this += -b;
- return *this;
- }
-
-
- base_uint& operator++()
- {
- // prefix operator
- int i = 0;
- while (++pn[i] == 0 && i < WIDTH-1)
- i++;
- return *this;
- }
-
- const base_uint operator++(int)
- {
- // postfix operator
- const base_uint ret = *this;
- ++(*this);
- return ret;
- }
-
- base_uint& operator--()
- {
- // prefix operator
- int i = 0;
- while (--pn[i] == -1 && i < WIDTH-1)
- i++;
- return *this;
- }
-
- const base_uint operator--(int)
- {
- // postfix operator
- const base_uint ret = *this;
- --(*this);
- return ret;
- }
-
-
- friend inline bool operator<(const base_uint& a, const base_uint& b)
- {
- for (int i = base_uint::WIDTH-1; i >= 0; i--)
- {
- if (a.pn[i] < b.pn[i])
- return true;
- else if (a.pn[i] > b.pn[i])
- return false;
- }
- return false;
- }
-
- friend inline bool operator<=(const base_uint& a, const base_uint& b)
- {
- for (int i = base_uint::WIDTH-1; i >= 0; i--)
- {
- if (a.pn[i] < b.pn[i])
- return true;
- else if (a.pn[i] > b.pn[i])
- return false;
- }
- return true;
- }
-
- friend inline bool operator>(const base_uint& a, const base_uint& b)
- {
- for (int i = base_uint::WIDTH-1; i >= 0; i--)
- {
- if (a.pn[i] > b.pn[i])
- return true;
- else if (a.pn[i] < b.pn[i])
- return false;
- }
- return false;
- }
-
- friend inline bool operator>=(const base_uint& a, const base_uint& b)
- {
- for (int i = base_uint::WIDTH-1; i >= 0; i--)
- {
- if (a.pn[i] > b.pn[i])
- return true;
- else if (a.pn[i] < b.pn[i])
- return false;
- }
- return true;
- }
-
- friend inline bool operator==(const base_uint& a, const base_uint& b)
- {
- for (int i = 0; i < base_uint::WIDTH; i++)
- if (a.pn[i] != b.pn[i])
- return false;
- return true;
- }
-
- friend inline bool operator==(const base_uint& a, uint64 b)
- {
- if (a.pn[0] != (unsigned int)b)
- return false;
- if (a.pn[1] != (unsigned int)(b >> 32))
- return false;
- for (int i = 2; i < base_uint::WIDTH; i++)
- if (a.pn[i] != 0)
- return false;
- return true;
- }
-
- friend inline bool operator!=(const base_uint& a, const base_uint& b)
- {
- return (!(a == b));
- }
-
- friend inline bool operator!=(const base_uint& a, uint64 b)
- {
- return (!(a == b));
- }
-
-
-
- std::string GetHex() const
- {
- char psz[sizeof(pn)*2 + 1];
- for (int i = 0; i < sizeof(pn); i++)
- sprintf(psz + i*2, "%02x", ((unsigned char*)pn)[sizeof(pn) - i - 1]);
- return string(psz, psz + sizeof(pn)*2);
- }
-
- void SetHex(const char* psz)
- {
- for (int i = 0; i < WIDTH; i++)
- pn[i] = 0;
-
- // skip leading spaces
- while (isspace(*psz))
- psz++;
-
- // skip 0x
- if (psz[0] == '0' && tolower(psz[1]) == 'x')
- psz += 2;
-
- // hex string to uint
- static char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 };
- const char* pbegin = psz;
- while (phexdigit[*psz] || *psz == '0')
- psz++;
- psz--;
- unsigned char* p1 = (unsigned char*)pn;
- unsigned char* pend = p1 + WIDTH * 4;
- while (psz >= pbegin && p1 < pend)
- {
- *p1 = phexdigit[(unsigned char)*psz--];
- if (psz >= pbegin)
- {
- *p1 |= (phexdigit[(unsigned char)*psz--] << 4);
- p1++;
- }
- }
- }
-
- void SetHex(const std::string& str)
- {
- SetHex(str.c_str());
- }
-
- std::string ToString() const
- {
- return (GetHex());
- }
-
- unsigned char* begin()
- {
- return (unsigned char*)&pn[0];
- }
-
- unsigned char* end()
- {
- return (unsigned char*)&pn[WIDTH];
- }
-
- unsigned int size()
- {
- return sizeof(pn);
- }
-
-
- unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const
- {
- return sizeof(pn);
- }
-
- template<typename Stream>
- void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const
- {
- s.write((char*)pn, sizeof(pn));
- }
-
- template<typename Stream>
- void Unserialize(Stream& s, int nType=0, int nVersion=VERSION)
- {
- s.read((char*)pn, sizeof(pn));
- }
-
-
- friend class uint160;
- friend class uint256;
- friend inline int Testuint256AdHoc(vector<string> vArg);
-};
-
-typedef base_uint<160> base_uint160;
-typedef base_uint<256> base_uint256;
-
-
-
-//
-// uint160 and uint256 could be implemented as templates, but to keep
-// compile errors and debugging cleaner, they're copy and pasted.
-//
-
-
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// uint160
-//
-
-class uint160 : public base_uint160
-{
-public:
- typedef base_uint160 basetype;
-
- uint160()
- {
- for (int i = 0; i < WIDTH; i++)
- pn[i] = 0;
- }
-
- uint160(const basetype& b)
- {
- for (int i = 0; i < WIDTH; i++)
- pn[i] = b.pn[i];
- }
-
- uint160& operator=(const basetype& b)
- {
- for (int i = 0; i < WIDTH; i++)
- pn[i] = b.pn[i];
- return *this;
- }
-
- uint160(uint64 b)
- {
- pn[0] = (unsigned int)b;
- pn[1] = (unsigned int)(b >> 32);
- for (int i = 2; i < WIDTH; i++)
- pn[i] = 0;
- }
-
- uint160& operator=(uint64 b)
- {
- pn[0] = (unsigned int)b;
- pn[1] = (unsigned int)(b >> 32);
- for (int i = 2; i < WIDTH; i++)
- pn[i] = 0;
- return *this;
- }
-
- explicit uint160(const std::string& str)
- {
- SetHex(str);
- }
-
- explicit uint160(const std::vector<unsigned char>& vch)
- {
- if (vch.size() == sizeof(pn))
- memcpy(pn, &vch[0], sizeof(pn));
- else
- *this = 0;
- }
-};
-
-inline bool operator==(const uint160& a, uint64 b) { return (base_uint160)a == b; }
-inline bool operator!=(const uint160& a, uint64 b) { return (base_uint160)a != b; }
-inline const uint160 operator<<(const base_uint160& a, unsigned int shift) { return uint160(a) <<= shift; }
-inline const uint160 operator>>(const base_uint160& a, unsigned int shift) { return uint160(a) >>= shift; }
-inline const uint160 operator<<(const uint160& a, unsigned int shift) { return uint160(a) <<= shift; }
-inline const uint160 operator>>(const uint160& a, unsigned int shift) { return uint160(a) >>= shift; }
-
-inline const uint160 operator^(const base_uint160& a, const base_uint160& b) { return uint160(a) ^= b; }
-inline const uint160 operator&(const base_uint160& a, const base_uint160& b) { return uint160(a) &= b; }
-inline const uint160 operator|(const base_uint160& a, const base_uint160& b) { return uint160(a) |= b; }
-inline const uint160 operator+(const base_uint160& a, const base_uint160& b) { return uint160(a) += b; }
-inline const uint160 operator-(const base_uint160& a, const base_uint160& b) { return uint160(a) -= b; }
-
-inline bool operator<(const base_uint160& a, const uint160& b) { return (base_uint160)a < (base_uint160)b; }
-inline bool operator<=(const base_uint160& a, const uint160& b) { return (base_uint160)a <= (base_uint160)b; }
-inline bool operator>(const base_uint160& a, const uint160& b) { return (base_uint160)a > (base_uint160)b; }
-inline bool operator>=(const base_uint160& a, const uint160& b) { return (base_uint160)a >= (base_uint160)b; }
-inline bool operator==(const base_uint160& a, const uint160& b) { return (base_uint160)a == (base_uint160)b; }
-inline bool operator!=(const base_uint160& a, const uint160& b) { return (base_uint160)a != (base_uint160)b; }
-inline const uint160 operator^(const base_uint160& a, const uint160& b) { return (base_uint160)a ^ (base_uint160)b; }
-inline const uint160 operator&(const base_uint160& a, const uint160& b) { return (base_uint160)a & (base_uint160)b; }
-inline const uint160 operator|(const base_uint160& a, const uint160& b) { return (base_uint160)a | (base_uint160)b; }
-inline const uint160 operator+(const base_uint160& a, const uint160& b) { return (base_uint160)a + (base_uint160)b; }
-inline const uint160 operator-(const base_uint160& a, const uint160& b) { return (base_uint160)a - (base_uint160)b; }
-
-inline bool operator<(const uint160& a, const base_uint160& b) { return (base_uint160)a < (base_uint160)b; }
-inline bool operator<=(const uint160& a, const base_uint160& b) { return (base_uint160)a <= (base_uint160)b; }
-inline bool operator>(const uint160& a, const base_uint160& b) { return (base_uint160)a > (base_uint160)b; }
-inline bool operator>=(const uint160& a, const base_uint160& b) { return (base_uint160)a >= (base_uint160)b; }
-inline bool operator==(const uint160& a, const base_uint160& b) { return (base_uint160)a == (base_uint160)b; }
-inline bool operator!=(const uint160& a, const base_uint160& b) { return (base_uint160)a != (base_uint160)b; }
-inline const uint160 operator^(const uint160& a, const base_uint160& b) { return (base_uint160)a ^ (base_uint160)b; }
-inline const uint160 operator&(const uint160& a, const base_uint160& b) { return (base_uint160)a & (base_uint160)b; }
-inline const uint160 operator|(const uint160& a, const base_uint160& b) { return (base_uint160)a | (base_uint160)b; }
-inline const uint160 operator+(const uint160& a, const base_uint160& b) { return (base_uint160)a + (base_uint160)b; }
-inline const uint160 operator-(const uint160& a, const base_uint160& b) { return (base_uint160)a - (base_uint160)b; }
-
-inline bool operator<(const uint160& a, const uint160& b) { return (base_uint160)a < (base_uint160)b; }
-inline bool operator<=(const uint160& a, const uint160& b) { return (base_uint160)a <= (base_uint160)b; }
-inline bool operator>(const uint160& a, const uint160& b) { return (base_uint160)a > (base_uint160)b; }
-inline bool operator>=(const uint160& a, const uint160& b) { return (base_uint160)a >= (base_uint160)b; }
-inline bool operator==(const uint160& a, const uint160& b) { return (base_uint160)a == (base_uint160)b; }
-inline bool operator!=(const uint160& a, const uint160& b) { return (base_uint160)a != (base_uint160)b; }
-inline const uint160 operator^(const uint160& a, const uint160& b) { return (base_uint160)a ^ (base_uint160)b; }
-inline const uint160 operator&(const uint160& a, const uint160& b) { return (base_uint160)a & (base_uint160)b; }
-inline const uint160 operator|(const uint160& a, const uint160& b) { return (base_uint160)a | (base_uint160)b; }
-inline const uint160 operator+(const uint160& a, const uint160& b) { return (base_uint160)a + (base_uint160)b; }
-inline const uint160 operator-(const uint160& a, const uint160& b) { return (base_uint160)a - (base_uint160)b; }
-
-
-
-
-
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// uint256
-//
-
-class uint256 : public base_uint256
-{
-public:
- typedef base_uint256 basetype;
-
- uint256()
- {
- for (int i = 0; i < WIDTH; i++)
- pn[i] = 0;
- }
-
- uint256(const basetype& b)
- {
- for (int i = 0; i < WIDTH; i++)
- pn[i] = b.pn[i];
- }
-
- uint256& operator=(const basetype& b)
- {
- for (int i = 0; i < WIDTH; i++)
- pn[i] = b.pn[i];
- return *this;
- }
-
- uint256(uint64 b)
- {
- pn[0] = (unsigned int)b;
- pn[1] = (unsigned int)(b >> 32);
- for (int i = 2; i < WIDTH; i++)
- pn[i] = 0;
- }
-
- uint256& operator=(uint64 b)
- {
- pn[0] = (unsigned int)b;
- pn[1] = (unsigned int)(b >> 32);
- for (int i = 2; i < WIDTH; i++)
- pn[i] = 0;
- return *this;
- }
-
- explicit uint256(const std::string& str)
- {
- SetHex(str);
- }
-
- explicit uint256(const std::vector<unsigned char>& vch)
- {
- if (vch.size() == sizeof(pn))
- memcpy(pn, &vch[0], sizeof(pn));
- else
- *this = 0;
- }
-};
-
-inline bool operator==(const uint256& a, uint64 b) { return (base_uint256)a == b; }
-inline bool operator!=(const uint256& a, uint64 b) { return (base_uint256)a != b; }
-inline const uint256 operator<<(const base_uint256& a, unsigned int shift) { return uint256(a) <<= shift; }
-inline const uint256 operator>>(const base_uint256& a, unsigned int shift) { return uint256(a) >>= shift; }
-inline const uint256 operator<<(const uint256& a, unsigned int shift) { return uint256(a) <<= shift; }
-inline const uint256 operator>>(const uint256& a, unsigned int shift) { return uint256(a) >>= shift; }
-
-inline const uint256 operator^(const base_uint256& a, const base_uint256& b) { return uint256(a) ^= b; }
-inline const uint256 operator&(const base_uint256& a, const base_uint256& b) { return uint256(a) &= b; }
-inline const uint256 operator|(const base_uint256& a, const base_uint256& b) { return uint256(a) |= b; }
-inline const uint256 operator+(const base_uint256& a, const base_uint256& b) { return uint256(a) += b; }
-inline const uint256 operator-(const base_uint256& a, const base_uint256& b) { return uint256(a) -= b; }
-
-inline bool operator<(const base_uint256& a, const uint256& b) { return (base_uint256)a < (base_uint256)b; }
-inline bool operator<=(const base_uint256& a, const uint256& b) { return (base_uint256)a <= (base_uint256)b; }
-inline bool operator>(const base_uint256& a, const uint256& b) { return (base_uint256)a > (base_uint256)b; }
-inline bool operator>=(const base_uint256& a, const uint256& b) { return (base_uint256)a >= (base_uint256)b; }
-inline bool operator==(const base_uint256& a, const uint256& b) { return (base_uint256)a == (base_uint256)b; }
-inline bool operator!=(const base_uint256& a, const uint256& b) { return (base_uint256)a != (base_uint256)b; }
-inline const uint256 operator^(const base_uint256& a, const uint256& b) { return (base_uint256)a ^ (base_uint256)b; }
-inline const uint256 operator&(const base_uint256& a, const uint256& b) { return (base_uint256)a & (base_uint256)b; }
-inline const uint256 operator|(const base_uint256& a, const uint256& b) { return (base_uint256)a | (base_uint256)b; }
-inline const uint256 operator+(const base_uint256& a, const uint256& b) { return (base_uint256)a + (base_uint256)b; }
-inline const uint256 operator-(const base_uint256& a, const uint256& b) { return (base_uint256)a - (base_uint256)b; }
-
-inline bool operator<(const uint256& a, const base_uint256& b) { return (base_uint256)a < (base_uint256)b; }
-inline bool operator<=(const uint256& a, const base_uint256& b) { return (base_uint256)a <= (base_uint256)b; }
-inline bool operator>(const uint256& a, const base_uint256& b) { return (base_uint256)a > (base_uint256)b; }
-inline bool operator>=(const uint256& a, const base_uint256& b) { return (base_uint256)a >= (base_uint256)b; }
-inline bool operator==(const uint256& a, const base_uint256& b) { return (base_uint256)a == (base_uint256)b; }
-inline bool operator!=(const uint256& a, const base_uint256& b) { return (base_uint256)a != (base_uint256)b; }
-inline const uint256 operator^(const uint256& a, const base_uint256& b) { return (base_uint256)a ^ (base_uint256)b; }
-inline const uint256 operator&(const uint256& a, const base_uint256& b) { return (base_uint256)a & (base_uint256)b; }
-inline const uint256 operator|(const uint256& a, const base_uint256& b) { return (base_uint256)a | (base_uint256)b; }
-inline const uint256 operator+(const uint256& a, const base_uint256& b) { return (base_uint256)a + (base_uint256)b; }
-inline const uint256 operator-(const uint256& a, const base_uint256& b) { return (base_uint256)a - (base_uint256)b; }
-
-inline bool operator<(const uint256& a, const uint256& b) { return (base_uint256)a < (base_uint256)b; }
-inline bool operator<=(const uint256& a, const uint256& b) { return (base_uint256)a <= (base_uint256)b; }
-inline bool operator>(const uint256& a, const uint256& b) { return (base_uint256)a > (base_uint256)b; }
-inline bool operator>=(const uint256& a, const uint256& b) { return (base_uint256)a >= (base_uint256)b; }
-inline bool operator==(const uint256& a, const uint256& b) { return (base_uint256)a == (base_uint256)b; }
-inline bool operator!=(const uint256& a, const uint256& b) { return (base_uint256)a != (base_uint256)b; }
-inline const uint256 operator^(const uint256& a, const uint256& b) { return (base_uint256)a ^ (base_uint256)b; }
-inline const uint256 operator&(const uint256& a, const uint256& b) { return (base_uint256)a & (base_uint256)b; }
-inline const uint256 operator|(const uint256& a, const uint256& b) { return (base_uint256)a | (base_uint256)b; }
-inline const uint256 operator+(const uint256& a, const uint256& b) { return (base_uint256)a + (base_uint256)b; }
-inline const uint256 operator-(const uint256& a, const uint256& b) { return (base_uint256)a - (base_uint256)b; }
-
-
-
-
-
-
-
-
-
-
-
-
-inline int Testuint256AdHoc(vector<string> vArg)
-{
- uint256 g(0);
-
-
- printf("%s\n", g.ToString().c_str());
- g--; printf("g--\n");
- printf("%s\n", g.ToString().c_str());
- g--; printf("g--\n");
- printf("%s\n", g.ToString().c_str());
- g++; printf("g++\n");
- printf("%s\n", g.ToString().c_str());
- g++; printf("g++\n");
- printf("%s\n", g.ToString().c_str());
- g++; printf("g++\n");
- printf("%s\n", g.ToString().c_str());
- g++; printf("g++\n");
- printf("%s\n", g.ToString().c_str());
-
-
-
- uint256 a(7);
- printf("a=7\n");
- printf("%s\n", a.ToString().c_str());
-
- uint256 b;
- printf("b undefined\n");
- printf("%s\n", b.ToString().c_str());
- int c = 3;
-
- a = c;
- a.pn[3] = 15;
- printf("%s\n", a.ToString().c_str());
- uint256 k(c);
-
- a = 5;
- a.pn[3] = 15;
- printf("%s\n", a.ToString().c_str());
- b = 1;
- b <<= 52;
-
- a |= b;
-
- a ^= 0x500;
-
- printf("a %s\n", a.ToString().c_str());
-
- a = a | b | (uint256)0x1000;
-
-
- printf("a %s\n", a.ToString().c_str());
- printf("b %s\n", b.ToString().c_str());
-
- a = 0xfffffffe;
- a.pn[4] = 9;
-
- printf("%s\n", a.ToString().c_str());
- a++;
- printf("%s\n", a.ToString().c_str());
- a++;
- printf("%s\n", a.ToString().c_str());
- a++;
- printf("%s\n", a.ToString().c_str());
- a++;
- printf("%s\n", a.ToString().c_str());
-
- a--;
- printf("%s\n", a.ToString().c_str());
- a--;
- printf("%s\n", a.ToString().c_str());
- a--;
- printf("%s\n", a.ToString().c_str());
- uint256 d = a--;
- printf("%s\n", d.ToString().c_str());
- printf("%s\n", a.ToString().c_str());
- a--;
- printf("%s\n", a.ToString().c_str());
- a--;
- printf("%s\n", a.ToString().c_str());
-
- d = a;
-
- printf("%s\n", d.ToString().c_str());
- for (int i = uint256::WIDTH-1; i >= 0; i--) printf("%08x", d.pn[i]); printf("\n");
-
- uint256 neg = d;
- neg = ~neg;
- printf("%s\n", neg.ToString().c_str());
-
-
- uint256 e = uint256("0xABCDEF123abcdef12345678909832180000011111111");
- printf("\n");
- printf("%s\n", e.ToString().c_str());
-
-
- printf("\n");
- uint256 x1 = uint256("0xABCDEF123abcdef12345678909832180000011111111");
- uint256 x2;
- printf("%s\n", x1.ToString().c_str());
- for (int i = 0; i < 270; i += 4)
- {
- x2 = x1 << i;
- printf("%s\n", x2.ToString().c_str());
- }
-
- printf("\n");
- printf("%s\n", x1.ToString().c_str());
- for (int i = 0; i < 270; i += 4)
- {
- x2 = x1;
- x2 >>= i;
- printf("%s\n", x2.ToString().c_str());
- }
-
-
- for (int i = 0; i < 100; i++)
- {
- uint256 k = (~uint256(0) >> i);
- printf("%s\n", k.ToString().c_str());
- }
-
- for (int i = 0; i < 100; i++)
- {
- uint256 k = (~uint256(0) << i);
- printf("%s\n", k.ToString().c_str());
- }
-
- return (0);
-}
+// Copyright (c) 2009-2010 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +#include <limits.h> +#include <string> +#if defined(_MSC_VER) || defined(__BORLANDC__) +typedef __int64 int64; +typedef unsigned __int64 uint64; +#else +typedef long long int64; +typedef unsigned long long uint64; +#endif +#if defined(_MSC_VER) && _MSC_VER < 1300 +#define for if (false) ; else for +#endif + + +inline int Testuint256AdHoc(vector<string> vArg); + + + +// We have to keep a separate base class without constructors +// so the compiler will let us use it in a union +template<unsigned int BITS> +class base_uint +{ +protected: + enum { WIDTH=BITS/32 }; + unsigned int pn[WIDTH]; +public: + + bool operator!() const + { + for (int i = 0; i < WIDTH; i++) + if (pn[i] != 0) + return false; + return true; + } + + const base_uint operator~() const + { + base_uint ret; + for (int i = 0; i < WIDTH; i++) + ret.pn[i] = ~pn[i]; + return ret; + } + + const base_uint operator-() const + { + base_uint ret; + for (int i = 0; i < WIDTH; i++) + ret.pn[i] = ~pn[i]; + ret++; + return ret; + } + + + base_uint& operator=(uint64 b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + return *this; + } + + base_uint& operator^=(const base_uint& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] ^= b.pn[i]; + return *this; + } + + base_uint& operator&=(const base_uint& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] &= b.pn[i]; + return *this; + } + + base_uint& operator|=(const base_uint& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] |= b.pn[i]; + return *this; + } + + base_uint& operator^=(uint64 b) + { + pn[0] ^= (unsigned int)b; + pn[1] ^= (unsigned int)(b >> 32); + return *this; + } + + base_uint& operator&=(uint64 b) + { + pn[0] &= (unsigned int)b; + pn[1] &= (unsigned int)(b >> 32); + return *this; + } + + base_uint& operator|=(uint64 b) + { + pn[0] |= (unsigned int)b; + pn[1] |= (unsigned int)(b >> 32); + return *this; + } + + base_uint& operator<<=(unsigned int shift) + { + base_uint a(*this); + for (int i = 0; i < WIDTH; i++) + pn[i] = 0; + 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); + } + return *this; + } + + base_uint& operator>>=(unsigned int shift) + { + base_uint a(*this); + for (int i = 0; i < WIDTH; i++) + pn[i] = 0; + 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); + } + return *this; + } + + base_uint& operator+=(const base_uint& b) + { + uint64 carry = 0; + for (int i = 0; i < WIDTH; i++) + { + uint64 n = carry + pn[i] + b.pn[i]; + pn[i] = n & 0xffffffff; + carry = n >> 32; + } + return *this; + } + + base_uint& operator-=(const base_uint& b) + { + *this += -b; + return *this; + } + + base_uint& operator+=(uint64 b64) + { + base_uint b; + b = b64; + *this += b; + return *this; + } + + base_uint& operator-=(uint64 b64) + { + base_uint b; + b = b64; + *this += -b; + return *this; + } + + + base_uint& operator++() + { + // prefix operator + int i = 0; + while (++pn[i] == 0 && i < WIDTH-1) + i++; + return *this; + } + + const base_uint operator++(int) + { + // postfix operator + const base_uint ret = *this; + ++(*this); + return ret; + } + + base_uint& operator--() + { + // prefix operator + int i = 0; + while (--pn[i] == -1 && i < WIDTH-1) + i++; + return *this; + } + + const base_uint operator--(int) + { + // postfix operator + const base_uint ret = *this; + --(*this); + return ret; + } + + + friend inline bool operator<(const base_uint& a, const base_uint& b) + { + for (int i = base_uint::WIDTH-1; i >= 0; i--) + { + if (a.pn[i] < b.pn[i]) + return true; + else if (a.pn[i] > b.pn[i]) + return false; + } + return false; + } + + friend inline bool operator<=(const base_uint& a, const base_uint& b) + { + for (int i = base_uint::WIDTH-1; i >= 0; i--) + { + if (a.pn[i] < b.pn[i]) + return true; + else if (a.pn[i] > b.pn[i]) + return false; + } + return true; + } + + friend inline bool operator>(const base_uint& a, const base_uint& b) + { + for (int i = base_uint::WIDTH-1; i >= 0; i--) + { + if (a.pn[i] > b.pn[i]) + return true; + else if (a.pn[i] < b.pn[i]) + return false; + } + return false; + } + + friend inline bool operator>=(const base_uint& a, const base_uint& b) + { + for (int i = base_uint::WIDTH-1; i >= 0; i--) + { + if (a.pn[i] > b.pn[i]) + return true; + else if (a.pn[i] < b.pn[i]) + return false; + } + return true; + } + + friend inline bool operator==(const base_uint& a, const base_uint& b) + { + for (int i = 0; i < base_uint::WIDTH; i++) + if (a.pn[i] != b.pn[i]) + return false; + return true; + } + + friend inline bool operator==(const base_uint& a, uint64 b) + { + if (a.pn[0] != (unsigned int)b) + return false; + if (a.pn[1] != (unsigned int)(b >> 32)) + return false; + for (int i = 2; i < base_uint::WIDTH; i++) + if (a.pn[i] != 0) + return false; + return true; + } + + friend inline bool operator!=(const base_uint& a, const base_uint& b) + { + return (!(a == b)); + } + + friend inline bool operator!=(const base_uint& a, uint64 b) + { + return (!(a == b)); + } + + + + std::string GetHex() const + { + char psz[sizeof(pn)*2 + 1]; + for (int i = 0; i < sizeof(pn); i++) + sprintf(psz + i*2, "%02x", ((unsigned char*)pn)[sizeof(pn) - i - 1]); + return string(psz, psz + sizeof(pn)*2); + } + + void SetHex(const char* psz) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = 0; + + // skip leading spaces + while (isspace(*psz)) + psz++; + + // skip 0x + if (psz[0] == '0' && tolower(psz[1]) == 'x') + psz += 2; + + // hex string to uint + static char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 }; + const char* pbegin = psz; + while (phexdigit[*psz] || *psz == '0') + psz++; + psz--; + unsigned char* p1 = (unsigned char*)pn; + unsigned char* pend = p1 + WIDTH * 4; + while (psz >= pbegin && p1 < pend) + { + *p1 = phexdigit[(unsigned char)*psz--]; + if (psz >= pbegin) + { + *p1 |= (phexdigit[(unsigned char)*psz--] << 4); + p1++; + } + } + } + + void SetHex(const std::string& str) + { + SetHex(str.c_str()); + } + + std::string ToString() const + { + return (GetHex()); + } + + unsigned char* begin() + { + return (unsigned char*)&pn[0]; + } + + unsigned char* end() + { + return (unsigned char*)&pn[WIDTH]; + } + + unsigned int size() + { + return sizeof(pn); + } + + + unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const + { + return sizeof(pn); + } + + template<typename Stream> + void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const + { + s.write((char*)pn, sizeof(pn)); + } + + template<typename Stream> + void Unserialize(Stream& s, int nType=0, int nVersion=VERSION) + { + s.read((char*)pn, sizeof(pn)); + } + + + friend class uint160; + friend class uint256; + friend inline int Testuint256AdHoc(vector<string> vArg); +}; + +typedef base_uint<160> base_uint160; +typedef base_uint<256> base_uint256; + + + +// +// uint160 and uint256 could be implemented as templates, but to keep +// compile errors and debugging cleaner, they're copy and pasted. +// + + + +////////////////////////////////////////////////////////////////////////////// +// +// uint160 +// + +class uint160 : public base_uint160 +{ +public: + typedef base_uint160 basetype; + + uint160() + { + for (int i = 0; i < WIDTH; i++) + pn[i] = 0; + } + + uint160(const basetype& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = b.pn[i]; + } + + uint160& operator=(const basetype& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = b.pn[i]; + return *this; + } + + uint160(uint64 b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + } + + uint160& operator=(uint64 b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + return *this; + } + + explicit uint160(const std::string& str) + { + SetHex(str); + } + + explicit uint160(const std::vector<unsigned char>& vch) + { + if (vch.size() == sizeof(pn)) + memcpy(pn, &vch[0], sizeof(pn)); + else + *this = 0; + } +}; + +inline bool operator==(const uint160& a, uint64 b) { return (base_uint160)a == b; } +inline bool operator!=(const uint160& a, uint64 b) { return (base_uint160)a != b; } +inline const uint160 operator<<(const base_uint160& a, unsigned int shift) { return uint160(a) <<= shift; } +inline const uint160 operator>>(const base_uint160& a, unsigned int shift) { return uint160(a) >>= shift; } +inline const uint160 operator<<(const uint160& a, unsigned int shift) { return uint160(a) <<= shift; } +inline const uint160 operator>>(const uint160& a, unsigned int shift) { return uint160(a) >>= shift; } + +inline const uint160 operator^(const base_uint160& a, const base_uint160& b) { return uint160(a) ^= b; } +inline const uint160 operator&(const base_uint160& a, const base_uint160& b) { return uint160(a) &= b; } +inline const uint160 operator|(const base_uint160& a, const base_uint160& b) { return uint160(a) |= b; } +inline const uint160 operator+(const base_uint160& a, const base_uint160& b) { return uint160(a) += b; } +inline const uint160 operator-(const base_uint160& a, const base_uint160& b) { return uint160(a) -= b; } + +inline bool operator<(const base_uint160& a, const uint160& b) { return (base_uint160)a < (base_uint160)b; } +inline bool operator<=(const base_uint160& a, const uint160& b) { return (base_uint160)a <= (base_uint160)b; } +inline bool operator>(const base_uint160& a, const uint160& b) { return (base_uint160)a > (base_uint160)b; } +inline bool operator>=(const base_uint160& a, const uint160& b) { return (base_uint160)a >= (base_uint160)b; } +inline bool operator==(const base_uint160& a, const uint160& b) { return (base_uint160)a == (base_uint160)b; } +inline bool operator!=(const base_uint160& a, const uint160& b) { return (base_uint160)a != (base_uint160)b; } +inline const uint160 operator^(const base_uint160& a, const uint160& b) { return (base_uint160)a ^ (base_uint160)b; } +inline const uint160 operator&(const base_uint160& a, const uint160& b) { return (base_uint160)a & (base_uint160)b; } +inline const uint160 operator|(const base_uint160& a, const uint160& b) { return (base_uint160)a | (base_uint160)b; } +inline const uint160 operator+(const base_uint160& a, const uint160& b) { return (base_uint160)a + (base_uint160)b; } +inline const uint160 operator-(const base_uint160& a, const uint160& b) { return (base_uint160)a - (base_uint160)b; } + +inline bool operator<(const uint160& a, const base_uint160& b) { return (base_uint160)a < (base_uint160)b; } +inline bool operator<=(const uint160& a, const base_uint160& b) { return (base_uint160)a <= (base_uint160)b; } +inline bool operator>(const uint160& a, const base_uint160& b) { return (base_uint160)a > (base_uint160)b; } +inline bool operator>=(const uint160& a, const base_uint160& b) { return (base_uint160)a >= (base_uint160)b; } +inline bool operator==(const uint160& a, const base_uint160& b) { return (base_uint160)a == (base_uint160)b; } +inline bool operator!=(const uint160& a, const base_uint160& b) { return (base_uint160)a != (base_uint160)b; } +inline const uint160 operator^(const uint160& a, const base_uint160& b) { return (base_uint160)a ^ (base_uint160)b; } +inline const uint160 operator&(const uint160& a, const base_uint160& b) { return (base_uint160)a & (base_uint160)b; } +inline const uint160 operator|(const uint160& a, const base_uint160& b) { return (base_uint160)a | (base_uint160)b; } +inline const uint160 operator+(const uint160& a, const base_uint160& b) { return (base_uint160)a + (base_uint160)b; } +inline const uint160 operator-(const uint160& a, const base_uint160& b) { return (base_uint160)a - (base_uint160)b; } + +inline bool operator<(const uint160& a, const uint160& b) { return (base_uint160)a < (base_uint160)b; } +inline bool operator<=(const uint160& a, const uint160& b) { return (base_uint160)a <= (base_uint160)b; } +inline bool operator>(const uint160& a, const uint160& b) { return (base_uint160)a > (base_uint160)b; } +inline bool operator>=(const uint160& a, const uint160& b) { return (base_uint160)a >= (base_uint160)b; } +inline bool operator==(const uint160& a, const uint160& b) { return (base_uint160)a == (base_uint160)b; } +inline bool operator!=(const uint160& a, const uint160& b) { return (base_uint160)a != (base_uint160)b; } +inline const uint160 operator^(const uint160& a, const uint160& b) { return (base_uint160)a ^ (base_uint160)b; } +inline const uint160 operator&(const uint160& a, const uint160& b) { return (base_uint160)a & (base_uint160)b; } +inline const uint160 operator|(const uint160& a, const uint160& b) { return (base_uint160)a | (base_uint160)b; } +inline const uint160 operator+(const uint160& a, const uint160& b) { return (base_uint160)a + (base_uint160)b; } +inline const uint160 operator-(const uint160& a, const uint160& b) { return (base_uint160)a - (base_uint160)b; } + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// uint256 +// + +class uint256 : public base_uint256 +{ +public: + typedef base_uint256 basetype; + + uint256() + { + for (int i = 0; i < WIDTH; i++) + pn[i] = 0; + } + + uint256(const basetype& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = b.pn[i]; + } + + uint256& operator=(const basetype& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = b.pn[i]; + return *this; + } + + uint256(uint64 b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + } + + uint256& operator=(uint64 b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + return *this; + } + + explicit uint256(const std::string& str) + { + SetHex(str); + } + + explicit uint256(const std::vector<unsigned char>& vch) + { + if (vch.size() == sizeof(pn)) + memcpy(pn, &vch[0], sizeof(pn)); + else + *this = 0; + } +}; + +inline bool operator==(const uint256& a, uint64 b) { return (base_uint256)a == b; } +inline bool operator!=(const uint256& a, uint64 b) { return (base_uint256)a != b; } +inline const uint256 operator<<(const base_uint256& a, unsigned int shift) { return uint256(a) <<= shift; } +inline const uint256 operator>>(const base_uint256& a, unsigned int shift) { return uint256(a) >>= shift; } +inline const uint256 operator<<(const uint256& a, unsigned int shift) { return uint256(a) <<= shift; } +inline const uint256 operator>>(const uint256& a, unsigned int shift) { return uint256(a) >>= shift; } + +inline const uint256 operator^(const base_uint256& a, const base_uint256& b) { return uint256(a) ^= b; } +inline const uint256 operator&(const base_uint256& a, const base_uint256& b) { return uint256(a) &= b; } +inline const uint256 operator|(const base_uint256& a, const base_uint256& b) { return uint256(a) |= b; } +inline const uint256 operator+(const base_uint256& a, const base_uint256& b) { return uint256(a) += b; } +inline const uint256 operator-(const base_uint256& a, const base_uint256& b) { return uint256(a) -= b; } + +inline bool operator<(const base_uint256& a, const uint256& b) { return (base_uint256)a < (base_uint256)b; } +inline bool operator<=(const base_uint256& a, const uint256& b) { return (base_uint256)a <= (base_uint256)b; } +inline bool operator>(const base_uint256& a, const uint256& b) { return (base_uint256)a > (base_uint256)b; } +inline bool operator>=(const base_uint256& a, const uint256& b) { return (base_uint256)a >= (base_uint256)b; } +inline bool operator==(const base_uint256& a, const uint256& b) { return (base_uint256)a == (base_uint256)b; } +inline bool operator!=(const base_uint256& a, const uint256& b) { return (base_uint256)a != (base_uint256)b; } +inline const uint256 operator^(const base_uint256& a, const uint256& b) { return (base_uint256)a ^ (base_uint256)b; } +inline const uint256 operator&(const base_uint256& a, const uint256& b) { return (base_uint256)a & (base_uint256)b; } +inline const uint256 operator|(const base_uint256& a, const uint256& b) { return (base_uint256)a | (base_uint256)b; } +inline const uint256 operator+(const base_uint256& a, const uint256& b) { return (base_uint256)a + (base_uint256)b; } +inline const uint256 operator-(const base_uint256& a, const uint256& b) { return (base_uint256)a - (base_uint256)b; } + +inline bool operator<(const uint256& a, const base_uint256& b) { return (base_uint256)a < (base_uint256)b; } +inline bool operator<=(const uint256& a, const base_uint256& b) { return (base_uint256)a <= (base_uint256)b; } +inline bool operator>(const uint256& a, const base_uint256& b) { return (base_uint256)a > (base_uint256)b; } +inline bool operator>=(const uint256& a, const base_uint256& b) { return (base_uint256)a >= (base_uint256)b; } +inline bool operator==(const uint256& a, const base_uint256& b) { return (base_uint256)a == (base_uint256)b; } +inline bool operator!=(const uint256& a, const base_uint256& b) { return (base_uint256)a != (base_uint256)b; } +inline const uint256 operator^(const uint256& a, const base_uint256& b) { return (base_uint256)a ^ (base_uint256)b; } +inline const uint256 operator&(const uint256& a, const base_uint256& b) { return (base_uint256)a & (base_uint256)b; } +inline const uint256 operator|(const uint256& a, const base_uint256& b) { return (base_uint256)a | (base_uint256)b; } +inline const uint256 operator+(const uint256& a, const base_uint256& b) { return (base_uint256)a + (base_uint256)b; } +inline const uint256 operator-(const uint256& a, const base_uint256& b) { return (base_uint256)a - (base_uint256)b; } + +inline bool operator<(const uint256& a, const uint256& b) { return (base_uint256)a < (base_uint256)b; } +inline bool operator<=(const uint256& a, const uint256& b) { return (base_uint256)a <= (base_uint256)b; } +inline bool operator>(const uint256& a, const uint256& b) { return (base_uint256)a > (base_uint256)b; } +inline bool operator>=(const uint256& a, const uint256& b) { return (base_uint256)a >= (base_uint256)b; } +inline bool operator==(const uint256& a, const uint256& b) { return (base_uint256)a == (base_uint256)b; } +inline bool operator!=(const uint256& a, const uint256& b) { return (base_uint256)a != (base_uint256)b; } +inline const uint256 operator^(const uint256& a, const uint256& b) { return (base_uint256)a ^ (base_uint256)b; } +inline const uint256 operator&(const uint256& a, const uint256& b) { return (base_uint256)a & (base_uint256)b; } +inline const uint256 operator|(const uint256& a, const uint256& b) { return (base_uint256)a | (base_uint256)b; } +inline const uint256 operator+(const uint256& a, const uint256& b) { return (base_uint256)a + (base_uint256)b; } +inline const uint256 operator-(const uint256& a, const uint256& b) { return (base_uint256)a - (base_uint256)b; } + + + + + + + + + + + + +inline int Testuint256AdHoc(vector<string> vArg) +{ + uint256 g(0); + + + printf("%s\n", g.ToString().c_str()); + g--; printf("g--\n"); + printf("%s\n", g.ToString().c_str()); + g--; printf("g--\n"); + printf("%s\n", g.ToString().c_str()); + g++; printf("g++\n"); + printf("%s\n", g.ToString().c_str()); + g++; printf("g++\n"); + printf("%s\n", g.ToString().c_str()); + g++; printf("g++\n"); + printf("%s\n", g.ToString().c_str()); + g++; printf("g++\n"); + printf("%s\n", g.ToString().c_str()); + + + + uint256 a(7); + printf("a=7\n"); + printf("%s\n", a.ToString().c_str()); + + uint256 b; + printf("b undefined\n"); + printf("%s\n", b.ToString().c_str()); + int c = 3; + + a = c; + a.pn[3] = 15; + printf("%s\n", a.ToString().c_str()); + uint256 k(c); + + a = 5; + a.pn[3] = 15; + printf("%s\n", a.ToString().c_str()); + b = 1; + b <<= 52; + + a |= b; + + a ^= 0x500; + + printf("a %s\n", a.ToString().c_str()); + + a = a | b | (uint256)0x1000; + + + printf("a %s\n", a.ToString().c_str()); + printf("b %s\n", b.ToString().c_str()); + + a = 0xfffffffe; + a.pn[4] = 9; + + printf("%s\n", a.ToString().c_str()); + a++; + printf("%s\n", a.ToString().c_str()); + a++; + printf("%s\n", a.ToString().c_str()); + a++; + printf("%s\n", a.ToString().c_str()); + a++; + printf("%s\n", a.ToString().c_str()); + + a--; + printf("%s\n", a.ToString().c_str()); + a--; + printf("%s\n", a.ToString().c_str()); + a--; + printf("%s\n", a.ToString().c_str()); + uint256 d = a--; + printf("%s\n", d.ToString().c_str()); + printf("%s\n", a.ToString().c_str()); + a--; + printf("%s\n", a.ToString().c_str()); + a--; + printf("%s\n", a.ToString().c_str()); + + d = a; + + printf("%s\n", d.ToString().c_str()); + for (int i = uint256::WIDTH-1; i >= 0; i--) printf("%08x", d.pn[i]); printf("\n"); + + uint256 neg = d; + neg = ~neg; + printf("%s\n", neg.ToString().c_str()); + + + uint256 e = uint256("0xABCDEF123abcdef12345678909832180000011111111"); + printf("\n"); + printf("%s\n", e.ToString().c_str()); + + + printf("\n"); + uint256 x1 = uint256("0xABCDEF123abcdef12345678909832180000011111111"); + uint256 x2; + printf("%s\n", x1.ToString().c_str()); + for (int i = 0; i < 270; i += 4) + { + x2 = x1 << i; + printf("%s\n", x2.ToString().c_str()); + } + + printf("\n"); + printf("%s\n", x1.ToString().c_str()); + for (int i = 0; i < 270; i += 4) + { + x2 = x1; + x2 >>= i; + printf("%s\n", x2.ToString().c_str()); + } + + + for (int i = 0; i < 100; i++) + { + uint256 k = (~uint256(0) >> i); + printf("%s\n", k.ToString().c_str()); + } + + for (int i = 0; i < 100; i++) + { + uint256 k = (~uint256(0) << i); + printf("%s\n", k.ToString().c_str()); + } + + return (0); +} diff --git a/uiproject.fbp b/uiproject.fbp index 4753924d9f..54e010bdda 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -1,6332 +1,6332 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<wxFormBuilder_Project>
- <FileVersion major="1" minor="9" />
- <object class="Project" expanded="1">
- <property name="class_decoration"></property>
- <property name="code_generation">C++</property>
- <property name="disconnect_events">1</property>
- <property name="encoding">UTF-8</property>
- <property name="event_generation">connect</property>
- <property name="file">uibase</property>
- <property name="first_id">1000</property>
- <property name="help_provider">none</property>
- <property name="internationalize">1</property>
- <property name="name"></property>
- <property name="namespace"></property>
- <property name="path">.</property>
- <property name="precompiled_header"></property>
- <property name="relative_path">1</property>
- <property name="use_enum">0</property>
- <property name="use_microsoft_bom">0</property>
- <object class="Frame" expanded="0">
- <property name="bg">wxSYS_COLOUR_BTNFACE</property>
- <property name="center"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="extra_style"></property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_MAINFRAME</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">CMainFrameBase</property>
- <property name="pos"></property>
- <property name="size">723,484</property>
- <property name="style">wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER</property>
- <property name="subclass"></property>
- <property name="title">Bitcoin</property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style">wxTAB_TRAVERSAL</property>
- <property name="xrc_skip_sizer">1</property>
- <event name="OnActivate"></event>
- <event name="OnActivateApp"></event>
- <event name="OnChar"></event>
- <event name="OnClose">OnClose</event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnHibernate"></event>
- <event name="OnIconize">OnIconize</event>
- <event name="OnIdle">OnIdle</event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents">OnMouseEvents</event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint">OnPaint</event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxMenuBar" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">MyMenuBar</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_menubar</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxMenu" expanded="1">
- <property name="label">&File</property>
- <property name="name">m_menuFile</property>
- <property name="permission">protected</property>
- <object class="wxMenuItem" expanded="1">
- <property name="bitmap"></property>
- <property name="checked">0</property>
- <property name="enabled">1</property>
- <property name="help"></property>
- <property name="id">wxID_EXIT</property>
- <property name="kind">wxITEM_NORMAL</property>
- <property name="label">E&xit</property>
- <property name="name">m_menuFileExit</property>
- <property name="permission">none</property>
- <property name="shortcut"></property>
- <property name="unchecked_bitmap"></property>
- <event name="OnMenuSelection">OnMenuFileExit</event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="wxMenu" expanded="1">
- <property name="label">&Settings</property>
- <property name="name">m_menuOptions</property>
- <property name="permission">public</property>
- <object class="wxMenuItem" expanded="1">
- <property name="bitmap"></property>
- <property name="checked">0</property>
- <property name="enabled">1</property>
- <property name="help"></property>
- <property name="id">wxID_OPTIONSGENERATEBITCOINS</property>
- <property name="kind">wxITEM_CHECK</property>
- <property name="label">&Generate Coins</property>
- <property name="name">m_menuOptionsGenerateBitcoins</property>
- <property name="permission">none</property>
- <property name="shortcut"></property>
- <property name="unchecked_bitmap"></property>
- <event name="OnMenuSelection">OnMenuOptionsGenerate</event>
- <event name="OnUpdateUI">OnUpdateUIOptionsGenerate</event>
- </object>
- <object class="wxMenuItem" expanded="1">
- <property name="bitmap"></property>
- <property name="checked">0</property>
- <property name="enabled">1</property>
- <property name="help"></property>
- <property name="id">wxID_ANY</property>
- <property name="kind">wxITEM_NORMAL</property>
- <property name="label">&Your Receiving Addresses...</property>
- <property name="name">m_menuOptionsChangeYourAddress</property>
- <property name="permission">none</property>
- <property name="shortcut"></property>
- <property name="unchecked_bitmap"></property>
- <event name="OnMenuSelection">OnMenuOptionsChangeYourAddress</event>
- <event name="OnUpdateUI"></event>
- </object>
- <object class="wxMenuItem" expanded="1">
- <property name="bitmap"></property>
- <property name="checked">0</property>
- <property name="enabled">1</property>
- <property name="help"></property>
- <property name="id">wxID_PREFERENCES</property>
- <property name="kind">wxITEM_NORMAL</property>
- <property name="label">&Options...</property>
- <property name="name">m_menuOptionsOptions</property>
- <property name="permission">none</property>
- <property name="shortcut"></property>
- <property name="unchecked_bitmap"></property>
- <event name="OnMenuSelection">OnMenuOptionsOptions</event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="wxMenu" expanded="1">
- <property name="label">&Help</property>
- <property name="name">m_menuHelp</property>
- <property name="permission">protected</property>
- <object class="wxMenuItem" expanded="1">
- <property name="bitmap"></property>
- <property name="checked">0</property>
- <property name="enabled">1</property>
- <property name="help"></property>
- <property name="id">wxID_ABOUT</property>
- <property name="kind">wxITEM_NORMAL</property>
- <property name="label">&About...</property>
- <property name="name">m_menuHelpAbout</property>
- <property name="permission">none</property>
- <property name="shortcut"></property>
- <property name="unchecked_bitmap"></property>
- <event name="OnMenuSelection">OnMenuHelpAbout</event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- <object class="wxToolBar" expanded="1">
- <property name="bg"></property>
- <property name="bitmapsize">20,20</property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font">,90,90,-1,70,0</property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="margins"></property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_toolBar</property>
- <property name="packing">1</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="separation">1</property>
- <property name="size">-1,-1</property>
- <property name="style">wxTB_FLAT|wxTB_HORZ_TEXT</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="tool" expanded="1">
- <property name="bitmap">xpm/send20.xpm; Load From File</property>
- <property name="id">wxID_BUTTONSEND</property>
- <property name="kind">wxITEM_NORMAL</property>
- <property name="label">Send Coins</property>
- <property name="name">m_tool1</property>
- <property name="statusbar"></property>
- <property name="tooltip"></property>
- <event name="OnMenuSelection"></event>
- <event name="OnToolClicked">OnButtonSend</event>
- <event name="OnToolEnter"></event>
- <event name="OnToolRClicked"></event>
- <event name="OnUpdateUI"></event>
- </object>
- <object class="tool" expanded="1">
- <property name="bitmap">xpm/addressbook20.xpm; Load From File</property>
- <property name="id">wxID_BUTTONRECEIVE</property>
- <property name="kind">wxITEM_NORMAL</property>
- <property name="label">Address Book</property>
- <property name="name">m_tool2</property>
- <property name="statusbar"></property>
- <property name="tooltip"></property>
- <event name="OnMenuSelection"></event>
- <event name="OnToolClicked">OnButtonAddressBook</event>
- <event name="OnToolEnter"></event>
- <event name="OnToolRClicked"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="wxStatusBar" expanded="1">
- <property name="bg">240,240,240</property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="fields">1</property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_statusBar</property>
- <property name="permission">public</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style">wxST_SIZEGRIP</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer2</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="spacer" expanded="1">
- <property name="height">2</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
- <property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer85</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">Your Bitcoin Address:</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticText32</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
- <property name="proportion">0</property>
- <object class="wxTextCtrl" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_TEXTCTRLADDRESS</property>
- <property name="maximum_size">-1,-1</property>
- <property name="maxlength">0</property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_textCtrlAddress</property>
- <property name="permission">public</property>
- <property name="pos"></property>
- <property name="size">340,-1</property>
- <property name="style">wxTE_READONLY</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="value"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown">OnKeyDown</event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents">OnMouseEventsAddress</event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus">OnSetFocusAddress</event>
- <event name="OnSize"></event>
- <event name="OnText"></event>
- <event name="OnTextEnter"></event>
- <event name="OnTextMaxLen"></event>
- <event name="OnTextURL"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxRIGHT|wxALIGN_CENTER_VERTICAL</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_BUTTONNEW</property>
- <property name="label"> &New... </property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_buttonNew</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style">wxBU_EXACTFIT</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonNew</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_BUTTONCOPY</property>
- <property name="label"> &Copy to Clipboard </property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_buttonCopy</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style">wxBU_EXACTFIT</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonCopy</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="spacer" expanded="1">
- <property name="height">0</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer3</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND|wxALL</property>
- <property name="proportion">1</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer66</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">Balance:</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticText41</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,15</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg">255,255,255</property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font">,90,90,8,70,0</property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label"></property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticTextBalance</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">120,15</property>
- <property name="style">wxALIGN_RIGHT|wxST_NO_AUTORESIZE</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="spacer" expanded="1">
- <property name="height">0</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_BOTTOM|wxTOP|wxRIGHT|wxLEFT</property>
- <property name="proportion">0</property>
- <object class="wxChoice" expanded="1">
- <property name="bg"></property>
- <property name="choices">" All" " Sent" " Received" " In Progress"</property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">1</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_choiceFilter</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="selection">0</property>
- <property name="size">110,-1</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnChoice"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="wxNotebook" expanded="1">
- <property name="bg"></property>
- <property name="bitmapsize"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_notebook</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnNotebookPageChanged">OnNotebookPageChanged</event>
- <event name="OnNotebookPageChanging"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="notebookpage" expanded="1">
- <property name="bitmap"></property>
- <property name="label">All Transactions</property>
- <property name="select">1</property>
- <object class="wxPanel" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_panel9</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style">wxTAB_TRAVERSAL</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer11</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="wxListCtrl" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_listCtrlAll</property>
- <property name="permission">public</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style">wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnListBeginDrag"></event>
- <event name="OnListBeginLabelEdit"></event>
- <event name="OnListBeginRDrag"></event>
- <event name="OnListCacheHint"></event>
- <event name="OnListColBeginDrag">OnListColBeginDrag</event>
- <event name="OnListColClick"></event>
- <event name="OnListColDragging"></event>
- <event name="OnListColEndDrag"></event>
- <event name="OnListColRightClick"></event>
- <event name="OnListDeleteAllItems"></event>
- <event name="OnListDeleteItem"></event>
- <event name="OnListEndLabelEdit"></event>
- <event name="OnListInsertItem"></event>
- <event name="OnListItemActivated">OnListItemActivated</event>
- <event name="OnListItemDeselected"></event>
- <event name="OnListItemFocused"></event>
- <event name="OnListItemMiddleClick"></event>
- <event name="OnListItemRightClick"></event>
- <event name="OnListItemSelected"></event>
- <event name="OnListKeyDown"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint">OnPaintListCtrl</event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="notebookpage" expanded="1">
- <property name="bitmap"></property>
- <property name="label">Sent/Received</property>
- <property name="select">0</property>
- <object class="wxPanel" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_panel91</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style">wxTAB_TRAVERSAL</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer111</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="wxListCtrl" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_listCtrlSentReceived</property>
- <property name="permission">public</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style">wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnListBeginDrag"></event>
- <event name="OnListBeginLabelEdit"></event>
- <event name="OnListBeginRDrag"></event>
- <event name="OnListCacheHint"></event>
- <event name="OnListColBeginDrag">OnListColBeginDrag</event>
- <event name="OnListColClick"></event>
- <event name="OnListColDragging"></event>
- <event name="OnListColEndDrag"></event>
- <event name="OnListColRightClick"></event>
- <event name="OnListDeleteAllItems"></event>
- <event name="OnListDeleteItem"></event>
- <event name="OnListEndLabelEdit"></event>
- <event name="OnListInsertItem"></event>
- <event name="OnListItemActivated">OnListItemActivated</event>
- <event name="OnListItemDeselected"></event>
- <event name="OnListItemFocused"></event>
- <event name="OnListItemMiddleClick"></event>
- <event name="OnListItemRightClick"></event>
- <event name="OnListItemSelected"></event>
- <event name="OnListKeyDown"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint">OnPaintListCtrl</event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="notebookpage" expanded="1">
- <property name="bitmap"></property>
- <property name="label">Sent</property>
- <property name="select">0</property>
- <object class="wxPanel" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_panel92</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style">wxTAB_TRAVERSAL</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer112</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="wxListCtrl" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_listCtrlSent</property>
- <property name="permission">public</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style">wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnListBeginDrag"></event>
- <event name="OnListBeginLabelEdit"></event>
- <event name="OnListBeginRDrag"></event>
- <event name="OnListCacheHint"></event>
- <event name="OnListColBeginDrag">OnListColBeginDrag</event>
- <event name="OnListColClick"></event>
- <event name="OnListColDragging"></event>
- <event name="OnListColEndDrag"></event>
- <event name="OnListColRightClick"></event>
- <event name="OnListDeleteAllItems"></event>
- <event name="OnListDeleteItem"></event>
- <event name="OnListEndLabelEdit"></event>
- <event name="OnListInsertItem"></event>
- <event name="OnListItemActivated">OnListItemActivated</event>
- <event name="OnListItemDeselected"></event>
- <event name="OnListItemFocused"></event>
- <event name="OnListItemMiddleClick"></event>
- <event name="OnListItemRightClick"></event>
- <event name="OnListItemSelected"></event>
- <event name="OnListKeyDown"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint">OnPaintListCtrl</event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="notebookpage" expanded="1">
- <property name="bitmap"></property>
- <property name="label">Received</property>
- <property name="select">0</property>
- <object class="wxPanel" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_panel93</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style">wxTAB_TRAVERSAL</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer113</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="wxListCtrl" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_listCtrlReceived</property>
- <property name="permission">public</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style">wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnListBeginDrag"></event>
- <event name="OnListBeginLabelEdit"></event>
- <event name="OnListBeginRDrag"></event>
- <event name="OnListCacheHint"></event>
- <event name="OnListColBeginDrag">OnListColBeginDrag</event>
- <event name="OnListColClick"></event>
- <event name="OnListColDragging"></event>
- <event name="OnListColEndDrag"></event>
- <event name="OnListColRightClick"></event>
- <event name="OnListDeleteAllItems"></event>
- <event name="OnListDeleteItem"></event>
- <event name="OnListEndLabelEdit"></event>
- <event name="OnListInsertItem"></event>
- <event name="OnListItemActivated">OnListItemActivated</event>
- <event name="OnListItemDeselected"></event>
- <event name="OnListItemFocused"></event>
- <event name="OnListItemMiddleClick"></event>
- <event name="OnListItemRightClick"></event>
- <event name="OnListItemSelected"></event>
- <event name="OnListKeyDown"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint">OnPaintListCtrl</event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="Dialog" expanded="0">
- <property name="bg"></property>
- <property name="center"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="extra_style"></property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">CTxDetailsDialogBase</property>
- <property name="pos"></property>
- <property name="size">620,450</property>
- <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
- <property name="subclass"></property>
- <property name="title">Transaction Details</property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnActivate"></event>
- <event name="OnActivateApp"></event>
- <event name="OnChar"></event>
- <event name="OnClose"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnHibernate"></event>
- <event name="OnIconize"></event>
- <event name="OnIdle"></event>
- <event name="OnInitDialog"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer64</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer66</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="wxHtmlWindow" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_htmlWin</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style">wxHW_SCROLLBAR_AUTO</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnHtmlCellClicked"></event>
- <event name="OnHtmlCellHover"></event>
- <event name="OnHtmlLinkClicked"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_RIGHT</property>
- <property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer65</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_OK</property>
- <property name="label">OK</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_buttonOK</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonOK</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="Dialog" expanded="0">
- <property name="bg"></property>
- <property name="center"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="extra_style"></property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">COptionsDialogBase</property>
- <property name="pos"></property>
- <property name="size">540,360</property>
- <property name="style">wxDEFAULT_DIALOG_STYLE</property>
- <property name="subclass"></property>
- <property name="title">Options</property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnActivate"></event>
- <event name="OnActivateApp"></event>
- <event name="OnChar"></event>
- <event name="OnClose"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnHibernate"></event>
- <event name="OnIconize"></event>
- <event name="OnIdle"></event>
- <event name="OnInitDialog"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="0">
- <property name="minimum_size"></property>
- <property name="name">bSizer55</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">9</property>
- <property name="flag">wxEXPAND|wxALL</property>
- <property name="proportion">1</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer66</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND|wxRIGHT</property>
- <property name="proportion">0</property>
- <object class="wxListBox" expanded="1">
- <property name="bg"></property>
- <property name="choices"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_listBox</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">110,-1</property>
- <property name="style">wxLB_NEEDED_SB|wxLB_SINGLE</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnListBox">OnListBox</event>
- <event name="OnListBoxDClick"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND|wxLEFT</property>
- <property name="proportion">1</property>
- <object class="wxScrolledWindow" expanded="0">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_scrolledWindow</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="scroll_rate_x">5</property>
- <property name="scroll_rate_y">5</property>
- <property name="size"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer63</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxPanel" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_panelMain</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style">wxTAB_TRAVERSAL</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer69</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="spacer" expanded="1">
- <property name="height">16</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">1</property>
- <property name="id">wxID_ANY</property>
- <property name="label">Optional transaction fee you give to the nodes that process your transactions.</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticText32</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer56</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">1</property>
- <property name="id">wxID_ANY</property>
- <property name="label">Transaction fee:</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticText31</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
- <property name="proportion">0</property>
- <object class="wxTextCtrl" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">1</property>
- <property name="id">wxID_TRANSACTIONFEE</property>
- <property name="maximum_size"></property>
- <property name="maxlength">0</property>
- <property name="minimum_size"></property>
- <property name="name">m_textCtrlTransactionFee</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">70,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="value"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus">OnKillFocusTransactionFee</event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnText"></event>
- <event name="OnTextEnter"></event>
- <event name="OnTextMaxLen"></event>
- <event name="OnTextURL"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag"></property>
- <property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer71</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
- <property name="proportion">0</property>
- <object class="wxCheckBox" expanded="1">
- <property name="bg"></property>
- <property name="checked">0</property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">&Limit coin generation to</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_checkBoxLimitProcessors</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnCheckBox">OnCheckBoxLimitProcessors</event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL</property>
- <property name="proportion">0</property>
- <object class="wxSpinCtrl" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="initial">1</property>
- <property name="max">999</property>
- <property name="maximum_size"></property>
- <property name="min">1</property>
- <property name="minimum_size"></property>
- <property name="name">m_spinCtrlLimitProcessors</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">48,-1</property>
- <property name="style">wxSP_ARROW_KEYS</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="value"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnSpinCtrl"></event>
- <event name="OnSpinCtrlText"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">processors</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticText35</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL</property>
- <property name="proportion">0</property>
- <object class="wxCheckBox" expanded="1">
- <property name="bg"></property>
- <property name="checked">0</property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">&Start Bitcoin on system startup</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_checkBoxStartOnSystemStartup</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnCheckBox"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL</property>
- <property name="proportion">0</property>
- <object class="wxCheckBox" expanded="1">
- <property name="bg"></property>
- <property name="checked">0</property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">&Minimize to the tray instead of the taskbar</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_checkBoxMinimizeToTray</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnCheckBox">OnCheckBoxMinimizeToTray</event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
- <property name="proportion">0</property>
- <object class="wxCheckBox" expanded="1">
- <property name="bg"></property>
- <property name="checked">0</property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">M&inimize to the tray on close</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_checkBoxMinimizeOnClose</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnCheckBox"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer102</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
- <property name="proportion">0</property>
- <object class="wxCheckBox" expanded="1">
- <property name="bg"></property>
- <property name="checked">0</property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">&Connect through socks4 proxy: </property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_checkBoxUseProxy</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnCheckBox">OnCheckBoxUseProxy</event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer103</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag"></property>
- <property name="proportion">0</property>
- <object class="spacer" expanded="1">
- <property name="height">0</property>
- <property name="permission">protected</property>
- <property name="width">18</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">Proxy &IP:</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticTextProxyIP</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL</property>
- <property name="proportion">0</property>
- <object class="wxTextCtrl" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_PROXYIP</property>
- <property name="maximum_size"></property>
- <property name="maxlength">15</property>
- <property name="minimum_size"></property>
- <property name="name">m_textCtrlProxyIP</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">140,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="value"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus">OnKillFocusProxy</event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnText"></event>
- <event name="OnTextEnter"></event>
- <event name="OnTextMaxLen"></event>
- <event name="OnTextURL"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label"> &Port:</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticTextProxyPort</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL</property>
- <property name="proportion">0</property>
- <object class="wxTextCtrl" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_PROXYPORT</property>
- <property name="maximum_size"></property>
- <property name="maxlength">5</property>
- <property name="minimum_size"></property>
- <property name="name">m_textCtrlProxyPort</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">55,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="value"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus">OnKillFocusProxy</event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnText"></event>
- <event name="OnTextEnter"></event>
- <event name="OnTextMaxLen"></event>
- <event name="OnTextURL"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxPanel" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_panelTest2</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style">wxTAB_TRAVERSAL</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer64</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="spacer" expanded="1">
- <property name="height">16</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">// [don't translate] Test panel 2 for future expansion</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticText321</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">// [don't translate] Let's not start multiple pages until the first page is filled up</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticText69</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_RIGHT</property>
- <property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer58</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_OK</property>
- <property name="label">OK</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_buttonOK</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonOK</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_CANCEL</property>
- <property name="label">Cancel</property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonCancel</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonCancel</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_APPLY</property>
- <property name="label">&Apply</property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonApply</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonApply</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="Dialog" expanded="0">
- <property name="bg"></property>
- <property name="center"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="extra_style"></property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">CAboutDialogBase</property>
- <property name="pos"></property>
- <property name="size">532,329</property>
- <property name="style">wxDEFAULT_DIALOG_STYLE</property>
- <property name="subclass"></property>
- <property name="title">About Bitcoin</property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnActivate"></event>
- <event name="OnActivateApp"></event>
- <event name="OnChar"></event>
- <event name="OnClose"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnHibernate"></event>
- <event name="OnIconize"></event>
- <event name="OnIdle"></event>
- <event name="OnInitDialog"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer63</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag"></property>
- <property name="proportion">0</property>
- <object class="wxStaticBitmap" expanded="1">
- <property name="bg"></property>
- <property name="bitmap">xpm/about.xpm; Load From File</property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_bitmap</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND|wxLEFT</property>
- <property name="proportion">1</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer60</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer62</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer631</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="spacer" expanded="1">
- <property name="height">65</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer64</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxLEFT</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font">Tahoma,90,92,10,74,0</property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">Bitcoin </property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticText40</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxRIGHT</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font">Tahoma,90,90,10,74,0</property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">version</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticTextVersion</property>
- <property name="permission">public</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="spacer" expanded="1">
- <property name="height">4</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">Copyright (c) 2009-2010 Satoshi Nakamoto.

This is experimental software.

Distributed under the MIT/X11 software license, see the accompanying file 
license.txt or http://www.opensource.org/licenses/mit-license.php.

This product includes software developed by the OpenSSL Project for use in the 
OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by 
Eric Young (eay@cryptsoft.com).</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticTextMain</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="spacer" expanded="1">
- <property name="height">0</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">2</property>
- <property name="flag">wxALIGN_RIGHT|wxEXPAND|wxRIGHT</property>
- <property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer61</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="spacer" expanded="1">
- <property name="height">0</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">6</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_OK</property>
- <property name="label">OK</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_buttonOK</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonOK</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="Dialog" expanded="0">
- <property name="bg"></property>
- <property name="center"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="extra_style"></property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">CSendDialogBase</property>
- <property name="pos"></property>
- <property name="size">675,298</property>
- <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
- <property name="subclass"></property>
- <property name="title">Send Coins</property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnActivate"></event>
- <event name="OnActivateApp"></event>
- <event name="OnChar"></event>
- <event name="OnClose"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnHibernate"></event>
- <event name="OnIconize"></event>
- <event name="OnIdle"></event>
- <event name="OnInitDialog"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer21</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="spacer" expanded="1">
- <property name="height">5</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND|wxLEFT</property>
- <property name="proportion">0</property>
- <object class="wxFlexGridSizer" expanded="1">
- <property name="cols">2</property>
- <property name="flexible_direction">wxBOTH</property>
- <property name="growablecols">1</property>
- <property name="growablerows"></property>
- <property name="hgap">0</property>
- <property name="minimum_size"></property>
- <property name="name">fgSizer1</property>
- <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
- <property name="permission">none</property>
- <property name="rows">0</property>
- <property name="vgap">0</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="spacer" expanded="1">
- <property name="height">0</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJED9L) or IP address (e.g. 123.45.6.7)</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticTextInstructions</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND|wxLEFT</property>
- <property name="proportion">1</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size">70,-1</property>
- <property name="name">bSizer47</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="spacer" expanded="1">
- <property name="height">0</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
- <property name="proportion">0</property>
- <object class="wxStaticBitmap" expanded="1">
- <property name="bg"></property>
- <property name="bitmap">xpm/check.xpm; Load From File</property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_bitmapCheckMark</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">16,16</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">Pay &To:</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticText36</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style">wxALIGN_RIGHT</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND|wxRIGHT</property>
- <property name="proportion">1</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer19</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
- <property name="proportion">1</property>
- <object class="wxTextCtrl" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_TEXTCTRLPAYTO</property>
- <property name="maximum_size"></property>
- <property name="maxlength">0</property>
- <property name="minimum_size"></property>
- <property name="name">m_textCtrlAddress</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="value"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown">OnKeyDown</event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnText">OnTextAddress</event>
- <event name="OnTextEnter"></event>
- <event name="OnTextMaxLen"></event>
- <event name="OnTextURL"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL</property>
- <property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer66</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_BUTTONPASTE</property>
- <property name="label">&Paste</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_buttonPaste</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style">wxBU_EXACTFIT</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonPaste</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_BUTTONADDRESSBOOK</property>
- <property name="label"> Address &Book...</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_buttonAddress</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonAddressBook</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT|wxALIGN_RIGHT</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">&Amount:</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticText19</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style">wxALIGN_RIGHT</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
- <property name="proportion">0</property>
- <object class="wxTextCtrl" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font">,90,90,-1,70,0</property>
- <property name="hidden">0</property>
- <property name="id">wxID_TEXTCTRLAMOUNT</property>
- <property name="maximum_size"></property>
- <property name="maxlength">20</property>
- <property name="minimum_size"></property>
- <property name="name">m_textCtrlAmount</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">145,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="value"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown">OnKeyDown</event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus">OnKillFocusAmount</event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnText"></event>
- <event name="OnTextEnter"></event>
- <event name="OnTextMaxLen"></event>
- <event name="OnTextURL"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">1</property>
- <property name="id">wxID_ANY</property>
- <property name="label">T&ransfer:</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticText20</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style">wxALIGN_RIGHT</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
- <property name="proportion">0</property>
- <object class="wxChoice" expanded="1">
- <property name="bg"></property>
- <property name="choices">" Standard"</property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">1</property>
- <property name="id">wxID_CHOICETRANSFERTYPE</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_choiceTransferType</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="selection">0</property>
- <property name="size"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnChoice"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="spacer" expanded="1">
- <property name="height">3</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="spacer" expanded="1">
- <property name="height">0</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="0">
- <property name="minimum_size"></property>
- <property name="name">bSizer672</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
- <property name="proportion">1</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer681</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxBOTTOM|wxLEFT</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">&From:</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticTextFrom</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxLEFT|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxTextCtrl" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="maxlength">0</property>
- <property name="minimum_size"></property>
- <property name="name">m_textCtrlFrom</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="value"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown">OnKeyDown</event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnText"></event>
- <event name="OnTextEnter"></event>
- <event name="OnTextMaxLen"></event>
- <event name="OnTextURL"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="wxBoxSizer" expanded="0">
- <property name="minimum_size"></property>
- <property name="name">bSizer67</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
- <property name="proportion">1</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer68</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxTOP|wxBOTTOM|wxLEFT</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">&Message:</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticTextMessage</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND|wxLEFT</property>
- <property name="proportion">1</property>
- <object class="wxTextCtrl" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="maxlength">0</property>
- <property name="minimum_size"></property>
- <property name="name">m_textCtrlMessage</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style">wxTE_MULTILINE</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="value"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown">OnKeyDown</event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnText"></event>
- <event name="OnTextEnter"></event>
- <event name="OnTextMaxLen"></event>
- <event name="OnTextURL"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="0">
- <property name="minimum_size"></property>
- <property name="name">bSizer23</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="spacer" expanded="1">
- <property name="height">0</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font">,90,90,-1,70,0</property>
- <property name="hidden">0</property>
- <property name="id">wxID_BUTTONSEND</property>
- <property name="label">&Send</property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonSend</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonSend</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_CANCEL</property>
- <property name="label">Cancel</property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonCancel</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonCancel</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="Dialog" expanded="0">
- <property name="bg"></property>
- <property name="center"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="extra_style"></property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">CSendingDialogBase</property>
- <property name="pos"></property>
- <property name="size">442,151</property>
- <property name="style">wxDEFAULT_DIALOG_STYLE</property>
- <property name="subclass"></property>
- <property name="title">Sending...</property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnActivate"></event>
- <event name="OnActivateApp"></event>
- <event name="OnChar"></event>
- <event name="OnClose">OnClose</event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnHibernate"></event>
- <event name="OnIconize"></event>
- <event name="OnIdle"></event>
- <event name="OnInitDialog"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint">OnPaint</event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer68</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">8</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label"></property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticTextSending</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,14</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">10</property>
- <property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
- <property name="proportion">1</property>
- <object class="wxTextCtrl" expanded="1">
- <property name="bg">wxSYS_COLOUR_BTNFACE</property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="maxlength">0</property>
- <property name="minimum_size"></property>
- <property name="name">m_textCtrlStatus</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style">wxTE_CENTRE|wxTE_MULTILINE|wxTE_NO_VSCROLL|wxTE_READONLY</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="value">

Connecting...</property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style">wxNO_BORDER</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnText"></event>
- <event name="OnTextEnter"></event>
- <event name="OnTextMaxLen"></event>
- <event name="OnTextURL"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer69</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="spacer" expanded="1">
- <property name="height">0</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">0</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">OK</property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonOK</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonOK</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_CANCEL</property>
- <property name="label">Cancel</property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonCancel</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonCancel</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="Dialog" expanded="0">
- <property name="bg"></property>
- <property name="center"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="extra_style"></property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">CYourAddressDialogBase</property>
- <property name="pos"></property>
- <property name="size">610,390</property>
- <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
- <property name="subclass"></property>
- <property name="title">Your Bitcoin Addresses</property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnActivate"></event>
- <event name="OnActivateApp"></event>
- <event name="OnChar"></event>
- <event name="OnClose">OnClose</event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnHibernate"></event>
- <event name="OnIconize"></event>
- <event name="OnIdle"></event>
- <event name="OnInitDialog"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer68</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="spacer" expanded="1">
- <property name="height">5</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. The highlighted address is displayed in the main window.</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticText45</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">590</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="wxListCtrl" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_LISTCTRL</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_listCtrl</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style">wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnListBeginDrag"></event>
- <event name="OnListBeginLabelEdit"></event>
- <event name="OnListBeginRDrag"></event>
- <event name="OnListCacheHint"></event>
- <event name="OnListColBeginDrag"></event>
- <event name="OnListColClick"></event>
- <event name="OnListColDragging"></event>
- <event name="OnListColEndDrag"></event>
- <event name="OnListColRightClick"></event>
- <event name="OnListDeleteAllItems"></event>
- <event name="OnListDeleteItem"></event>
- <event name="OnListEndLabelEdit">OnListEndLabelEdit</event>
- <event name="OnListInsertItem"></event>
- <event name="OnListItemActivated">OnListItemActivated</event>
- <event name="OnListItemDeselected"></event>
- <event name="OnListItemFocused"></event>
- <event name="OnListItemMiddleClick"></event>
- <event name="OnListItemRightClick"></event>
- <event name="OnListItemSelected">OnListItemSelected</event>
- <event name="OnListKeyDown"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer69</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="spacer" expanded="1">
- <property name="height">0</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_BUTTONRENAME</property>
- <property name="label">&Edit...</property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonRename</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonRename</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_BUTTONNEW</property>
- <property name="label"> &New Address... </property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonNew</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonNew</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_BUTTONCOPY</property>
- <property name="label"> &Copy to Clipboard </property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonCopy</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonCopy</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_OK</property>
- <property name="label">OK</property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonOK</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonOK</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">1</property>
- <property name="id">wxID_CANCEL</property>
- <property name="label">Cancel</property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonCancel</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonCancel</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="Dialog" expanded="0">
- <property name="bg"></property>
- <property name="center"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="extra_style"></property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">CAddressBookDialogBase</property>
- <property name="pos"></property>
- <property name="size">610,390</property>
- <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
- <property name="subclass"></property>
- <property name="title">Address Book</property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnActivate"></event>
- <event name="OnActivateApp"></event>
- <event name="OnChar"></event>
- <event name="OnClose">OnClose</event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnHibernate"></event>
- <event name="OnIconize"></event>
- <event name="OnIdle"></event>
- <event name="OnInitDialog"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer58</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
- <property name="proportion">1</property>
- <object class="wxNotebook" expanded="1">
- <property name="bg"></property>
- <property name="bitmapsize"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_notebook</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnNotebookPageChanged">OnNotebookPageChanged</event>
- <event name="OnNotebookPageChanging"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="notebookpage" expanded="1">
- <property name="bitmap"></property>
- <property name="label">Sending</property>
- <property name="select">0</property>
- <object class="wxPanel" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_PANELSENDING</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_panelSending</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style">wxTAB_TRAVERSAL</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer68</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="spacer" expanded="1">
- <property name="height">0</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">1</property>
- <property name="id">wxID_ANY</property>
- <property name="label">Bitcoin Address</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticText55</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="wxListCtrl" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_LISTCTRLSENDING</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_listCtrlSending</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style">wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnListBeginDrag"></event>
- <event name="OnListBeginLabelEdit"></event>
- <event name="OnListBeginRDrag"></event>
- <event name="OnListCacheHint"></event>
- <event name="OnListColBeginDrag"></event>
- <event name="OnListColClick"></event>
- <event name="OnListColDragging"></event>
- <event name="OnListColEndDrag"></event>
- <event name="OnListColRightClick"></event>
- <event name="OnListDeleteAllItems"></event>
- <event name="OnListDeleteItem"></event>
- <event name="OnListEndLabelEdit">OnListEndLabelEdit</event>
- <event name="OnListInsertItem"></event>
- <event name="OnListItemActivated">OnListItemActivated</event>
- <event name="OnListItemDeselected"></event>
- <event name="OnListItemFocused"></event>
- <event name="OnListItemMiddleClick"></event>
- <event name="OnListItemRightClick"></event>
- <event name="OnListItemSelected">OnListItemSelected</event>
- <event name="OnListKeyDown"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="notebookpage" expanded="1">
- <property name="bitmap"></property>
- <property name="label">Receiving</property>
- <property name="select">1</property>
- <object class="wxPanel" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_PANELRECEIVING</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_panelReceiving</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style">wxTAB_TRAVERSAL</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer681</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="spacer" expanded="1">
- <property name="height">0</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">6</property>
- <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">These are your Bitcoin addresses for receiving payments. You can give a different one to each sender to keep track of who is paying you. The highlighted address will be displayed in the main window.</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticText45</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">570</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="spacer" expanded="1">
- <property name="height">2</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="wxListCtrl" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_LISTCTRLRECEIVING</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_listCtrlReceiving</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style">wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnListBeginDrag"></event>
- <event name="OnListBeginLabelEdit"></event>
- <event name="OnListBeginRDrag"></event>
- <event name="OnListCacheHint"></event>
- <event name="OnListColBeginDrag"></event>
- <event name="OnListColClick"></event>
- <event name="OnListColDragging"></event>
- <event name="OnListColEndDrag"></event>
- <event name="OnListColRightClick"></event>
- <event name="OnListDeleteAllItems"></event>
- <event name="OnListDeleteItem"></event>
- <event name="OnListEndLabelEdit">OnListEndLabelEdit</event>
- <event name="OnListInsertItem"></event>
- <event name="OnListItemActivated">OnListItemActivated</event>
- <event name="OnListItemDeselected"></event>
- <event name="OnListItemFocused"></event>
- <event name="OnListItemMiddleClick"></event>
- <event name="OnListItemRightClick"></event>
- <event name="OnListItemSelected">OnListItemSelected</event>
- <event name="OnListKeyDown"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer69</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="spacer" expanded="1">
- <property name="height">0</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_BUTTONDELETE</property>
- <property name="label">&Delete</property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonDelete</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonDelete</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_BUTTONCOPY</property>
- <property name="label"> &Copy to Clipboard </property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonCopy</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonCopy</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_BUTTONEDIT</property>
- <property name="label">&Edit...</property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonEdit</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonEdit</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_BUTTONNEW</property>
- <property name="label"> &New Address... </property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonNew</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonNew</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_OK</property>
- <property name="label">OK</property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonOK</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonOK</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_CANCEL</property>
- <property name="label">Cancel</property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonCancel</property>
- <property name="permission">public</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonCancel</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="Dialog" expanded="0">
- <property name="bg"></property>
- <property name="center"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="extra_style"></property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">CGetTextFromUserDialogBase</property>
- <property name="pos"></property>
- <property name="size">440,138</property>
- <property name="style">wxDEFAULT_DIALOG_STYLE</property>
- <property name="subclass"></property>
- <property name="title"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnActivate"></event>
- <event name="OnActivateApp"></event>
- <event name="OnChar"></event>
- <event name="OnClose">OnClose</event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnHibernate"></event>
- <event name="OnIconize"></event>
- <event name="OnIdle"></event>
- <event name="OnInitDialog"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer79</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">10</property>
- <property name="flag">wxEXPAND|wxALL</property>
- <property name="proportion">1</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer81</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="spacer" expanded="1">
- <property name="height">0</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label"></property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticTextMessage1</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL</property>
- <property name="proportion">0</property>
- <object class="wxTextCtrl" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_TEXTCTRL</property>
- <property name="maximum_size"></property>
- <property name="maxlength">0</property>
- <property name="minimum_size"></property>
- <property name="name">m_textCtrl1</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style">wxTE_PROCESS_ENTER</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="value"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown">OnKeyDown</event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnText"></event>
- <event name="OnTextEnter"></event>
- <event name="OnTextMaxLen"></event>
- <event name="OnTextURL"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">1</property>
- <property name="id">wxID_ANY</property>
- <property name="label"></property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticTextMessage2</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL</property>
- <property name="proportion">0</property>
- <object class="wxTextCtrl" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">1</property>
- <property name="id">wxID_TEXTCTRL</property>
- <property name="maximum_size"></property>
- <property name="maxlength">0</property>
- <property name="minimum_size"></property>
- <property name="name">m_textCtrl2</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style">wxTE_PROCESS_ENTER</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="value"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown">OnKeyDown</event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnText"></event>
- <event name="OnTextEnter"></event>
- <event name="OnTextMaxLen"></event>
- <event name="OnTextURL"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="spacer" expanded="1">
- <property name="height">0</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer80</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="spacer" expanded="1">
- <property name="height">0</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_OK</property>
- <property name="label">OK</property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonOK</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonOK</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_CANCEL</property>
- <property name="label">Cancel</property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonCancel</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonCancel</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
-</wxFormBuilder_Project>
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> +<wxFormBuilder_Project> + <FileVersion major="1" minor="9" /> + <object class="Project" expanded="1"> + <property name="class_decoration"></property> + <property name="code_generation">C++</property> + <property name="disconnect_events">1</property> + <property name="encoding">UTF-8</property> + <property name="event_generation">connect</property> + <property name="file">uibase</property> + <property name="first_id">1000</property> + <property name="help_provider">none</property> + <property name="internationalize">1</property> + <property name="name"></property> + <property name="namespace"></property> + <property name="path">.</property> + <property name="precompiled_header"></property> + <property name="relative_path">1</property> + <property name="use_enum">0</property> + <property name="use_microsoft_bom">0</property> + <object class="Frame" expanded="0"> + <property name="bg">wxSYS_COLOUR_BTNFACE</property> + <property name="center"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="extra_style"></property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_MAINFRAME</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">CMainFrameBase</property> + <property name="pos"></property> + <property name="size">723,484</property> + <property name="style">wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER</property> + <property name="subclass"></property> + <property name="title">Bitcoin</property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style">wxTAB_TRAVERSAL</property> + <property name="xrc_skip_sizer">1</property> + <event name="OnActivate"></event> + <event name="OnActivateApp"></event> + <event name="OnChar"></event> + <event name="OnClose">OnClose</event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnHibernate"></event> + <event name="OnIconize">OnIconize</event> + <event name="OnIdle">OnIdle</event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents">OnMouseEvents</event> + <event name="OnMouseWheel"></event> + <event name="OnPaint">OnPaint</event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + <object class="wxMenuBar" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">MyMenuBar</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_menubar</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + <object class="wxMenu" expanded="1"> + <property name="label">&File</property> + <property name="name">m_menuFile</property> + <property name="permission">protected</property> + <object class="wxMenuItem" expanded="1"> + <property name="bitmap"></property> + <property name="checked">0</property> + <property name="enabled">1</property> + <property name="help"></property> + <property name="id">wxID_EXIT</property> + <property name="kind">wxITEM_NORMAL</property> + <property name="label">E&xit</property> + <property name="name">m_menuFileExit</property> + <property name="permission">none</property> + <property name="shortcut"></property> + <property name="unchecked_bitmap"></property> + <event name="OnMenuSelection">OnMenuFileExit</event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="wxMenu" expanded="1"> + <property name="label">&Settings</property> + <property name="name">m_menuOptions</property> + <property name="permission">public</property> + <object class="wxMenuItem" expanded="1"> + <property name="bitmap"></property> + <property name="checked">0</property> + <property name="enabled">1</property> + <property name="help"></property> + <property name="id">wxID_OPTIONSGENERATEBITCOINS</property> + <property name="kind">wxITEM_CHECK</property> + <property name="label">&Generate Coins</property> + <property name="name">m_menuOptionsGenerateBitcoins</property> + <property name="permission">none</property> + <property name="shortcut"></property> + <property name="unchecked_bitmap"></property> + <event name="OnMenuSelection">OnMenuOptionsGenerate</event> + <event name="OnUpdateUI">OnUpdateUIOptionsGenerate</event> + </object> + <object class="wxMenuItem" expanded="1"> + <property name="bitmap"></property> + <property name="checked">0</property> + <property name="enabled">1</property> + <property name="help"></property> + <property name="id">wxID_ANY</property> + <property name="kind">wxITEM_NORMAL</property> + <property name="label">&Your Receiving Addresses...</property> + <property name="name">m_menuOptionsChangeYourAddress</property> + <property name="permission">none</property> + <property name="shortcut"></property> + <property name="unchecked_bitmap"></property> + <event name="OnMenuSelection">OnMenuOptionsChangeYourAddress</event> + <event name="OnUpdateUI"></event> + </object> + <object class="wxMenuItem" expanded="1"> + <property name="bitmap"></property> + <property name="checked">0</property> + <property name="enabled">1</property> + <property name="help"></property> + <property name="id">wxID_PREFERENCES</property> + <property name="kind">wxITEM_NORMAL</property> + <property name="label">&Options...</property> + <property name="name">m_menuOptionsOptions</property> + <property name="permission">none</property> + <property name="shortcut"></property> + <property name="unchecked_bitmap"></property> + <event name="OnMenuSelection">OnMenuOptionsOptions</event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="wxMenu" expanded="1"> + <property name="label">&Help</property> + <property name="name">m_menuHelp</property> + <property name="permission">protected</property> + <object class="wxMenuItem" expanded="1"> + <property name="bitmap"></property> + <property name="checked">0</property> + <property name="enabled">1</property> + <property name="help"></property> + <property name="id">wxID_ABOUT</property> + <property name="kind">wxITEM_NORMAL</property> + <property name="label">&About...</property> + <property name="name">m_menuHelpAbout</property> + <property name="permission">none</property> + <property name="shortcut"></property> + <property name="unchecked_bitmap"></property> + <event name="OnMenuSelection">OnMenuHelpAbout</event> + <event name="OnUpdateUI"></event> + </object> + </object> + </object> + <object class="wxToolBar" expanded="1"> + <property name="bg"></property> + <property name="bitmapsize">20,20</property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font">,90,90,-1,70,0</property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="margins"></property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_toolBar</property> + <property name="packing">1</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="separation">1</property> + <property name="size">-1,-1</property> + <property name="style">wxTB_FLAT|wxTB_HORZ_TEXT</property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + <object class="tool" expanded="1"> + <property name="bitmap">xpm/send20.xpm; Load From File</property> + <property name="id">wxID_BUTTONSEND</property> + <property name="kind">wxITEM_NORMAL</property> + <property name="label">Send Coins</property> + <property name="name">m_tool1</property> + <property name="statusbar"></property> + <property name="tooltip"></property> + <event name="OnMenuSelection"></event> + <event name="OnToolClicked">OnButtonSend</event> + <event name="OnToolEnter"></event> + <event name="OnToolRClicked"></event> + <event name="OnUpdateUI"></event> + </object> + <object class="tool" expanded="1"> + <property name="bitmap">xpm/addressbook20.xpm; Load From File</property> + <property name="id">wxID_BUTTONRECEIVE</property> + <property name="kind">wxITEM_NORMAL</property> + <property name="label">Address Book</property> + <property name="name">m_tool2</property> + <property name="statusbar"></property> + <property name="tooltip"></property> + <event name="OnMenuSelection"></event> + <event name="OnToolClicked">OnButtonAddressBook</event> + <event name="OnToolEnter"></event> + <event name="OnToolRClicked"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="wxStatusBar" expanded="1"> + <property name="bg">240,240,240</property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="fields">1</property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_statusBar</property> + <property name="permission">public</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style">wxST_SIZEGRIP</property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer2</property> + <property name="orient">wxVERTICAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">0</property> + <object class="spacer" expanded="1"> + <property name="height">2</property> + <property name="permission">protected</property> + <property name="width">0</property> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property> + <property name="proportion">0</property> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer85</property> + <property name="orient">wxHORIZONTAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">Your Bitcoin Address:</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_staticText32</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <property name="wrap">-1</property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property> + <property name="proportion">0</property> + <object class="wxTextCtrl" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_TEXTCTRLADDRESS</property> + <property name="maximum_size">-1,-1</property> + <property name="maxlength">0</property> + <property name="minimum_size">-1,-1</property> + <property name="name">m_textCtrlAddress</property> + <property name="permission">public</property> + <property name="pos"></property> + <property name="size">340,-1</property> + <property name="style">wxTE_READONLY</property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="value"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown">OnKeyDown</event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents">OnMouseEventsAddress</event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus">OnSetFocusAddress</event> + <event name="OnSize"></event> + <event name="OnText"></event> + <event name="OnTextEnter"></event> + <event name="OnTextMaxLen"></event> + <event name="OnTextURL"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxRIGHT|wxALIGN_CENTER_VERTICAL</property> + <property name="proportion">0</property> + <object class="wxButton" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="default">0</property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_BUTTONNEW</property> + <property name="label"> &New... </property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_buttonNew</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size">-1,-1</property> + <property name="style">wxBU_EXACTFIT</property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">OnButtonNew</event> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT</property> + <property name="proportion">0</property> + <object class="wxButton" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="default">0</property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_BUTTONCOPY</property> + <property name="label"> &Copy to Clipboard </property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_buttonCopy</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style">wxBU_EXACTFIT</property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">OnButtonCopy</event> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">0</property> + <object class="spacer" expanded="1"> + <property name="height">0</property> + <property name="permission">protected</property> + <property name="width">0</property> + </object> + </object> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer3</property> + <property name="orient">wxHORIZONTAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND|wxALL</property> + <property name="proportion">1</property> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer66</property> + <property name="orient">wxHORIZONTAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">Balance:</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_staticText41</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size">-1,15</property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <property name="wrap">-1</property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="1"> + <property name="bg">255,255,255</property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font">,90,90,8,70,0</property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label"></property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_staticTextBalance</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size">120,15</property> + <property name="style">wxALIGN_RIGHT|wxST_NO_AUTORESIZE</property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <property name="wrap">-1</property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">0</property> + <object class="spacer" expanded="1"> + <property name="height">0</property> + <property name="permission">protected</property> + <property name="width">0</property> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALIGN_BOTTOM|wxTOP|wxRIGHT|wxLEFT</property> + <property name="proportion">0</property> + <object class="wxChoice" expanded="1"> + <property name="bg"></property> + <property name="choices">" All" " Sent" " Received" " In Progress"</property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">1</property> + <property name="id">wxID_ANY</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_choiceFilter</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="selection">0</property> + <property name="size">110,-1</property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnChar"></event> + <event name="OnChoice"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">1</property> + <object class="wxNotebook" expanded="1"> + <property name="bg"></property> + <property name="bitmapsize"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_notebook</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnNotebookPageChanged">OnNotebookPageChanged</event> + <event name="OnNotebookPageChanging"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + <object class="notebookpage" expanded="1"> + <property name="bitmap"></property> + <property name="label">All Transactions</property> + <property name="select">1</property> + <object class="wxPanel" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_panel9</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style">wxTAB_TRAVERSAL</property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer11</property> + <property name="orient">wxVERTICAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">1</property> + <object class="wxListCtrl" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_listCtrlAll</property> + <property name="permission">public</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style">wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING</property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnListBeginDrag"></event> + <event name="OnListBeginLabelEdit"></event> + <event name="OnListBeginRDrag"></event> + <event name="OnListCacheHint"></event> + <event name="OnListColBeginDrag">OnListColBeginDrag</event> + <event name="OnListColClick"></event> + <event name="OnListColDragging"></event> + <event name="OnListColEndDrag"></event> + <event name="OnListColRightClick"></event> + <event name="OnListDeleteAllItems"></event> + <event name="OnListDeleteItem"></event> + <event name="OnListEndLabelEdit"></event> + <event name="OnListInsertItem"></event> + <event name="OnListItemActivated">OnListItemActivated</event> + <event name="OnListItemDeselected"></event> + <event name="OnListItemFocused"></event> + <event name="OnListItemMiddleClick"></event> + <event name="OnListItemRightClick"></event> + <event name="OnListItemSelected"></event> + <event name="OnListKeyDown"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint">OnPaintListCtrl</event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + </object> + </object> + </object> + <object class="notebookpage" expanded="1"> + <property name="bitmap"></property> + <property name="label">Sent/Received</property> + <property name="select">0</property> + <object class="wxPanel" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_panel91</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style">wxTAB_TRAVERSAL</property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer111</property> + <property name="orient">wxVERTICAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">1</property> + <object class="wxListCtrl" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_listCtrlSentReceived</property> + <property name="permission">public</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style">wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING</property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnListBeginDrag"></event> + <event name="OnListBeginLabelEdit"></event> + <event name="OnListBeginRDrag"></event> + <event name="OnListCacheHint"></event> + <event name="OnListColBeginDrag">OnListColBeginDrag</event> + <event name="OnListColClick"></event> + <event name="OnListColDragging"></event> + <event name="OnListColEndDrag"></event> + <event name="OnListColRightClick"></event> + <event name="OnListDeleteAllItems"></event> + <event name="OnListDeleteItem"></event> + <event name="OnListEndLabelEdit"></event> + <event name="OnListInsertItem"></event> + <event name="OnListItemActivated">OnListItemActivated</event> + <event name="OnListItemDeselected"></event> + <event name="OnListItemFocused"></event> + <event name="OnListItemMiddleClick"></event> + <event name="OnListItemRightClick"></event> + <event name="OnListItemSelected"></event> + <event name="OnListKeyDown"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint">OnPaintListCtrl</event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + </object> + </object> + </object> + <object class="notebookpage" expanded="1"> + <property name="bitmap"></property> + <property name="label">Sent</property> + <property name="select">0</property> + <object class="wxPanel" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_panel92</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style">wxTAB_TRAVERSAL</property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer112</property> + <property name="orient">wxVERTICAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">1</property> + <object class="wxListCtrl" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_listCtrlSent</property> + <property name="permission">public</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style">wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING</property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnListBeginDrag"></event> + <event name="OnListBeginLabelEdit"></event> + <event name="OnListBeginRDrag"></event> + <event name="OnListCacheHint"></event> + <event name="OnListColBeginDrag">OnListColBeginDrag</event> + <event name="OnListColClick"></event> + <event name="OnListColDragging"></event> + <event name="OnListColEndDrag"></event> + <event name="OnListColRightClick"></event> + <event name="OnListDeleteAllItems"></event> + <event name="OnListDeleteItem"></event> + <event name="OnListEndLabelEdit"></event> + <event name="OnListInsertItem"></event> + <event name="OnListItemActivated">OnListItemActivated</event> + <event name="OnListItemDeselected"></event> + <event name="OnListItemFocused"></event> + <event name="OnListItemMiddleClick"></event> + <event name="OnListItemRightClick"></event> + <event name="OnListItemSelected"></event> + <event name="OnListKeyDown"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint">OnPaintListCtrl</event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + </object> + </object> + </object> + <object class="notebookpage" expanded="1"> + <property name="bitmap"></property> + <property name="label">Received</property> + <property name="select">0</property> + <object class="wxPanel" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_panel93</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style">wxTAB_TRAVERSAL</property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer113</property> + <property name="orient">wxVERTICAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">1</property> + <object class="wxListCtrl" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_listCtrlReceived</property> + <property name="permission">public</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style">wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING</property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnListBeginDrag"></event> + <event name="OnListBeginLabelEdit"></event> + <event name="OnListBeginRDrag"></event> + <event name="OnListCacheHint"></event> + <event name="OnListColBeginDrag">OnListColBeginDrag</event> + <event name="OnListColClick"></event> + <event name="OnListColDragging"></event> + <event name="OnListColEndDrag"></event> + <event name="OnListColRightClick"></event> + <event name="OnListDeleteAllItems"></event> + <event name="OnListDeleteItem"></event> + <event name="OnListEndLabelEdit"></event> + <event name="OnListInsertItem"></event> + <event name="OnListItemActivated">OnListItemActivated</event> + <event name="OnListItemDeselected"></event> + <event name="OnListItemFocused"></event> + <event name="OnListItemMiddleClick"></event> + <event name="OnListItemRightClick"></event> + <event name="OnListItemSelected"></event> + <event name="OnListKeyDown"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint">OnPaintListCtrl</event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + </object> + </object> + </object> + </object> + </object> + </object> + </object> + <object class="Dialog" expanded="0"> + <property name="bg"></property> + <property name="center"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="extra_style"></property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">CTxDetailsDialogBase</property> + <property name="pos"></property> + <property name="size">620,450</property> + <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property> + <property name="subclass"></property> + <property name="title">Transaction Details</property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnActivate"></event> + <event name="OnActivateApp"></event> + <event name="OnChar"></event> + <event name="OnClose"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnHibernate"></event> + <event name="OnIconize"></event> + <event name="OnIdle"></event> + <event name="OnInitDialog"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer64</property> + <property name="orient">wxVERTICAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">1</property> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer66</property> + <property name="orient">wxVERTICAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL|wxEXPAND</property> + <property name="proportion">1</property> + <object class="wxHtmlWindow" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_htmlWin</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style">wxHW_SCROLLBAR_AUTO</property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnHtmlCellClicked"></event> + <event name="OnHtmlCellHover"></event> + <event name="OnHtmlLinkClicked"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALIGN_RIGHT</property> + <property name="proportion">0</property> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer65</property> + <property name="orient">wxHORIZONTAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxButton" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="default">0</property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_OK</property> + <property name="label">OK</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_buttonOK</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size">-1,-1</property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">OnButtonOK</event> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + </object> + </object> + </object> + </object> + <object class="Dialog" expanded="0"> + <property name="bg"></property> + <property name="center"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="extra_style"></property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">COptionsDialogBase</property> + <property name="pos"></property> + <property name="size">540,360</property> + <property name="style">wxDEFAULT_DIALOG_STYLE</property> + <property name="subclass"></property> + <property name="title">Options</property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnActivate"></event> + <event name="OnActivateApp"></event> + <event name="OnChar"></event> + <event name="OnClose"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnHibernate"></event> + <event name="OnIconize"></event> + <event name="OnIdle"></event> + <event name="OnInitDialog"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + <object class="wxBoxSizer" expanded="0"> + <property name="minimum_size"></property> + <property name="name">bSizer55</property> + <property name="orient">wxVERTICAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">9</property> + <property name="flag">wxEXPAND|wxALL</property> + <property name="proportion">1</property> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer66</property> + <property name="orient">wxHORIZONTAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND|wxRIGHT</property> + <property name="proportion">0</property> + <object class="wxListBox" expanded="1"> + <property name="bg"></property> + <property name="choices"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_listBox</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size">110,-1</property> + <property name="style">wxLB_NEEDED_SB|wxLB_SINGLE</property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnListBox">OnListBox</event> + <event name="OnListBoxDClick"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND|wxLEFT</property> + <property name="proportion">1</property> + <object class="wxScrolledWindow" expanded="0"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_scrolledWindow</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="scroll_rate_x">5</property> + <property name="scroll_rate_y">5</property> + <property name="size"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer63</property> + <property name="orient">wxVERTICAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxPanel" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_panelMain</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style">wxTAB_TRAVERSAL</property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer69</property> + <property name="orient">wxVERTICAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">0</property> + <object class="spacer" expanded="1"> + <property name="height">16</property> + <property name="permission">protected</property> + <property name="width">0</property> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">1</property> + <property name="id">wxID_ANY</property> + <property name="label">Optional transaction fee you give to the nodes that process your transactions.</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_staticText32</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <property name="wrap">-1</property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer56</property> + <property name="orient">wxHORIZONTAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">1</property> + <property name="id">wxID_ANY</property> + <property name="label">Transaction fee:</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_staticText31</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <property name="wrap">-1</property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property> + <property name="proportion">0</property> + <object class="wxTextCtrl" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">1</property> + <property name="id">wxID_TRANSACTIONFEE</property> + <property name="maximum_size"></property> + <property name="maxlength">0</property> + <property name="minimum_size"></property> + <property name="name">m_textCtrlTransactionFee</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size">70,-1</property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="value"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus">OnKillFocusTransactionFee</event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnText"></event> + <event name="OnTextEnter"></event> + <event name="OnTextMaxLen"></event> + <event name="OnTextURL"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag"></property> + <property name="proportion">0</property> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer71</property> + <property name="orient">wxHORIZONTAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property> + <property name="proportion">0</property> + <object class="wxCheckBox" expanded="1"> + <property name="bg"></property> + <property name="checked">0</property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">&Limit coin generation to</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_checkBoxLimitProcessors</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnChar"></event> + <event name="OnCheckBox">OnCheckBoxLimitProcessors</event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALIGN_CENTER_VERTICAL</property> + <property name="proportion">0</property> + <object class="wxSpinCtrl" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="initial">1</property> + <property name="max">999</property> + <property name="maximum_size"></property> + <property name="min">1</property> + <property name="minimum_size"></property> + <property name="name">m_spinCtrlLimitProcessors</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size">48,-1</property> + <property name="style">wxSP_ARROW_KEYS</property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="value"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnSpinCtrl"></event> + <event name="OnSpinCtrlText"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">processors</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_staticText35</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <property name="wrap">-1</property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL</property> + <property name="proportion">0</property> + <object class="wxCheckBox" expanded="1"> + <property name="bg"></property> + <property name="checked">0</property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">&Start Bitcoin on system startup</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_checkBoxStartOnSystemStartup</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnChar"></event> + <event name="OnCheckBox"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL</property> + <property name="proportion">0</property> + <object class="wxCheckBox" expanded="1"> + <property name="bg"></property> + <property name="checked">0</property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">&Minimize to the tray instead of the taskbar</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_checkBoxMinimizeToTray</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnChar"></event> + <event name="OnCheckBox">OnCheckBoxMinimizeToTray</event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property> + <property name="proportion">0</property> + <object class="wxCheckBox" expanded="1"> + <property name="bg"></property> + <property name="checked">0</property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">M&inimize to the tray on close</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_checkBoxMinimizeOnClose</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnChar"></event> + <event name="OnCheckBox"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">1</property> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer102</property> + <property name="orient">wxHORIZONTAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property> + <property name="proportion">0</property> + <object class="wxCheckBox" expanded="1"> + <property name="bg"></property> + <property name="checked">0</property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">&Connect through socks4 proxy: </property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_checkBoxUseProxy</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnChar"></event> + <event name="OnCheckBox">OnCheckBoxUseProxy</event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">1</property> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer103</property> + <property name="orient">wxHORIZONTAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag"></property> + <property name="proportion">0</property> + <object class="spacer" expanded="1"> + <property name="height">0</property> + <property name="permission">protected</property> + <property name="width">18</property> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">Proxy &IP:</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_staticTextProxyIP</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <property name="wrap">-1</property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALIGN_CENTER_VERTICAL</property> + <property name="proportion">0</property> + <object class="wxTextCtrl" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_PROXYIP</property> + <property name="maximum_size"></property> + <property name="maxlength">15</property> + <property name="minimum_size"></property> + <property name="name">m_textCtrlProxyIP</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size">140,-1</property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="value"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus">OnKillFocusProxy</event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnText"></event> + <event name="OnTextEnter"></event> + <event name="OnTextMaxLen"></event> + <event name="OnTextURL"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label"> &Port:</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_staticTextProxyPort</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <property name="wrap">-1</property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALIGN_CENTER_VERTICAL</property> + <property name="proportion">0</property> + <object class="wxTextCtrl" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_PROXYPORT</property> + <property name="maximum_size"></property> + <property name="maxlength">5</property> + <property name="minimum_size"></property> + <property name="name">m_textCtrlProxyPort</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size">55,-1</property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="value"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus">OnKillFocusProxy</event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnText"></event> + <event name="OnTextEnter"></event> + <event name="OnTextMaxLen"></event> + <event name="OnTextURL"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + </object> + </object> + </object> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxPanel" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_panelTest2</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style">wxTAB_TRAVERSAL</property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer64</property> + <property name="orient">wxVERTICAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">0</property> + <object class="spacer" expanded="1"> + <property name="height">16</property> + <property name="permission">protected</property> + <property name="width">0</property> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">// [don't translate] Test panel 2 for future expansion</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_staticText321</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <property name="wrap">-1</property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">// [don't translate] Let's not start multiple pages until the first page is filled up</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_staticText69</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <property name="wrap">-1</property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + </object> + </object> + </object> + </object> + </object> + </object> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALIGN_RIGHT</property> + <property name="proportion">0</property> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer58</property> + <property name="orient">wxHORIZONTAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxButton" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="default">0</property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_OK</property> + <property name="label">OK</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_buttonOK</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size">-1,-1</property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">OnButtonOK</event> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxButton" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="default">0</property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_CANCEL</property> + <property name="label">Cancel</property> + <property name="maximum_size"></property> + <property name="minimum_size">-1,-1</property> + <property name="name">m_buttonCancel</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size">-1,-1</property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">OnButtonCancel</event> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxButton" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="default">0</property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_APPLY</property> + <property name="label">&Apply</property> + <property name="maximum_size"></property> + <property name="minimum_size">-1,-1</property> + <property name="name">m_buttonApply</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size">-1,-1</property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">OnButtonApply</event> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + </object> + </object> + </object> + </object> + <object class="Dialog" expanded="0"> + <property name="bg"></property> + <property name="center"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="extra_style"></property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">CAboutDialogBase</property> + <property name="pos"></property> + <property name="size">532,329</property> + <property name="style">wxDEFAULT_DIALOG_STYLE</property> + <property name="subclass"></property> + <property name="title">About Bitcoin</property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnActivate"></event> + <event name="OnActivateApp"></event> + <event name="OnChar"></event> + <event name="OnClose"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnHibernate"></event> + <event name="OnIconize"></event> + <event name="OnIdle"></event> + <event name="OnInitDialog"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer63</property> + <property name="orient">wxHORIZONTAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag"></property> + <property name="proportion">0</property> + <object class="wxStaticBitmap" expanded="1"> + <property name="bg"></property> + <property name="bitmap">xpm/about.xpm; Load From File</property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_bitmap</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND|wxLEFT</property> + <property name="proportion">1</property> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer60</property> + <property name="orient">wxVERTICAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">1</property> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer62</property> + <property name="orient">wxHORIZONTAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">1</property> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer631</property> + <property name="orient">wxVERTICAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">0</property> + <object class="spacer" expanded="1"> + <property name="height">65</property> + <property name="permission">protected</property> + <property name="width">0</property> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer64</property> + <property name="orient">wxHORIZONTAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxLEFT</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font">Tahoma,90,92,10,74,0</property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">Bitcoin </property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_staticText40</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <property name="wrap">-1</property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxRIGHT</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font">Tahoma,90,90,10,74,0</property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">version</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_staticTextVersion</property> + <property name="permission">public</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <property name="wrap">-1</property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">0</property> + <object class="spacer" expanded="1"> + <property name="height">4</property> + <property name="permission">protected</property> + <property name="width">0</property> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">Copyright (c) 2009-2010 Satoshi Nakamoto.

This is experimental software.

Distributed under the MIT/X11 software license, see the accompanying file 
license.txt or http://www.opensource.org/licenses/mit-license.php.

This product includes software developed by the OpenSSL Project for use in the 
OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by 
Eric Young (eay@cryptsoft.com).</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_staticTextMain</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <property name="wrap">-1</property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">0</property> + <object class="spacer" expanded="1"> + <property name="height">0</property> + <property name="permission">protected</property> + <property name="width">0</property> + </object> + </object> + </object> + </object> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">2</property> + <property name="flag">wxALIGN_RIGHT|wxEXPAND|wxRIGHT</property> + <property name="proportion">0</property> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer61</property> + <property name="orient">wxHORIZONTAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">1</property> + <object class="spacer" expanded="1"> + <property name="height">0</property> + <property name="permission">protected</property> + <property name="width">0</property> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">6</property> + <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxButton" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="default">0</property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_OK</property> + <property name="label">OK</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_buttonOK</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size">-1,-1</property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">OnButtonOK</event> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + </object> + </object> + </object> + </object> + </object> + </object> + <object class="Dialog" expanded="0"> + <property name="bg"></property> + <property name="center"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="extra_style"></property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">CSendDialogBase</property> + <property name="pos"></property> + <property name="size">675,298</property> + <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property> + <property name="subclass"></property> + <property name="title">Send Coins</property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnActivate"></event> + <event name="OnActivateApp"></event> + <event name="OnChar"></event> + <event name="OnClose"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnHibernate"></event> + <event name="OnIconize"></event> + <event name="OnIdle"></event> + <event name="OnInitDialog"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer21</property> + <property name="orient">wxVERTICAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">0</property> + <object class="spacer" expanded="1"> + <property name="height">5</property> + <property name="permission">protected</property> + <property name="width">0</property> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND|wxLEFT</property> + <property name="proportion">0</property> + <object class="wxFlexGridSizer" expanded="1"> + <property name="cols">2</property> + <property name="flexible_direction">wxBOTH</property> + <property name="growablecols">1</property> + <property name="growablerows"></property> + <property name="hgap">0</property> + <property name="minimum_size"></property> + <property name="name">fgSizer1</property> + <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property> + <property name="permission">none</property> + <property name="rows">0</property> + <property name="vgap">0</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">0</property> + <object class="spacer" expanded="1"> + <property name="height">0</property> + <property name="permission">protected</property> + <property name="width">0</property> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxTOP|wxRIGHT|wxLEFT</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJED9L) or IP address (e.g. 123.45.6.7)</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_staticTextInstructions</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <property name="wrap">-1</property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND|wxLEFT</property> + <property name="proportion">1</property> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size">70,-1</property> + <property name="name">bSizer47</property> + <property name="orient">wxHORIZONTAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">1</property> + <object class="spacer" expanded="1"> + <property name="height">0</property> + <property name="permission">protected</property> + <property name="width">0</property> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property> + <property name="proportion">0</property> + <object class="wxStaticBitmap" expanded="1"> + <property name="bg"></property> + <property name="bitmap">xpm/check.xpm; Load From File</property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_bitmapCheckMark</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size">16,16</property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">Pay &To:</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_staticText36</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size">-1,-1</property> + <property name="style">wxALIGN_RIGHT</property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <property name="wrap">-1</property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND|wxRIGHT</property> + <property name="proportion">1</property> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer19</property> + <property name="orient">wxHORIZONTAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property> + <property name="proportion">1</property> + <object class="wxTextCtrl" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_TEXTCTRLPAYTO</property> + <property name="maximum_size"></property> + <property name="maxlength">0</property> + <property name="minimum_size"></property> + <property name="name">m_textCtrlAddress</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="value"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown">OnKeyDown</event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnText">OnTextAddress</event> + <event name="OnTextEnter"></event> + <event name="OnTextMaxLen"></event> + <event name="OnTextURL"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALIGN_CENTER_VERTICAL</property> + <property name="proportion">0</property> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer66</property> + <property name="orient">wxHORIZONTAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxButton" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="default">0</property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_BUTTONPASTE</property> + <property name="label">&Paste</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_buttonPaste</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size">-1,-1</property> + <property name="style">wxBU_EXACTFIT</property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">OnButtonPaste</event> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxButton" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="default">0</property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_BUTTONADDRESSBOOK</property> + <property name="label"> Address &Book...</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_buttonAddress</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">OnButtonAddressBook</event> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + </object> + </object> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT|wxALIGN_RIGHT</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">&Amount:</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_staticText19</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size">-1,-1</property> + <property name="style">wxALIGN_RIGHT</property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <property name="wrap">-1</property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property> + <property name="proportion">0</property> + <object class="wxTextCtrl" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font">,90,90,-1,70,0</property> + <property name="hidden">0</property> + <property name="id">wxID_TEXTCTRLAMOUNT</property> + <property name="maximum_size"></property> + <property name="maxlength">20</property> + <property name="minimum_size"></property> + <property name="name">m_textCtrlAmount</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size">145,-1</property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="value"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown">OnKeyDown</event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus">OnKillFocusAmount</event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnText"></event> + <event name="OnTextEnter"></event> + <event name="OnTextMaxLen"></event> + <event name="OnTextURL"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">1</property> + <property name="id">wxID_ANY</property> + <property name="label">T&ransfer:</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_staticText20</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size">-1,-1</property> + <property name="style">wxALIGN_RIGHT</property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <property name="wrap">-1</property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property> + <property name="proportion">0</property> + <object class="wxChoice" expanded="1"> + <property name="bg"></property> + <property name="choices">" Standard"</property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">1</property> + <property name="id">wxID_CHOICETRANSFERTYPE</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_choiceTransferType</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="selection">0</property> + <property name="size"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnChar"></event> + <event name="OnChoice"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">0</property> + <object class="spacer" expanded="1"> + <property name="height">3</property> + <property name="permission">protected</property> + <property name="width">0</property> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">0</property> + <object class="spacer" expanded="1"> + <property name="height">0</property> + <property name="permission">protected</property> + <property name="width">0</property> + </object> + </object> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxBoxSizer" expanded="0"> + <property name="minimum_size"></property> + <property name="name">bSizer672</property> + <property name="orient">wxHORIZONTAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property> + <property name="proportion">1</property> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer681</property> + <property name="orient">wxVERTICAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxBOTTOM|wxLEFT</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">&From:</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_staticTextFrom</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <property name="wrap">-1</property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxLEFT|wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxTextCtrl" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="maximum_size"></property> + <property name="maxlength">0</property> + <property name="minimum_size"></property> + <property name="name">m_textCtrlFrom</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size">-1,-1</property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="value"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown">OnKeyDown</event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnText"></event> + <event name="OnTextEnter"></event> + <event name="OnTextMaxLen"></event> + <event name="OnTextURL"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + </object> + </object> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">1</property> + <object class="wxBoxSizer" expanded="0"> + <property name="minimum_size"></property> + <property name="name">bSizer67</property> + <property name="orient">wxHORIZONTAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property> + <property name="proportion">1</property> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer68</property> + <property name="orient">wxVERTICAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxTOP|wxBOTTOM|wxLEFT</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">&Message:</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_staticTextMessage</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <property name="wrap">-1</property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND|wxLEFT</property> + <property name="proportion">1</property> + <object class="wxTextCtrl" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="maximum_size"></property> + <property name="maxlength">0</property> + <property name="minimum_size"></property> + <property name="name">m_textCtrlMessage</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style">wxTE_MULTILINE</property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="value"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown">OnKeyDown</event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnText"></event> + <event name="OnTextEnter"></event> + <event name="OnTextMaxLen"></event> + <event name="OnTextURL"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + </object> + </object> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxBoxSizer" expanded="0"> + <property name="minimum_size"></property> + <property name="name">bSizer23</property> + <property name="orient">wxHORIZONTAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">1</property> + <object class="spacer" expanded="1"> + <property name="height">0</property> + <property name="permission">protected</property> + <property name="width">0</property> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxButton" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="default">0</property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font">,90,90,-1,70,0</property> + <property name="hidden">0</property> + <property name="id">wxID_BUTTONSEND</property> + <property name="label">&Send</property> + <property name="maximum_size"></property> + <property name="minimum_size">-1,-1</property> + <property name="name">m_buttonSend</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size">-1,-1</property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">OnButtonSend</event> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxButton" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="default">0</property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_CANCEL</property> + <property name="label">Cancel</property> + <property name="maximum_size"></property> + <property name="minimum_size">-1,-1</property> + <property name="name">m_buttonCancel</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size">-1,-1</property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">OnButtonCancel</event> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + </object> + </object> + </object> + </object> + <object class="Dialog" expanded="0"> + <property name="bg"></property> + <property name="center"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="extra_style"></property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">CSendingDialogBase</property> + <property name="pos"></property> + <property name="size">442,151</property> + <property name="style">wxDEFAULT_DIALOG_STYLE</property> + <property name="subclass"></property> + <property name="title">Sending...</property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnActivate"></event> + <event name="OnActivateApp"></event> + <event name="OnChar"></event> + <event name="OnClose">OnClose</event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnHibernate"></event> + <event name="OnIconize"></event> + <event name="OnIdle"></event> + <event name="OnInitDialog"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint">OnPaint</event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer68</property> + <property name="orient">wxVERTICAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">8</property> + <property name="flag">wxALIGN_CENTER_VERTICAL|wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label"></property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_staticTextSending</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size">-1,14</property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <property name="wrap">-1</property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">10</property> + <property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property> + <property name="proportion">1</property> + <object class="wxTextCtrl" expanded="1"> + <property name="bg">wxSYS_COLOUR_BTNFACE</property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="maximum_size"></property> + <property name="maxlength">0</property> + <property name="minimum_size"></property> + <property name="name">m_textCtrlStatus</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style">wxTE_CENTRE|wxTE_MULTILINE|wxTE_NO_VSCROLL|wxTE_READONLY</property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="value">

Connecting...</property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style">wxNO_BORDER</property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnText"></event> + <event name="OnTextEnter"></event> + <event name="OnTextMaxLen"></event> + <event name="OnTextURL"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer69</property> + <property name="orient">wxHORIZONTAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">1</property> + <object class="spacer" expanded="1"> + <property name="height">0</property> + <property name="permission">protected</property> + <property name="width">0</property> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxButton" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="default">0</property> + <property name="enabled">0</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">OK</property> + <property name="maximum_size"></property> + <property name="minimum_size">-1,-1</property> + <property name="name">m_buttonOK</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">OnButtonOK</event> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxButton" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="default">0</property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_CANCEL</property> + <property name="label">Cancel</property> + <property name="maximum_size"></property> + <property name="minimum_size">-1,-1</property> + <property name="name">m_buttonCancel</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size">-1,-1</property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">OnButtonCancel</event> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + </object> + </object> + </object> + </object> + <object class="Dialog" expanded="0"> + <property name="bg"></property> + <property name="center"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="extra_style"></property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">CYourAddressDialogBase</property> + <property name="pos"></property> + <property name="size">610,390</property> + <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property> + <property name="subclass"></property> + <property name="title">Your Bitcoin Addresses</property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnActivate"></event> + <event name="OnActivateApp"></event> + <event name="OnChar"></event> + <event name="OnClose">OnClose</event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnHibernate"></event> + <event name="OnIconize"></event> + <event name="OnIdle"></event> + <event name="OnInitDialog"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer68</property> + <property name="orient">wxVERTICAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">0</property> + <object class="spacer" expanded="1"> + <property name="height">5</property> + <property name="permission">protected</property> + <property name="width">0</property> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. The highlighted address is displayed in the main window.</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_staticText45</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <property name="wrap">590</property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL|wxEXPAND</property> + <property name="proportion">1</property> + <object class="wxListCtrl" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_LISTCTRL</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_listCtrl</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style">wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING</property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnListBeginDrag"></event> + <event name="OnListBeginLabelEdit"></event> + <event name="OnListBeginRDrag"></event> + <event name="OnListCacheHint"></event> + <event name="OnListColBeginDrag"></event> + <event name="OnListColClick"></event> + <event name="OnListColDragging"></event> + <event name="OnListColEndDrag"></event> + <event name="OnListColRightClick"></event> + <event name="OnListDeleteAllItems"></event> + <event name="OnListDeleteItem"></event> + <event name="OnListEndLabelEdit">OnListEndLabelEdit</event> + <event name="OnListInsertItem"></event> + <event name="OnListItemActivated">OnListItemActivated</event> + <event name="OnListItemDeselected"></event> + <event name="OnListItemFocused"></event> + <event name="OnListItemMiddleClick"></event> + <event name="OnListItemRightClick"></event> + <event name="OnListItemSelected">OnListItemSelected</event> + <event name="OnListKeyDown"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer69</property> + <property name="orient">wxHORIZONTAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">1</property> + <object class="spacer" expanded="1"> + <property name="height">0</property> + <property name="permission">protected</property> + <property name="width">0</property> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxButton" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="default">0</property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_BUTTONRENAME</property> + <property name="label">&Edit...</property> + <property name="maximum_size"></property> + <property name="minimum_size">-1,-1</property> + <property name="name">m_buttonRename</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">OnButtonRename</event> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxButton" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="default">0</property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_BUTTONNEW</property> + <property name="label"> &New Address... </property> + <property name="maximum_size"></property> + <property name="minimum_size">-1,-1</property> + <property name="name">m_buttonNew</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size">-1,-1</property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">OnButtonNew</event> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxButton" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="default">0</property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_BUTTONCOPY</property> + <property name="label"> &Copy to Clipboard </property> + <property name="maximum_size"></property> + <property name="minimum_size">-1,-1</property> + <property name="name">m_buttonCopy</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size">-1,-1</property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">OnButtonCopy</event> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxButton" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="default">0</property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_OK</property> + <property name="label">OK</property> + <property name="maximum_size"></property> + <property name="minimum_size">-1,-1</property> + <property name="name">m_buttonOK</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">OnButtonOK</event> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxButton" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="default">0</property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">1</property> + <property name="id">wxID_CANCEL</property> + <property name="label">Cancel</property> + <property name="maximum_size"></property> + <property name="minimum_size">-1,-1</property> + <property name="name">m_buttonCancel</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size">-1,-1</property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">OnButtonCancel</event> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + </object> + </object> + </object> + </object> + <object class="Dialog" expanded="0"> + <property name="bg"></property> + <property name="center"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="extra_style"></property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">CAddressBookDialogBase</property> + <property name="pos"></property> + <property name="size">610,390</property> + <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property> + <property name="subclass"></property> + <property name="title">Address Book</property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnActivate"></event> + <event name="OnActivateApp"></event> + <event name="OnChar"></event> + <event name="OnClose">OnClose</event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnHibernate"></event> + <event name="OnIconize"></event> + <event name="OnIdle"></event> + <event name="OnInitDialog"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer58</property> + <property name="orient">wxVERTICAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property> + <property name="proportion">1</property> + <object class="wxNotebook" expanded="1"> + <property name="bg"></property> + <property name="bitmapsize"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_notebook</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnNotebookPageChanged">OnNotebookPageChanged</event> + <event name="OnNotebookPageChanging"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + <object class="notebookpage" expanded="1"> + <property name="bitmap"></property> + <property name="label">Sending</property> + <property name="select">0</property> + <object class="wxPanel" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_PANELSENDING</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_panelSending</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style">wxTAB_TRAVERSAL</property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer68</property> + <property name="orient">wxVERTICAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">0</property> + <object class="spacer" expanded="1"> + <property name="height">0</property> + <property name="permission">protected</property> + <property name="width">0</property> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxTOP|wxRIGHT|wxLEFT</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">1</property> + <property name="id">wxID_ANY</property> + <property name="label">Bitcoin Address</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_staticText55</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <property name="wrap">-1</property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL|wxEXPAND</property> + <property name="proportion">1</property> + <object class="wxListCtrl" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_LISTCTRLSENDING</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_listCtrlSending</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style">wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING</property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnListBeginDrag"></event> + <event name="OnListBeginLabelEdit"></event> + <event name="OnListBeginRDrag"></event> + <event name="OnListCacheHint"></event> + <event name="OnListColBeginDrag"></event> + <event name="OnListColClick"></event> + <event name="OnListColDragging"></event> + <event name="OnListColEndDrag"></event> + <event name="OnListColRightClick"></event> + <event name="OnListDeleteAllItems"></event> + <event name="OnListDeleteItem"></event> + <event name="OnListEndLabelEdit">OnListEndLabelEdit</event> + <event name="OnListInsertItem"></event> + <event name="OnListItemActivated">OnListItemActivated</event> + <event name="OnListItemDeselected"></event> + <event name="OnListItemFocused"></event> + <event name="OnListItemMiddleClick"></event> + <event name="OnListItemRightClick"></event> + <event name="OnListItemSelected">OnListItemSelected</event> + <event name="OnListKeyDown"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + </object> + </object> + </object> + <object class="notebookpage" expanded="1"> + <property name="bitmap"></property> + <property name="label">Receiving</property> + <property name="select">1</property> + <object class="wxPanel" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_PANELRECEIVING</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_panelReceiving</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style">wxTAB_TRAVERSAL</property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer681</property> + <property name="orient">wxVERTICAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">0</property> + <object class="spacer" expanded="1"> + <property name="height">0</property> + <property name="permission">protected</property> + <property name="width">0</property> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">6</property> + <property name="flag">wxTOP|wxRIGHT|wxLEFT</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">These are your Bitcoin addresses for receiving payments. You can give a different one to each sender to keep track of who is paying you. The highlighted address will be displayed in the main window.</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_staticText45</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <property name="wrap">570</property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">0</property> + <object class="spacer" expanded="1"> + <property name="height">2</property> + <property name="permission">protected</property> + <property name="width">0</property> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL|wxEXPAND</property> + <property name="proportion">1</property> + <object class="wxListCtrl" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_LISTCTRLRECEIVING</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_listCtrlReceiving</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style">wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING</property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnListBeginDrag"></event> + <event name="OnListBeginLabelEdit"></event> + <event name="OnListBeginRDrag"></event> + <event name="OnListCacheHint"></event> + <event name="OnListColBeginDrag"></event> + <event name="OnListColClick"></event> + <event name="OnListColDragging"></event> + <event name="OnListColEndDrag"></event> + <event name="OnListColRightClick"></event> + <event name="OnListDeleteAllItems"></event> + <event name="OnListDeleteItem"></event> + <event name="OnListEndLabelEdit">OnListEndLabelEdit</event> + <event name="OnListInsertItem"></event> + <event name="OnListItemActivated">OnListItemActivated</event> + <event name="OnListItemDeselected"></event> + <event name="OnListItemFocused"></event> + <event name="OnListItemMiddleClick"></event> + <event name="OnListItemRightClick"></event> + <event name="OnListItemSelected">OnListItemSelected</event> + <event name="OnListKeyDown"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + </object> + </object> + </object> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer69</property> + <property name="orient">wxHORIZONTAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">1</property> + <object class="spacer" expanded="1"> + <property name="height">0</property> + <property name="permission">protected</property> + <property name="width">0</property> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxButton" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="default">0</property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_BUTTONDELETE</property> + <property name="label">&Delete</property> + <property name="maximum_size"></property> + <property name="minimum_size">-1,-1</property> + <property name="name">m_buttonDelete</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">OnButtonDelete</event> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxButton" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="default">0</property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_BUTTONCOPY</property> + <property name="label"> &Copy to Clipboard </property> + <property name="maximum_size"></property> + <property name="minimum_size">-1,-1</property> + <property name="name">m_buttonCopy</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size">-1,-1</property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">OnButtonCopy</event> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxButton" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="default">0</property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_BUTTONEDIT</property> + <property name="label">&Edit...</property> + <property name="maximum_size"></property> + <property name="minimum_size">-1,-1</property> + <property name="name">m_buttonEdit</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">OnButtonEdit</event> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxButton" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="default">0</property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_BUTTONNEW</property> + <property name="label"> &New Address... </property> + <property name="maximum_size"></property> + <property name="minimum_size">-1,-1</property> + <property name="name">m_buttonNew</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">OnButtonNew</event> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxButton" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="default">0</property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_OK</property> + <property name="label">OK</property> + <property name="maximum_size"></property> + <property name="minimum_size">-1,-1</property> + <property name="name">m_buttonOK</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size">-1,-1</property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">OnButtonOK</event> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxButton" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="default">0</property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_CANCEL</property> + <property name="label">Cancel</property> + <property name="maximum_size"></property> + <property name="minimum_size">-1,-1</property> + <property name="name">m_buttonCancel</property> + <property name="permission">public</property> + <property name="pos"></property> + <property name="size">-1,-1</property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">OnButtonCancel</event> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + </object> + </object> + </object> + </object> + <object class="Dialog" expanded="0"> + <property name="bg"></property> + <property name="center"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="extra_style"></property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">CGetTextFromUserDialogBase</property> + <property name="pos"></property> + <property name="size">440,138</property> + <property name="style">wxDEFAULT_DIALOG_STYLE</property> + <property name="subclass"></property> + <property name="title"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnActivate"></event> + <event name="OnActivateApp"></event> + <event name="OnChar"></event> + <event name="OnClose">OnClose</event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnHibernate"></event> + <event name="OnIconize"></event> + <event name="OnIdle"></event> + <event name="OnInitDialog"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer79</property> + <property name="orient">wxVERTICAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">10</property> + <property name="flag">wxEXPAND|wxALL</property> + <property name="proportion">1</property> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer81</property> + <property name="orient">wxVERTICAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">1</property> + <object class="spacer" expanded="1"> + <property name="height">0</property> + <property name="permission">protected</property> + <property name="width">0</property> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxTOP|wxRIGHT|wxLEFT</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label"></property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_staticTextMessage1</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <property name="wrap">-1</property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL</property> + <property name="proportion">0</property> + <object class="wxTextCtrl" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_TEXTCTRL</property> + <property name="maximum_size"></property> + <property name="maxlength">0</property> + <property name="minimum_size"></property> + <property name="name">m_textCtrl1</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style">wxTE_PROCESS_ENTER</property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="value"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown">OnKeyDown</event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnText"></event> + <event name="OnTextEnter"></event> + <event name="OnTextMaxLen"></event> + <event name="OnTextURL"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxTOP|wxRIGHT|wxLEFT</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">1</property> + <property name="id">wxID_ANY</property> + <property name="label"></property> + <property name="maximum_size"></property> + <property name="minimum_size"></property> + <property name="name">m_staticTextMessage2</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <property name="wrap">-1</property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL</property> + <property name="proportion">0</property> + <object class="wxTextCtrl" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">1</property> + <property name="id">wxID_TEXTCTRL</property> + <property name="maximum_size"></property> + <property name="maxlength">0</property> + <property name="minimum_size"></property> + <property name="name">m_textCtrl2</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style">wxTE_PROCESS_ENTER</property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="value"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown">OnKeyDown</event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnText"></event> + <event name="OnTextEnter"></event> + <event name="OnTextMaxLen"></event> + <event name="OnTextURL"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">1</property> + <object class="spacer" expanded="1"> + <property name="height">0</property> + <property name="permission">protected</property> + <property name="width">0</property> + </object> + </object> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxBoxSizer" expanded="1"> + <property name="minimum_size"></property> + <property name="name">bSizer80</property> + <property name="orient">wxHORIZONTAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">1</property> + <object class="spacer" expanded="1"> + <property name="height">0</property> + <property name="permission">protected</property> + <property name="width">0</property> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxButton" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="default">0</property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_OK</property> + <property name="label">OK</property> + <property name="maximum_size"></property> + <property name="minimum_size">-1,-1</property> + <property name="name">m_buttonOK</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size">-1,-1</property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">OnButtonOK</event> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + <object class="sizeritem" expanded="1"> + <property name="border">5</property> + <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxButton" expanded="1"> + <property name="bg"></property> + <property name="context_help"></property> + <property name="default">0</property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="font"></property> + <property name="hidden">0</property> + <property name="id">wxID_CANCEL</property> + <property name="label">Cancel</property> + <property name="maximum_size"></property> + <property name="minimum_size">-1,-1</property> + <property name="name">m_buttonCancel</property> + <property name="permission">protected</property> + <property name="pos"></property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="tooltip"></property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">OnButtonCancel</event> + <event name="OnChar"></event> + <event name="OnEnterWindow"></event> + <event name="OnEraseBackground"></event> + <event name="OnKeyDown"></event> + <event name="OnKeyUp"></event> + <event name="OnKillFocus"></event> + <event name="OnLeaveWindow"></event> + <event name="OnLeftDClick"></event> + <event name="OnLeftDown"></event> + <event name="OnLeftUp"></event> + <event name="OnMiddleDClick"></event> + <event name="OnMiddleDown"></event> + <event name="OnMiddleUp"></event> + <event name="OnMotion"></event> + <event name="OnMouseEvents"></event> + <event name="OnMouseWheel"></event> + <event name="OnPaint"></event> + <event name="OnRightDClick"></event> + <event name="OnRightDown"></event> + <event name="OnRightUp"></event> + <event name="OnSetFocus"></event> + <event name="OnSize"></event> + <event name="OnUpdateUI"></event> + </object> + </object> + </object> + </object> + </object> + </object> + </object> +</wxFormBuilder_Project> @@ -1,715 +1,715 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
-
-#include "headers.h"
-
-
-map<string, string> mapArgs;
-map<string, vector<string> > mapMultiArgs;
-bool fDebug = false;
-bool fPrintToConsole = false;
-bool fPrintToDebugger = false;
-char pszSetDataDir[MAX_PATH] = "";
-bool fShutdown = false;
-bool fDaemon = false;
-bool fCommandLine = false;
-
-
-
-
-
-// Init openssl library multithreading support
-static boost::interprocess::interprocess_mutex** ppmutexOpenSSL;
-void locking_callback(int mode, int i, const char* file, int line)
-{
- if (mode & CRYPTO_LOCK)
- ppmutexOpenSSL[i]->lock();
- else
- ppmutexOpenSSL[i]->unlock();
-}
-
-// Init
-class CInit
-{
-public:
- CInit()
- {
- // Init openssl library multithreading support
- ppmutexOpenSSL = (boost::interprocess::interprocess_mutex**)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(boost::interprocess::interprocess_mutex*));
- for (int i = 0; i < CRYPTO_num_locks(); i++)
- ppmutexOpenSSL[i] = new boost::interprocess::interprocess_mutex();
- CRYPTO_set_locking_callback(locking_callback);
-
-#ifdef __WXMSW__
- // Seed random number generator with screen scrape and other hardware sources
- RAND_screen();
-#endif
-
- // Seed random number generator with performance counter
- RandAddSeed();
- }
- ~CInit()
- {
- // Shutdown openssl library multithreading support
- CRYPTO_set_locking_callback(NULL);
- for (int i = 0; i < CRYPTO_num_locks(); i++)
- delete ppmutexOpenSSL[i];
- OPENSSL_free(ppmutexOpenSSL);
- }
-}
-instance_of_cinit;
-
-
-
-
-
-
-
-
-void RandAddSeed()
-{
- // Seed with CPU performance counter
- int64 nCounter = PerformanceCounter();
- RAND_add(&nCounter, sizeof(nCounter), 1.5);
- memset(&nCounter, 0, sizeof(nCounter));
-}
-
-void RandAddSeedPerfmon()
-{
- RandAddSeed();
-
- // This can take up to 2 seconds, so only do it every 10 minutes
- static int64 nLastPerfmon;
- if (GetTime() < nLastPerfmon + 10 * 60)
- return;
- nLastPerfmon = GetTime();
-
-#ifdef __WXMSW__
- // Don't need this on Linux, OpenSSL automatically uses /dev/urandom
- // Seed with the entire set of perfmon data
- unsigned char pdata[250000];
- memset(pdata, 0, sizeof(pdata));
- unsigned long nSize = sizeof(pdata);
- long ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize);
- RegCloseKey(HKEY_PERFORMANCE_DATA);
- if (ret == ERROR_SUCCESS)
- {
- uint256 hash;
- SHA256(pdata, nSize, (unsigned char*)&hash);
- RAND_add(&hash, sizeof(hash), min(nSize/500.0, (double)sizeof(hash)));
- hash = 0;
- memset(pdata, 0, nSize);
-
- printf("%s RandAddSeed() %d bytes\n", DateTimeStrFormat("%x %H:%M", GetTime()).c_str(), nSize);
- }
-#endif
-}
-
-uint64 GetRand(uint64 nMax)
-{
- if (nMax == 0)
- return 0;
-
- // The range of the random source must be a multiple of the modulus
- // to give every possible output value an equal possibility
- uint64 nRange = (UINT64_MAX / nMax) * nMax;
- uint64 nRand = 0;
- do
- RAND_bytes((unsigned char*)&nRand, sizeof(nRand));
- while (nRand >= nRange);
- return (nRand % nMax);
-}
-
-
-
-
-
-
-
-
-
-
-
-inline int OutputDebugStringF(const char* pszFormat, ...)
-{
- int ret = 0;
- if (fPrintToConsole || wxTheApp == NULL)
- {
- // print to console
- va_list arg_ptr;
- va_start(arg_ptr, pszFormat);
- ret = vprintf(pszFormat, arg_ptr);
- va_end(arg_ptr);
- }
- else
- {
- // print to debug.log
- char pszFile[MAX_PATH+100];
- GetDataDir(pszFile);
- strlcat(pszFile, "/debug.log", sizeof(pszFile));
- FILE* fileout = fopen(pszFile, "a");
- if (fileout)
- {
- //// Debug print useful for profiling
- //fprintf(fileout, " %"PRI64d" ", GetTimeMillis());
- va_list arg_ptr;
- va_start(arg_ptr, pszFormat);
- ret = vfprintf(fileout, pszFormat, arg_ptr);
- va_end(arg_ptr);
- fclose(fileout);
- }
- }
-
-#ifdef __WXMSW__
- if (fPrintToDebugger)
- {
- // accumulate a line at a time
- static CCriticalSection cs_OutputDebugStringF;
- CRITICAL_BLOCK(cs_OutputDebugStringF)
- {
- static char pszBuffer[50000];
- static char* pend;
- if (pend == NULL)
- pend = pszBuffer;
- va_list arg_ptr;
- va_start(arg_ptr, pszFormat);
- int limit = END(pszBuffer) - pend - 2;
- int ret = _vsnprintf(pend, limit, pszFormat, arg_ptr);
- va_end(arg_ptr);
- if (ret < 0 || ret >= limit)
- {
- pend = END(pszBuffer) - 2;
- *pend++ = '\n';
- }
- else
- pend += ret;
- *pend = '\0';
- char* p1 = pszBuffer;
- char* p2;
- while (p2 = strchr(p1, '\n'))
- {
- p2++;
- char c = *p2;
- *p2 = '\0';
- OutputDebugStringA(p1);
- *p2 = c;
- p1 = p2;
- }
- if (p1 != pszBuffer)
- memmove(pszBuffer, p1, pend - p1 + 1);
- pend -= (p1 - pszBuffer);
- }
- }
-#endif
- return ret;
-}
-
-
-// Safer snprintf
-// - prints up to limit-1 characters
-// - output string is always null terminated even if limit reached
-// - return value is the number of characters actually printed
-int my_snprintf(char* buffer, size_t limit, const char* format, ...)
-{
- if (limit == 0)
- return 0;
- va_list arg_ptr;
- va_start(arg_ptr, format);
- int ret = _vsnprintf(buffer, limit, format, arg_ptr);
- va_end(arg_ptr);
- if (ret < 0 || ret >= limit)
- {
- ret = limit - 1;
- buffer[limit-1] = 0;
- }
- return ret;
-}
-
-
-string strprintf(const char* format, ...)
-{
- char buffer[50000];
- char* p = buffer;
- int limit = sizeof(buffer);
- int ret;
- loop
- {
- va_list arg_ptr;
- va_start(arg_ptr, format);
- ret = _vsnprintf(p, limit, format, arg_ptr);
- va_end(arg_ptr);
- if (ret >= 0 && ret < limit)
- break;
- if (p != buffer)
- delete p;
- limit *= 2;
- p = new char[limit];
- if (p == NULL)
- throw std::bad_alloc();
- }
- string str(p, p+ret);
- if (p != buffer)
- delete p;
- return str;
-}
-
-
-bool error(const char* format, ...)
-{
- char buffer[50000];
- int limit = sizeof(buffer);
- va_list arg_ptr;
- va_start(arg_ptr, format);
- int ret = _vsnprintf(buffer, limit, format, arg_ptr);
- va_end(arg_ptr);
- if (ret < 0 || ret >= limit)
- {
- ret = limit - 1;
- buffer[limit-1] = 0;
- }
- printf("ERROR: %s\n", buffer);
- return false;
-}
-
-
-void ParseString(const string& str, char c, vector<string>& v)
-{
- if (str.empty())
- return;
- string::size_type i1 = 0;
- string::size_type i2;
- loop
- {
- i2 = str.find(c, i1);
- if (i2 == str.npos)
- {
- v.push_back(str.substr(i1));
- return;
- }
- v.push_back(str.substr(i1, i2-i1));
- i1 = i2+1;
- }
-}
-
-
-string FormatMoney(int64 n, bool fPlus)
-{
- n /= CENT;
- string str = strprintf("%"PRI64d".%02"PRI64d, (n > 0 ? n : -n)/100, (n > 0 ? n : -n)%100);
- for (int i = 6; i < str.size(); i += 4)
- if (isdigit(str[str.size() - i - 1]))
- str.insert(str.size() - i, 1, ',');
- if (n < 0)
- str.insert((unsigned int)0, 1, '-');
- else if (fPlus && n > 0)
- str.insert((unsigned int)0, 1, '+');
- return str;
-}
-
-
-bool ParseMoney(const string& str, int64& nRet)
-{
- return ParseMoney(str.c_str(), nRet);
-}
-
-bool ParseMoney(const char* pszIn, int64& nRet)
-{
- string strWhole;
- int64 nCents = 0;
- const char* p = pszIn;
- while (isspace(*p))
- p++;
- for (; *p; p++)
- {
- if (*p == ',' && p > pszIn && isdigit(p[-1]) && isdigit(p[1]) && isdigit(p[2]) && isdigit(p[3]) && !isdigit(p[4]))
- continue;
- if (*p == '.')
- {
- p++;
- if (isdigit(*p))
- {
- nCents = 10 * (*p++ - '0');
- if (isdigit(*p))
- nCents += (*p++ - '0');
- }
- break;
- }
- if (isspace(*p))
- break;
- if (!isdigit(*p))
- return false;
- strWhole.insert(strWhole.end(), *p);
- }
- for (; *p; p++)
- if (!isspace(*p))
- return false;
- if (strWhole.size() > 14)
- return false;
- if (nCents < 0 || nCents > 99)
- return false;
- int64 nWhole = atoi64(strWhole);
- int64 nPreValue = nWhole * 100 + nCents;
- int64 nValue = nPreValue * CENT;
- if (nValue / CENT != nPreValue)
- return false;
- if (nValue / COIN != nWhole)
- return false;
- nRet = nValue;
- return true;
-}
-
-
-vector<unsigned char> ParseHex(const char* psz)
-{
- vector<unsigned char> vch;
- while (isspace(*psz))
- psz++;
- vch.reserve((strlen(psz)+1)/3);
-
- static char phexdigit[256] =
- { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- 0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1,
- -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, };
-
- while (*psz)
- {
- char c = phexdigit[(unsigned char)*psz++];
- if (c == -1)
- break;
- unsigned char n = (c << 4);
- if (*psz)
- {
- char c = phexdigit[(unsigned char)*psz++];
- if (c == -1)
- break;
- n |= c;
- vch.push_back(n);
- }
- while (isspace(*psz))
- psz++;
- }
-
- return vch;
-}
-
-vector<unsigned char> ParseHex(const std::string& str)
-{
- return ParseHex(str.c_str());
-}
-
-
-void ParseParameters(int argc, char* argv[])
-{
- mapArgs.clear();
- mapMultiArgs.clear();
- for (int i = 0; i < argc; i++)
- {
- char psz[10000];
- strlcpy(psz, argv[i], sizeof(psz));
- char* pszValue = (char*)"";
- if (strchr(psz, '='))
- {
- pszValue = strchr(psz, '=');
- *pszValue++ = '\0';
- }
- #ifdef __WXMSW__
- _strlwr(psz);
- if (psz[0] == '/')
- psz[0] = '-';
- #endif
- mapArgs[psz] = pszValue;
- mapMultiArgs[psz].push_back(pszValue);
- }
-}
-
-
-const char* wxGetTranslation(const char* pszEnglish)
-{
- // Wrapper of wxGetTranslation returning the same const char* type as was passed in
- static CCriticalSection cs;
- CRITICAL_BLOCK(cs)
- {
- // Look in cache
- static map<string, char*> mapCache;
- map<string, char*>::iterator mi = mapCache.find(pszEnglish);
- if (mi != mapCache.end())
- return (*mi).second;
-
- // wxWidgets translation
- wxString strTranslated = wxGetTranslation(wxString(pszEnglish, wxConvUTF8));
-
- // We don't cache unknown strings because caller might be passing in a
- // dynamic string and we would keep allocating memory for each variation.
- if (strcmp(pszEnglish, strTranslated.utf8_str()) == 0)
- return pszEnglish;
-
- // Add to cache, memory doesn't need to be freed. We only cache because
- // we must pass back a pointer to permanently allocated memory.
- char* pszCached = new char[strlen(strTranslated.utf8_str())+1];
- strcpy(pszCached, strTranslated.utf8_str());
- mapCache[pszEnglish] = pszCached;
- return pszCached;
- }
- return NULL;
-}
-
-
-
-
-
-
-
-
-
-
-void FormatException(char* pszMessage, std::exception* pex, const char* pszThread)
-{
-#ifdef __WXMSW__
- char pszModule[MAX_PATH];
- pszModule[0] = '\0';
- GetModuleFileNameA(NULL, pszModule, sizeof(pszModule));
-#else
- // might not be thread safe, uses wxString
- //const char* pszModule = wxStandardPaths::Get().GetExecutablePath().mb_str();
- const char* pszModule = "bitcoin";
-#endif
- if (pex)
- snprintf(pszMessage, 1000,
- "EXCEPTION: %s \n%s \n%s in %s \n", typeid(*pex).name(), pex->what(), pszModule, pszThread);
- else
- snprintf(pszMessage, 1000,
- "UNKNOWN EXCEPTION \n%s in %s \n", pszModule, pszThread);
-}
-
-void LogException(std::exception* pex, const char* pszThread)
-{
- char pszMessage[1000];
- FormatException(pszMessage, pex, pszThread);
- printf("\n%s", pszMessage);
-}
-
-void PrintException(std::exception* pex, const char* pszThread)
-{
- char pszMessage[1000];
- FormatException(pszMessage, pex, pszThread);
- printf("\n\n************************\n%s\n", pszMessage);
- fprintf(stderr, "\n\n************************\n%s\n", pszMessage);
- if (wxTheApp && !fDaemon && fGUI)
- MyMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR);
- throw;
- //DebugBreak();
-}
-
-
-
-
-
-
-
-
-#ifdef __WXMSW__
-typedef WINSHELLAPI BOOL (WINAPI *PSHGETSPECIALFOLDERPATHA)(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate);
-
-string MyGetSpecialFolderPath(int nFolder, bool fCreate)
-{
- char pszPath[MAX_PATH+100] = "";
-
- // SHGetSpecialFolderPath isn't always available on old Windows versions
- HMODULE hShell32 = LoadLibraryA("shell32.dll");
- if (hShell32)
- {
- PSHGETSPECIALFOLDERPATHA pSHGetSpecialFolderPath =
- (PSHGETSPECIALFOLDERPATHA)GetProcAddress(hShell32, "SHGetSpecialFolderPathA");
- if (pSHGetSpecialFolderPath)
- (*pSHGetSpecialFolderPath)(NULL, pszPath, nFolder, fCreate);
- FreeModule(hShell32);
- }
-
- // Backup option
- if (pszPath[0] == '\0')
- {
- if (nFolder == CSIDL_STARTUP)
- {
- strcpy(pszPath, getenv("USERPROFILE"));
- strcat(pszPath, "\\Start Menu\\Programs\\Startup");
- }
- else if (nFolder == CSIDL_APPDATA)
- {
- strcpy(pszPath, getenv("APPDATA"));
- }
- }
-
- return pszPath;
-}
-#endif
-
-string GetDefaultDataDir()
-{
- // Windows: C:\Documents and Settings\username\Application Data\Bitcoin
- // Mac: ~/Library/Application Support/Bitcoin
- // Unix: ~/.bitcoin
-#ifdef __WXMSW__
- // Windows
- return MyGetSpecialFolderPath(CSIDL_APPDATA, true) + "\\Bitcoin";
-#else
- char* pszHome = getenv("HOME");
- if (pszHome == NULL || strlen(pszHome) == 0)
- pszHome = (char*)"/";
- string strHome = pszHome;
- if (strHome[strHome.size()-1] != '/')
- strHome += '/';
-#ifdef __WXOSX__
- // Mac
- strHome += "Library/Application Support/";
- _mkdir(strHome.c_str());
- return strHome + "Bitcoin";
-#else
- // Unix
- return strHome + ".bitcoin";
-#endif
-#endif
-}
-
-void GetDataDir(char* pszDir)
-{
- // pszDir must be at least MAX_PATH length.
- if (pszSetDataDir[0] != 0)
- {
- strlcpy(pszDir, pszSetDataDir, MAX_PATH);
- static bool fMkdirDone;
- if (!fMkdirDone)
- {
- fMkdirDone = true;
- _mkdir(pszDir);
- }
- }
- else
- {
- // This can be called during exceptions by printf, so we cache the
- // value so we don't have to do memory allocations after that.
- static char pszCachedDir[MAX_PATH];
- if (pszCachedDir[0] == 0)
- {
- //strlcpy(pszCachedDir, wxStandardPaths::Get().GetUserDataDir().c_str(), sizeof(pszCachedDir));
- strlcpy(pszCachedDir, GetDefaultDataDir().c_str(), sizeof(pszCachedDir));
- _mkdir(pszCachedDir);
- }
- strlcpy(pszDir, pszCachedDir, MAX_PATH);
- }
-}
-
-string GetDataDir()
-{
- char pszDir[MAX_PATH];
- GetDataDir(pszDir);
- return pszDir;
-}
-
-int GetFilesize(FILE* file)
-{
- int nSavePos = ftell(file);
- int nFilesize = -1;
- if (fseek(file, 0, SEEK_END) == 0)
- nFilesize = ftell(file);
- fseek(file, nSavePos, SEEK_SET);
- return nFilesize;
-}
-
-void ShrinkDebugFile()
-{
- // Scroll debug.log if it's getting too big
- string strFile = GetDataDir() + "/debug.log";
- FILE* file = fopen(strFile.c_str(), "r");
- if (file && GetFilesize(file) > 10 * 1000000)
- {
- // Restart the file with some of the end
- char pch[200000];
- fseek(file, -sizeof(pch), SEEK_END);
- int nBytes = fread(pch, 1, sizeof(pch), file);
- fclose(file);
- if (file = fopen(strFile.c_str(), "w"))
- {
- fwrite(pch, 1, nBytes, file);
- fclose(file);
- }
- }
-}
-
-
-
-
-
-
-
-
-
-
-
-//
-// "Never go to sea with two chronometers; take one or three."
-// Our three chronometers are:
-// - System clock
-// - Median of other server's clocks
-// - NTP servers
-//
-// note: NTP isn't implemented yet, so until then we just use the median
-// of other nodes clocks to correct ours.
-//
-int64 GetTime()
-{
- return time(NULL);
-}
-
-static int64 nTimeOffset = 0;
-
-int64 GetAdjustedTime()
-{
- return GetTime() + nTimeOffset;
-}
-
-void AddTimeData(unsigned int ip, int64 nTime)
-{
- int64 nOffsetSample = nTime - GetTime();
-
- // Ignore duplicates
- static set<unsigned int> setKnown;
- if (!setKnown.insert(ip).second)
- return;
-
- // Add data
- static vector<int64> vTimeOffsets;
- if (vTimeOffsets.empty())
- vTimeOffsets.push_back(0);
- vTimeOffsets.push_back(nOffsetSample);
- printf("Added time data, samples %d, offset %+"PRI64d" (%+"PRI64d" minutes)\n", vTimeOffsets.size(), vTimeOffsets.back(), vTimeOffsets.back()/60);
- if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1)
- {
- sort(vTimeOffsets.begin(), vTimeOffsets.end());
- int64 nMedian = vTimeOffsets[vTimeOffsets.size()/2];
- nTimeOffset = nMedian;
- if ((nMedian > 0 ? nMedian : -nMedian) > 5 * 60)
- {
- // Only let other nodes change our clock so far before we
- // go to the NTP servers
- /// todo: Get time from NTP servers, then set a flag
- /// to make sure it doesn't get changed again
- }
- foreach(int64 n, vTimeOffsets)
- printf("%+"PRI64d" ", n);
- printf("| nTimeOffset = %+"PRI64d" (%+"PRI64d" minutes)\n", nTimeOffset, nTimeOffset/60);
- }
-}
+// Copyright (c) 2009-2010 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +#include "headers.h" + + +map<string, string> mapArgs; +map<string, vector<string> > mapMultiArgs; +bool fDebug = false; +bool fPrintToConsole = false; +bool fPrintToDebugger = false; +char pszSetDataDir[MAX_PATH] = ""; +bool fShutdown = false; +bool fDaemon = false; +bool fCommandLine = false; + + + + + +// Init openssl library multithreading support +static boost::interprocess::interprocess_mutex** ppmutexOpenSSL; +void locking_callback(int mode, int i, const char* file, int line) +{ + if (mode & CRYPTO_LOCK) + ppmutexOpenSSL[i]->lock(); + else + ppmutexOpenSSL[i]->unlock(); +} + +// Init +class CInit +{ +public: + CInit() + { + // Init openssl library multithreading support + ppmutexOpenSSL = (boost::interprocess::interprocess_mutex**)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(boost::interprocess::interprocess_mutex*)); + for (int i = 0; i < CRYPTO_num_locks(); i++) + ppmutexOpenSSL[i] = new boost::interprocess::interprocess_mutex(); + CRYPTO_set_locking_callback(locking_callback); + +#ifdef __WXMSW__ + // Seed random number generator with screen scrape and other hardware sources + RAND_screen(); +#endif + + // Seed random number generator with performance counter + RandAddSeed(); + } + ~CInit() + { + // Shutdown openssl library multithreading support + CRYPTO_set_locking_callback(NULL); + for (int i = 0; i < CRYPTO_num_locks(); i++) + delete ppmutexOpenSSL[i]; + OPENSSL_free(ppmutexOpenSSL); + } +} +instance_of_cinit; + + + + + + + + +void RandAddSeed() +{ + // Seed with CPU performance counter + int64 nCounter = PerformanceCounter(); + RAND_add(&nCounter, sizeof(nCounter), 1.5); + memset(&nCounter, 0, sizeof(nCounter)); +} + +void RandAddSeedPerfmon() +{ + RandAddSeed(); + + // This can take up to 2 seconds, so only do it every 10 minutes + static int64 nLastPerfmon; + if (GetTime() < nLastPerfmon + 10 * 60) + return; + nLastPerfmon = GetTime(); + +#ifdef __WXMSW__ + // Don't need this on Linux, OpenSSL automatically uses /dev/urandom + // Seed with the entire set of perfmon data + unsigned char pdata[250000]; + memset(pdata, 0, sizeof(pdata)); + unsigned long nSize = sizeof(pdata); + long ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize); + RegCloseKey(HKEY_PERFORMANCE_DATA); + if (ret == ERROR_SUCCESS) + { + uint256 hash; + SHA256(pdata, nSize, (unsigned char*)&hash); + RAND_add(&hash, sizeof(hash), min(nSize/500.0, (double)sizeof(hash))); + hash = 0; + memset(pdata, 0, nSize); + + printf("%s RandAddSeed() %d bytes\n", DateTimeStrFormat("%x %H:%M", GetTime()).c_str(), nSize); + } +#endif +} + +uint64 GetRand(uint64 nMax) +{ + if (nMax == 0) + return 0; + + // The range of the random source must be a multiple of the modulus + // to give every possible output value an equal possibility + uint64 nRange = (UINT64_MAX / nMax) * nMax; + uint64 nRand = 0; + do + RAND_bytes((unsigned char*)&nRand, sizeof(nRand)); + while (nRand >= nRange); + return (nRand % nMax); +} + + + + + + + + + + + +inline int OutputDebugStringF(const char* pszFormat, ...) +{ + int ret = 0; + if (fPrintToConsole || wxTheApp == NULL) + { + // print to console + va_list arg_ptr; + va_start(arg_ptr, pszFormat); + ret = vprintf(pszFormat, arg_ptr); + va_end(arg_ptr); + } + else + { + // print to debug.log + char pszFile[MAX_PATH+100]; + GetDataDir(pszFile); + strlcat(pszFile, "/debug.log", sizeof(pszFile)); + FILE* fileout = fopen(pszFile, "a"); + if (fileout) + { + //// Debug print useful for profiling + //fprintf(fileout, " %"PRI64d" ", GetTimeMillis()); + va_list arg_ptr; + va_start(arg_ptr, pszFormat); + ret = vfprintf(fileout, pszFormat, arg_ptr); + va_end(arg_ptr); + fclose(fileout); + } + } + +#ifdef __WXMSW__ + if (fPrintToDebugger) + { + // accumulate a line at a time + static CCriticalSection cs_OutputDebugStringF; + CRITICAL_BLOCK(cs_OutputDebugStringF) + { + static char pszBuffer[50000]; + static char* pend; + if (pend == NULL) + pend = pszBuffer; + va_list arg_ptr; + va_start(arg_ptr, pszFormat); + int limit = END(pszBuffer) - pend - 2; + int ret = _vsnprintf(pend, limit, pszFormat, arg_ptr); + va_end(arg_ptr); + if (ret < 0 || ret >= limit) + { + pend = END(pszBuffer) - 2; + *pend++ = '\n'; + } + else + pend += ret; + *pend = '\0'; + char* p1 = pszBuffer; + char* p2; + while (p2 = strchr(p1, '\n')) + { + p2++; + char c = *p2; + *p2 = '\0'; + OutputDebugStringA(p1); + *p2 = c; + p1 = p2; + } + if (p1 != pszBuffer) + memmove(pszBuffer, p1, pend - p1 + 1); + pend -= (p1 - pszBuffer); + } + } +#endif + return ret; +} + + +// Safer snprintf +// - prints up to limit-1 characters +// - output string is always null terminated even if limit reached +// - return value is the number of characters actually printed +int my_snprintf(char* buffer, size_t limit, const char* format, ...) +{ + if (limit == 0) + return 0; + va_list arg_ptr; + va_start(arg_ptr, format); + int ret = _vsnprintf(buffer, limit, format, arg_ptr); + va_end(arg_ptr); + if (ret < 0 || ret >= limit) + { + ret = limit - 1; + buffer[limit-1] = 0; + } + return ret; +} + + +string strprintf(const char* format, ...) +{ + char buffer[50000]; + char* p = buffer; + int limit = sizeof(buffer); + int ret; + loop + { + va_list arg_ptr; + va_start(arg_ptr, format); + ret = _vsnprintf(p, limit, format, arg_ptr); + va_end(arg_ptr); + if (ret >= 0 && ret < limit) + break; + if (p != buffer) + delete p; + limit *= 2; + p = new char[limit]; + if (p == NULL) + throw std::bad_alloc(); + } + string str(p, p+ret); + if (p != buffer) + delete p; + return str; +} + + +bool error(const char* format, ...) +{ + char buffer[50000]; + int limit = sizeof(buffer); + va_list arg_ptr; + va_start(arg_ptr, format); + int ret = _vsnprintf(buffer, limit, format, arg_ptr); + va_end(arg_ptr); + if (ret < 0 || ret >= limit) + { + ret = limit - 1; + buffer[limit-1] = 0; + } + printf("ERROR: %s\n", buffer); + return false; +} + + +void ParseString(const string& str, char c, vector<string>& v) +{ + if (str.empty()) + return; + string::size_type i1 = 0; + string::size_type i2; + loop + { + i2 = str.find(c, i1); + if (i2 == str.npos) + { + v.push_back(str.substr(i1)); + return; + } + v.push_back(str.substr(i1, i2-i1)); + i1 = i2+1; + } +} + + +string FormatMoney(int64 n, bool fPlus) +{ + n /= CENT; + string str = strprintf("%"PRI64d".%02"PRI64d, (n > 0 ? n : -n)/100, (n > 0 ? n : -n)%100); + for (int i = 6; i < str.size(); i += 4) + if (isdigit(str[str.size() - i - 1])) + str.insert(str.size() - i, 1, ','); + if (n < 0) + str.insert((unsigned int)0, 1, '-'); + else if (fPlus && n > 0) + str.insert((unsigned int)0, 1, '+'); + return str; +} + + +bool ParseMoney(const string& str, int64& nRet) +{ + return ParseMoney(str.c_str(), nRet); +} + +bool ParseMoney(const char* pszIn, int64& nRet) +{ + string strWhole; + int64 nCents = 0; + const char* p = pszIn; + while (isspace(*p)) + p++; + for (; *p; p++) + { + if (*p == ',' && p > pszIn && isdigit(p[-1]) && isdigit(p[1]) && isdigit(p[2]) && isdigit(p[3]) && !isdigit(p[4])) + continue; + if (*p == '.') + { + p++; + if (isdigit(*p)) + { + nCents = 10 * (*p++ - '0'); + if (isdigit(*p)) + nCents += (*p++ - '0'); + } + break; + } + if (isspace(*p)) + break; + if (!isdigit(*p)) + return false; + strWhole.insert(strWhole.end(), *p); + } + for (; *p; p++) + if (!isspace(*p)) + return false; + if (strWhole.size() > 14) + return false; + if (nCents < 0 || nCents > 99) + return false; + int64 nWhole = atoi64(strWhole); + int64 nPreValue = nWhole * 100 + nCents; + int64 nValue = nPreValue * CENT; + if (nValue / CENT != nPreValue) + return false; + if (nValue / COIN != nWhole) + return false; + nRet = nValue; + return true; +} + + +vector<unsigned char> ParseHex(const char* psz) +{ + vector<unsigned char> vch; + while (isspace(*psz)) + psz++; + vch.reserve((strlen(psz)+1)/3); + + static char phexdigit[256] = + { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + 0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1, + -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1 + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, }; + + while (*psz) + { + char c = phexdigit[(unsigned char)*psz++]; + if (c == -1) + break; + unsigned char n = (c << 4); + if (*psz) + { + char c = phexdigit[(unsigned char)*psz++]; + if (c == -1) + break; + n |= c; + vch.push_back(n); + } + while (isspace(*psz)) + psz++; + } + + return vch; +} + +vector<unsigned char> ParseHex(const std::string& str) +{ + return ParseHex(str.c_str()); +} + + +void ParseParameters(int argc, char* argv[]) +{ + mapArgs.clear(); + mapMultiArgs.clear(); + for (int i = 0; i < argc; i++) + { + char psz[10000]; + strlcpy(psz, argv[i], sizeof(psz)); + char* pszValue = (char*)""; + if (strchr(psz, '=')) + { + pszValue = strchr(psz, '='); + *pszValue++ = '\0'; + } + #ifdef __WXMSW__ + _strlwr(psz); + if (psz[0] == '/') + psz[0] = '-'; + #endif + mapArgs[psz] = pszValue; + mapMultiArgs[psz].push_back(pszValue); + } +} + + +const char* wxGetTranslation(const char* pszEnglish) +{ + // Wrapper of wxGetTranslation returning the same const char* type as was passed in + static CCriticalSection cs; + CRITICAL_BLOCK(cs) + { + // Look in cache + static map<string, char*> mapCache; + map<string, char*>::iterator mi = mapCache.find(pszEnglish); + if (mi != mapCache.end()) + return (*mi).second; + + // wxWidgets translation + wxString strTranslated = wxGetTranslation(wxString(pszEnglish, wxConvUTF8)); + + // We don't cache unknown strings because caller might be passing in a + // dynamic string and we would keep allocating memory for each variation. + if (strcmp(pszEnglish, strTranslated.utf8_str()) == 0) + return pszEnglish; + + // Add to cache, memory doesn't need to be freed. We only cache because + // we must pass back a pointer to permanently allocated memory. + char* pszCached = new char[strlen(strTranslated.utf8_str())+1]; + strcpy(pszCached, strTranslated.utf8_str()); + mapCache[pszEnglish] = pszCached; + return pszCached; + } + return NULL; +} + + + + + + + + + + +void FormatException(char* pszMessage, std::exception* pex, const char* pszThread) +{ +#ifdef __WXMSW__ + char pszModule[MAX_PATH]; + pszModule[0] = '\0'; + GetModuleFileNameA(NULL, pszModule, sizeof(pszModule)); +#else + // might not be thread safe, uses wxString + //const char* pszModule = wxStandardPaths::Get().GetExecutablePath().mb_str(); + const char* pszModule = "bitcoin"; +#endif + if (pex) + snprintf(pszMessage, 1000, + "EXCEPTION: %s \n%s \n%s in %s \n", typeid(*pex).name(), pex->what(), pszModule, pszThread); + else + snprintf(pszMessage, 1000, + "UNKNOWN EXCEPTION \n%s in %s \n", pszModule, pszThread); +} + +void LogException(std::exception* pex, const char* pszThread) +{ + char pszMessage[1000]; + FormatException(pszMessage, pex, pszThread); + printf("\n%s", pszMessage); +} + +void PrintException(std::exception* pex, const char* pszThread) +{ + char pszMessage[1000]; + FormatException(pszMessage, pex, pszThread); + printf("\n\n************************\n%s\n", pszMessage); + fprintf(stderr, "\n\n************************\n%s\n", pszMessage); + if (wxTheApp && !fDaemon && fGUI) + MyMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR); + throw; + //DebugBreak(); +} + + + + + + + + +#ifdef __WXMSW__ +typedef WINSHELLAPI BOOL (WINAPI *PSHGETSPECIALFOLDERPATHA)(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate); + +string MyGetSpecialFolderPath(int nFolder, bool fCreate) +{ + char pszPath[MAX_PATH+100] = ""; + + // SHGetSpecialFolderPath isn't always available on old Windows versions + HMODULE hShell32 = LoadLibraryA("shell32.dll"); + if (hShell32) + { + PSHGETSPECIALFOLDERPATHA pSHGetSpecialFolderPath = + (PSHGETSPECIALFOLDERPATHA)GetProcAddress(hShell32, "SHGetSpecialFolderPathA"); + if (pSHGetSpecialFolderPath) + (*pSHGetSpecialFolderPath)(NULL, pszPath, nFolder, fCreate); + FreeModule(hShell32); + } + + // Backup option + if (pszPath[0] == '\0') + { + if (nFolder == CSIDL_STARTUP) + { + strcpy(pszPath, getenv("USERPROFILE")); + strcat(pszPath, "\\Start Menu\\Programs\\Startup"); + } + else if (nFolder == CSIDL_APPDATA) + { + strcpy(pszPath, getenv("APPDATA")); + } + } + + return pszPath; +} +#endif + +string GetDefaultDataDir() +{ + // Windows: C:\Documents and Settings\username\Application Data\Bitcoin + // Mac: ~/Library/Application Support/Bitcoin + // Unix: ~/.bitcoin +#ifdef __WXMSW__ + // Windows + return MyGetSpecialFolderPath(CSIDL_APPDATA, true) + "\\Bitcoin"; +#else + char* pszHome = getenv("HOME"); + if (pszHome == NULL || strlen(pszHome) == 0) + pszHome = (char*)"/"; + string strHome = pszHome; + if (strHome[strHome.size()-1] != '/') + strHome += '/'; +#ifdef __WXOSX__ + // Mac + strHome += "Library/Application Support/"; + _mkdir(strHome.c_str()); + return strHome + "Bitcoin"; +#else + // Unix + return strHome + ".bitcoin"; +#endif +#endif +} + +void GetDataDir(char* pszDir) +{ + // pszDir must be at least MAX_PATH length. + if (pszSetDataDir[0] != 0) + { + strlcpy(pszDir, pszSetDataDir, MAX_PATH); + static bool fMkdirDone; + if (!fMkdirDone) + { + fMkdirDone = true; + _mkdir(pszDir); + } + } + else + { + // This can be called during exceptions by printf, so we cache the + // value so we don't have to do memory allocations after that. + static char pszCachedDir[MAX_PATH]; + if (pszCachedDir[0] == 0) + { + //strlcpy(pszCachedDir, wxStandardPaths::Get().GetUserDataDir().c_str(), sizeof(pszCachedDir)); + strlcpy(pszCachedDir, GetDefaultDataDir().c_str(), sizeof(pszCachedDir)); + _mkdir(pszCachedDir); + } + strlcpy(pszDir, pszCachedDir, MAX_PATH); + } +} + +string GetDataDir() +{ + char pszDir[MAX_PATH]; + GetDataDir(pszDir); + return pszDir; +} + +int GetFilesize(FILE* file) +{ + int nSavePos = ftell(file); + int nFilesize = -1; + if (fseek(file, 0, SEEK_END) == 0) + nFilesize = ftell(file); + fseek(file, nSavePos, SEEK_SET); + return nFilesize; +} + +void ShrinkDebugFile() +{ + // Scroll debug.log if it's getting too big + string strFile = GetDataDir() + "/debug.log"; + FILE* file = fopen(strFile.c_str(), "r"); + if (file && GetFilesize(file) > 10 * 1000000) + { + // Restart the file with some of the end + char pch[200000]; + fseek(file, -sizeof(pch), SEEK_END); + int nBytes = fread(pch, 1, sizeof(pch), file); + fclose(file); + if (file = fopen(strFile.c_str(), "w")) + { + fwrite(pch, 1, nBytes, file); + fclose(file); + } + } +} + + + + + + + + + + + +// +// "Never go to sea with two chronometers; take one or three." +// Our three chronometers are: +// - System clock +// - Median of other server's clocks +// - NTP servers +// +// note: NTP isn't implemented yet, so until then we just use the median +// of other nodes clocks to correct ours. +// +int64 GetTime() +{ + return time(NULL); +} + +static int64 nTimeOffset = 0; + +int64 GetAdjustedTime() +{ + return GetTime() + nTimeOffset; +} + +void AddTimeData(unsigned int ip, int64 nTime) +{ + int64 nOffsetSample = nTime - GetTime(); + + // Ignore duplicates + static set<unsigned int> setKnown; + if (!setKnown.insert(ip).second) + return; + + // Add data + static vector<int64> vTimeOffsets; + if (vTimeOffsets.empty()) + vTimeOffsets.push_back(0); + vTimeOffsets.push_back(nOffsetSample); + printf("Added time data, samples %d, offset %+"PRI64d" (%+"PRI64d" minutes)\n", vTimeOffsets.size(), vTimeOffsets.back(), vTimeOffsets.back()/60); + if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1) + { + sort(vTimeOffsets.begin(), vTimeOffsets.end()); + int64 nMedian = vTimeOffsets[vTimeOffsets.size()/2]; + nTimeOffset = nMedian; + if ((nMedian > 0 ? nMedian : -nMedian) > 5 * 60) + { + // Only let other nodes change our clock so far before we + // go to the NTP servers + /// todo: Get time from NTP servers, then set a flag + /// to make sure it doesn't get changed again + } + foreach(int64 n, vTimeOffsets) + printf("%+"PRI64d" ", n); + printf("| nTimeOffset = %+"PRI64d" (%+"PRI64d" minutes)\n", nTimeOffset, nTimeOffset/60); + } +} @@ -1,546 +1,546 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
-
-
-#if defined(_MSC_VER) || defined(__BORLANDC__)
-typedef __int64 int64;
-typedef unsigned __int64 uint64;
-#else
-typedef long long int64;
-typedef unsigned long long uint64;
-#endif
-#if defined(_MSC_VER) && _MSC_VER < 1300
-#define for if (false) ; else for
-#endif
-#ifndef _MSC_VER
-#define __forceinline inline
-#endif
-
-#define foreach BOOST_FOREACH
-#define loop for (;;)
-#define BEGIN(a) ((char*)&(a))
-#define END(a) ((char*)&((&(a))[1]))
-#define UBEGIN(a) ((unsigned char*)&(a))
-#define UEND(a) ((unsigned char*)&((&(a))[1]))
-#define ARRAYLEN(array) (sizeof(array)/sizeof((array)[0]))
-#define printf OutputDebugStringF
-
-#ifdef snprintf
-#undef snprintf
-#endif
-#define snprintf my_snprintf
-
-#ifndef PRI64d
-#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MSVCRT__)
-#define PRI64d "I64d"
-#define PRI64u "I64u"
-#define PRI64x "I64x"
-#else
-#define PRI64d "lld"
-#define PRI64u "llu"
-#define PRI64x "llx"
-#endif
-#endif
-
-// This is needed because the foreach macro can't get over the comma in pair<t1, t2>
-#define PAIRTYPE(t1, t2) pair<t1, t2>
-
-// Used to bypass the rule against non-const reference to temporary
-// where it makes sense with wrappers such as CFlatData or CTxDB
-template<typename T>
-inline T& REF(const T& val)
-{
- return (T&)val;
-}
-
-#ifdef __WXMSW__
-static const bool fWindows = true;
-#define MSG_NOSIGNAL 0
-#define MSG_DONTWAIT 0
-#ifndef UINT64_MAX
-#define UINT64_MAX _UI64_MAX
-#define INT64_MAX _I64_MAX
-#define INT64_MIN _I64_MIN
-#endif
-#ifndef S_IRUSR
-#define S_IRUSR 0400
-#define S_IWUSR 0200
-#endif
-#define unlink _unlink
-typedef int socklen_t;
-#else
-static const bool fWindows = false;
-#define WSAGetLastError() errno
-#define WSAEWOULDBLOCK EWOULDBLOCK
-#define WSAEMSGSIZE EMSGSIZE
-#define WSAEINTR EINTR
-#define WSAEINPROGRESS EINPROGRESS
-#define WSAEADDRINUSE EADDRINUSE
-#define WSAENOTSOCK EBADF
-#define INVALID_SOCKET (SOCKET)(~0)
-#define SOCKET_ERROR -1
-typedef u_int SOCKET;
-#define _vsnprintf(a,b,c,d) vsnprintf(a,b,c,d)
-#define strlwr(psz) to_lower(psz)
-#define _strlwr(psz) to_lower(psz)
-#define _mkdir(psz) filesystem::create_directory(psz)
-#define MAX_PATH 1024
-#define Sleep(n) wxMilliSleep(n)
-#define Beep(n1,n2) (0)
-#endif
-
-inline int myclosesocket(SOCKET& hSocket)
-{
- if (hSocket == INVALID_SOCKET)
- return WSAENOTSOCK;
-#ifdef __WXMSW__
- int ret = closesocket(hSocket);
-#else
- int ret = close(hSocket);
-#endif
- hSocket = INVALID_SOCKET;
- return ret;
-}
-#define closesocket(s) myclosesocket(s)
-
-
-
-
-
-
-
-
-
-
-extern map<string, string> mapArgs;
-extern map<string, vector<string> > mapMultiArgs;
-extern bool fDebug;
-extern bool fPrintToConsole;
-extern bool fPrintToDebugger;
-extern char pszSetDataDir[MAX_PATH];
-extern bool fShutdown;
-extern bool fDaemon;
-extern bool fCommandLine;
-
-void RandAddSeed();
-void RandAddSeedPerfmon();
-int OutputDebugStringF(const char* pszFormat, ...);
-int my_snprintf(char* buffer, size_t limit, const char* format, ...);
-string strprintf(const char* format, ...);
-bool error(const char* format, ...);
-void PrintException(std::exception* pex, const char* pszThread);
-void LogException(std::exception* pex, const char* pszThread);
-void ParseString(const string& str, char c, vector<string>& v);
-string FormatMoney(int64 n, bool fPlus=false);
-bool ParseMoney(const string& str, int64& nRet);
-bool ParseMoney(const char* pszIn, int64& nRet);
-vector<unsigned char> ParseHex(const char* psz);
-vector<unsigned char> ParseHex(const std::string& str);
-void ParseParameters(int argc, char* argv[]);
-const char* wxGetTranslation(const char* psz);
-int GetFilesize(FILE* file);
-void GetDataDir(char* pszDirRet);
-#ifdef __WXMSW__
-string MyGetSpecialFolderPath(int nFolder, bool fCreate);
-#endif
-string GetDefaultDataDir();
-string GetDataDir();
-void ShrinkDebugFile();
-uint64 GetRand(uint64 nMax);
-int64 GetTime();
-int64 GetAdjustedTime();
-void AddTimeData(unsigned int ip, int64 nTime);
-
-
-
-
-
-
-
-
-
-
-
-
-
-// Wrapper to automatically initialize critical sections
-class CCriticalSection
-{
-#ifdef __WXMSW__
-protected:
- CRITICAL_SECTION cs;
-public:
- explicit CCriticalSection() { InitializeCriticalSection(&cs); }
- ~CCriticalSection() { DeleteCriticalSection(&cs); }
- void Enter() { EnterCriticalSection(&cs); }
- void Leave() { LeaveCriticalSection(&cs); }
- bool TryEnter() { return TryEnterCriticalSection(&cs); }
-#else
-protected:
- boost::interprocess::interprocess_recursive_mutex mutex;
-public:
- explicit CCriticalSection() { }
- ~CCriticalSection() { }
- void Enter() { mutex.lock(); }
- void Leave() { mutex.unlock(); }
- bool TryEnter() { return mutex.try_lock(); }
-#endif
-public:
- const char* pszFile;
- int nLine;
-};
-
-// Automatically leave critical section when leaving block, needed for exception safety
-class CCriticalBlock
-{
-protected:
- CCriticalSection* pcs;
-public:
- CCriticalBlock(CCriticalSection& csIn) { pcs = &csIn; pcs->Enter(); }
- ~CCriticalBlock() { pcs->Leave(); }
-};
-
-// WARNING: This will catch continue and break!
-// break is caught with an assertion, but there's no way to detect continue.
-// I'd rather be careful than suffer the other more error prone syntax.
-// The compiler will optimise away all this loop junk.
-#define CRITICAL_BLOCK(cs) \
- for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by CRITICAL_BLOCK!", !fcriticalblockonce)), fcriticalblockonce=false) \
- for (CCriticalBlock criticalblock(cs); fcriticalblockonce && (cs.pszFile=__FILE__, cs.nLine=__LINE__, true); fcriticalblockonce=false, cs.pszFile=NULL, cs.nLine=0)
-
-class CTryCriticalBlock
-{
-protected:
- CCriticalSection* pcs;
-public:
- CTryCriticalBlock(CCriticalSection& csIn) { pcs = (csIn.TryEnter() ? &csIn : NULL); }
- ~CTryCriticalBlock() { if (pcs) pcs->Leave(); }
- bool Entered() { return pcs != NULL; }
-};
-
-#define TRY_CRITICAL_BLOCK(cs) \
- for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by TRY_CRITICAL_BLOCK!", !fcriticalblockonce)), fcriticalblockonce=false) \
- for (CTryCriticalBlock criticalblock(cs); fcriticalblockonce && (fcriticalblockonce = criticalblock.Entered()) && (cs.pszFile=__FILE__, cs.nLine=__LINE__, true); fcriticalblockonce=false, cs.pszFile=NULL, cs.nLine=0)
-
-
-
-
-
-
-
-
-
-
-inline string i64tostr(int64 n)
-{
- return strprintf("%"PRI64d, n);
-}
-
-inline string itostr(int n)
-{
- return strprintf("%d", n);
-}
-
-inline int64 atoi64(const char* psz)
-{
-#ifdef _MSC_VER
- return _atoi64(psz);
-#else
- return strtoll(psz, NULL, 10);
-#endif
-}
-
-inline int64 atoi64(const string& str)
-{
-#ifdef _MSC_VER
- return _atoi64(str.c_str());
-#else
- return strtoll(str.c_str(), NULL, 10);
-#endif
-}
-
-inline int atoi(const string& str)
-{
- return atoi(str.c_str());
-}
-
-inline int roundint(double d)
-{
- return (int)(d > 0 ? d + 0.5 : d - 0.5);
-}
-
-inline int64 roundint64(double d)
-{
- return (int64)(d > 0 ? d + 0.5 : d - 0.5);
-}
-
-template<typename T>
-string HexStr(const T itbegin, const T itend, bool fSpaces=true)
-{
- const unsigned char* pbegin = (const unsigned char*)&itbegin[0];
- const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]);
- string str;
- for (const unsigned char* p = pbegin; p != pend; p++)
- str += strprintf((fSpaces && p != pend-1 ? "%02x " : "%02x"), *p);
- return str;
-}
-
-inline string HexStr(vector<unsigned char> vch, bool fSpaces=true)
-{
- return HexStr(vch.begin(), vch.end(), fSpaces);
-}
-
-template<typename T>
-string HexNumStr(const T itbegin, const T itend, bool f0x=true)
-{
- const unsigned char* pbegin = (const unsigned char*)&itbegin[0];
- const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]);
- string str = (f0x ? "0x" : "");
- for (const unsigned char* p = pend-1; p >= pbegin; p--)
- str += strprintf("%02X", *p);
- return str;
-}
-
-template<typename T>
-void PrintHex(const T pbegin, const T pend, const char* pszFormat="%s", bool fSpaces=true)
-{
- printf(pszFormat, HexStr(pbegin, pend, fSpaces).c_str());
-}
-
-inline void PrintHex(vector<unsigned char> vch, const char* pszFormat="%s", bool fSpaces=true)
-{
- printf(pszFormat, HexStr(vch, fSpaces).c_str());
-}
-
-inline int64 PerformanceCounter()
-{
- int64 nCounter = 0;
-#ifdef __WXMSW__
- QueryPerformanceCounter((LARGE_INTEGER*)&nCounter);
-#else
- timeval t;
- gettimeofday(&t, NULL);
- nCounter = t.tv_sec * 1000000 + t.tv_usec;
-#endif
- return nCounter;
-}
-
-inline int64 GetTimeMillis()
-{
- return (posix_time::ptime(posix_time::microsec_clock::universal_time()) -
- posix_time::ptime(gregorian::date(1970,1,1))).total_milliseconds();
-}
-
-inline string DateTimeStrFormat(const char* pszFormat, int64 nTime)
-{
- time_t n = nTime;
- struct tm* ptmTime = gmtime(&n);
- char pszTime[200];
- strftime(pszTime, sizeof(pszTime), pszFormat, ptmTime);
- return pszTime;
-}
-
-template<typename T>
-void skipspaces(T& it)
-{
- while (isspace(*it))
- ++it;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-inline void heapchk()
-{
-#ifdef __WXMSW__
- /// for debugging
- //if (_heapchk() != _HEAPOK)
- // DebugBreak();
-#endif
-}
-
-// Randomize the stack to help protect against buffer overrun exploits
-#define IMPLEMENT_RANDOMIZE_STACK(ThreadFn) \
- { \
- static char nLoops; \
- if (nLoops <= 0) \
- nLoops = GetRand(20) + 1; \
- if (nLoops-- > 1) \
- { \
- ThreadFn; \
- return; \
- } \
- }
-
-#define CATCH_PRINT_EXCEPTION(pszFn) \
- catch (std::exception& e) { \
- PrintException(&e, (pszFn)); \
- } catch (...) { \
- PrintException(NULL, (pszFn)); \
- }
-
-
-
-
-
-
-
-
-
-
-template<typename T1>
-inline uint256 Hash(const T1 pbegin, const T1 pend)
-{
- uint256 hash1;
- SHA256((unsigned char*)&pbegin[0], (pend - pbegin) * sizeof(pbegin[0]), (unsigned char*)&hash1);
- uint256 hash2;
- SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
- return hash2;
-}
-
-template<typename T1, typename T2>
-inline uint256 Hash(const T1 p1begin, const T1 p1end,
- const T2 p2begin, const T2 p2end)
-{
- uint256 hash1;
- SHA256_CTX ctx;
- SHA256_Init(&ctx);
- SHA256_Update(&ctx, (unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0]));
- SHA256_Update(&ctx, (unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0]));
- SHA256_Final((unsigned char*)&hash1, &ctx);
- uint256 hash2;
- SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
- return hash2;
-}
-
-template<typename T1, typename T2, typename T3>
-inline uint256 Hash(const T1 p1begin, const T1 p1end,
- const T2 p2begin, const T2 p2end,
- const T3 p3begin, const T3 p3end)
-{
- uint256 hash1;
- SHA256_CTX ctx;
- SHA256_Init(&ctx);
- SHA256_Update(&ctx, (unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0]));
- SHA256_Update(&ctx, (unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0]));
- SHA256_Update(&ctx, (unsigned char*)&p3begin[0], (p3end - p3begin) * sizeof(p3begin[0]));
- SHA256_Final((unsigned char*)&hash1, &ctx);
- uint256 hash2;
- SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
- return hash2;
-}
-
-template<typename T>
-uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=VERSION)
-{
- // Most of the time is spent allocating and deallocating CDataStream's
- // buffer. If this ever needs to be optimized further, make a CStaticStream
- // class with its buffer on the stack.
- CDataStream ss(nType, nVersion);
- ss.reserve(10000);
- ss << obj;
- return Hash(ss.begin(), ss.end());
-}
-
-inline uint160 Hash160(const vector<unsigned char>& vch)
-{
- uint256 hash1;
- SHA256(&vch[0], vch.size(), (unsigned char*)&hash1);
- uint160 hash2;
- RIPEMD160((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
- return hash2;
-}
-
-
-
-
-
-
-
-
-
-
-
-// Note: It turns out we might have been able to use boost::thread
-// by using TerminateThread(boost::thread.native_handle(), 0);
-#ifdef __WXMSW__
-typedef HANDLE pthread_t;
-
-inline pthread_t CreateThread(void(*pfn)(void*), void* parg, bool fWantHandle=false)
-{
- DWORD nUnused = 0;
- HANDLE hthread =
- CreateThread(
- NULL, // default security
- 0, // inherit stack size from parent
- (LPTHREAD_START_ROUTINE)pfn, // function pointer
- parg, // argument
- 0, // creation option, start immediately
- &nUnused); // thread identifier
- if (hthread == NULL)
- {
- printf("Error: CreateThread() returned %d\n", GetLastError());
- return (pthread_t)0;
- }
- if (!fWantHandle)
- {
- CloseHandle(hthread);
- return (pthread_t)-1;
- }
- return hthread;
-}
-
-inline void SetThreadPriority(int nPriority)
-{
- SetThreadPriority(GetCurrentThread(), nPriority);
-}
-#else
-inline pthread_t CreateThread(void(*pfn)(void*), void* parg, bool fWantHandle=false)
-{
- pthread_t hthread = 0;
- int ret = pthread_create(&hthread, NULL, (void*(*)(void*))pfn, parg);
- if (ret != 0)
- {
- printf("Error: pthread_create() returned %d\n", ret);
- return (pthread_t)0;
- }
- if (!fWantHandle)
- return (pthread_t)-1;
- return hthread;
-}
-
-#define THREAD_PRIORITY_LOWEST PRIO_MAX
-#define THREAD_PRIORITY_BELOW_NORMAL 2
-#define THREAD_PRIORITY_NORMAL 0
-#define THREAD_PRIORITY_ABOVE_NORMAL 0
-
-inline void SetThreadPriority(int nPriority)
-{
- // It's unclear if it's even possible to change thread priorities on Linux,
- // but we really and truly need it for the generation threads.
-#ifdef PRIO_THREAD
- setpriority(PRIO_THREAD, 0, nPriority);
-#else
- setpriority(PRIO_PROCESS, 0, nPriority);
-#endif
-}
-
-inline bool TerminateThread(pthread_t hthread, unsigned int nExitCode)
-{
- return (pthread_cancel(hthread) == 0);
-}
-
-inline void ExitThread(unsigned int nExitCode)
-{
- pthread_exit((void*)nExitCode);
-}
-#endif
+// Copyright (c) 2009-2010 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + + +#if defined(_MSC_VER) || defined(__BORLANDC__) +typedef __int64 int64; +typedef unsigned __int64 uint64; +#else +typedef long long int64; +typedef unsigned long long uint64; +#endif +#if defined(_MSC_VER) && _MSC_VER < 1300 +#define for if (false) ; else for +#endif +#ifndef _MSC_VER +#define __forceinline inline +#endif + +#define foreach BOOST_FOREACH +#define loop for (;;) +#define BEGIN(a) ((char*)&(a)) +#define END(a) ((char*)&((&(a))[1])) +#define UBEGIN(a) ((unsigned char*)&(a)) +#define UEND(a) ((unsigned char*)&((&(a))[1])) +#define ARRAYLEN(array) (sizeof(array)/sizeof((array)[0])) +#define printf OutputDebugStringF + +#ifdef snprintf +#undef snprintf +#endif +#define snprintf my_snprintf + +#ifndef PRI64d +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MSVCRT__) +#define PRI64d "I64d" +#define PRI64u "I64u" +#define PRI64x "I64x" +#else +#define PRI64d "lld" +#define PRI64u "llu" +#define PRI64x "llx" +#endif +#endif + +// This is needed because the foreach macro can't get over the comma in pair<t1, t2> +#define PAIRTYPE(t1, t2) pair<t1, t2> + +// Used to bypass the rule against non-const reference to temporary +// where it makes sense with wrappers such as CFlatData or CTxDB +template<typename T> +inline T& REF(const T& val) +{ + return (T&)val; +} + +#ifdef __WXMSW__ +static const bool fWindows = true; +#define MSG_NOSIGNAL 0 +#define MSG_DONTWAIT 0 +#ifndef UINT64_MAX +#define UINT64_MAX _UI64_MAX +#define INT64_MAX _I64_MAX +#define INT64_MIN _I64_MIN +#endif +#ifndef S_IRUSR +#define S_IRUSR 0400 +#define S_IWUSR 0200 +#endif +#define unlink _unlink +typedef int socklen_t; +#else +static const bool fWindows = false; +#define WSAGetLastError() errno +#define WSAEWOULDBLOCK EWOULDBLOCK +#define WSAEMSGSIZE EMSGSIZE +#define WSAEINTR EINTR +#define WSAEINPROGRESS EINPROGRESS +#define WSAEADDRINUSE EADDRINUSE +#define WSAENOTSOCK EBADF +#define INVALID_SOCKET (SOCKET)(~0) +#define SOCKET_ERROR -1 +typedef u_int SOCKET; +#define _vsnprintf(a,b,c,d) vsnprintf(a,b,c,d) +#define strlwr(psz) to_lower(psz) +#define _strlwr(psz) to_lower(psz) +#define _mkdir(psz) filesystem::create_directory(psz) +#define MAX_PATH 1024 +#define Sleep(n) wxMilliSleep(n) +#define Beep(n1,n2) (0) +#endif + +inline int myclosesocket(SOCKET& hSocket) +{ + if (hSocket == INVALID_SOCKET) + return WSAENOTSOCK; +#ifdef __WXMSW__ + int ret = closesocket(hSocket); +#else + int ret = close(hSocket); +#endif + hSocket = INVALID_SOCKET; + return ret; +} +#define closesocket(s) myclosesocket(s) + + + + + + + + + + +extern map<string, string> mapArgs; +extern map<string, vector<string> > mapMultiArgs; +extern bool fDebug; +extern bool fPrintToConsole; +extern bool fPrintToDebugger; +extern char pszSetDataDir[MAX_PATH]; +extern bool fShutdown; +extern bool fDaemon; +extern bool fCommandLine; + +void RandAddSeed(); +void RandAddSeedPerfmon(); +int OutputDebugStringF(const char* pszFormat, ...); +int my_snprintf(char* buffer, size_t limit, const char* format, ...); +string strprintf(const char* format, ...); +bool error(const char* format, ...); +void PrintException(std::exception* pex, const char* pszThread); +void LogException(std::exception* pex, const char* pszThread); +void ParseString(const string& str, char c, vector<string>& v); +string FormatMoney(int64 n, bool fPlus=false); +bool ParseMoney(const string& str, int64& nRet); +bool ParseMoney(const char* pszIn, int64& nRet); +vector<unsigned char> ParseHex(const char* psz); +vector<unsigned char> ParseHex(const std::string& str); +void ParseParameters(int argc, char* argv[]); +const char* wxGetTranslation(const char* psz); +int GetFilesize(FILE* file); +void GetDataDir(char* pszDirRet); +#ifdef __WXMSW__ +string MyGetSpecialFolderPath(int nFolder, bool fCreate); +#endif +string GetDefaultDataDir(); +string GetDataDir(); +void ShrinkDebugFile(); +uint64 GetRand(uint64 nMax); +int64 GetTime(); +int64 GetAdjustedTime(); +void AddTimeData(unsigned int ip, int64 nTime); + + + + + + + + + + + + + +// Wrapper to automatically initialize critical sections +class CCriticalSection +{ +#ifdef __WXMSW__ +protected: + CRITICAL_SECTION cs; +public: + explicit CCriticalSection() { InitializeCriticalSection(&cs); } + ~CCriticalSection() { DeleteCriticalSection(&cs); } + void Enter() { EnterCriticalSection(&cs); } + void Leave() { LeaveCriticalSection(&cs); } + bool TryEnter() { return TryEnterCriticalSection(&cs); } +#else +protected: + boost::interprocess::interprocess_recursive_mutex mutex; +public: + explicit CCriticalSection() { } + ~CCriticalSection() { } + void Enter() { mutex.lock(); } + void Leave() { mutex.unlock(); } + bool TryEnter() { return mutex.try_lock(); } +#endif +public: + const char* pszFile; + int nLine; +}; + +// Automatically leave critical section when leaving block, needed for exception safety +class CCriticalBlock +{ +protected: + CCriticalSection* pcs; +public: + CCriticalBlock(CCriticalSection& csIn) { pcs = &csIn; pcs->Enter(); } + ~CCriticalBlock() { pcs->Leave(); } +}; + +// WARNING: This will catch continue and break! +// break is caught with an assertion, but there's no way to detect continue. +// I'd rather be careful than suffer the other more error prone syntax. +// The compiler will optimise away all this loop junk. +#define CRITICAL_BLOCK(cs) \ + for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by CRITICAL_BLOCK!", !fcriticalblockonce)), fcriticalblockonce=false) \ + for (CCriticalBlock criticalblock(cs); fcriticalblockonce && (cs.pszFile=__FILE__, cs.nLine=__LINE__, true); fcriticalblockonce=false, cs.pszFile=NULL, cs.nLine=0) + +class CTryCriticalBlock +{ +protected: + CCriticalSection* pcs; +public: + CTryCriticalBlock(CCriticalSection& csIn) { pcs = (csIn.TryEnter() ? &csIn : NULL); } + ~CTryCriticalBlock() { if (pcs) pcs->Leave(); } + bool Entered() { return pcs != NULL; } +}; + +#define TRY_CRITICAL_BLOCK(cs) \ + for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by TRY_CRITICAL_BLOCK!", !fcriticalblockonce)), fcriticalblockonce=false) \ + for (CTryCriticalBlock criticalblock(cs); fcriticalblockonce && (fcriticalblockonce = criticalblock.Entered()) && (cs.pszFile=__FILE__, cs.nLine=__LINE__, true); fcriticalblockonce=false, cs.pszFile=NULL, cs.nLine=0) + + + + + + + + + + +inline string i64tostr(int64 n) +{ + return strprintf("%"PRI64d, n); +} + +inline string itostr(int n) +{ + return strprintf("%d", n); +} + +inline int64 atoi64(const char* psz) +{ +#ifdef _MSC_VER + return _atoi64(psz); +#else + return strtoll(psz, NULL, 10); +#endif +} + +inline int64 atoi64(const string& str) +{ +#ifdef _MSC_VER + return _atoi64(str.c_str()); +#else + return strtoll(str.c_str(), NULL, 10); +#endif +} + +inline int atoi(const string& str) +{ + return atoi(str.c_str()); +} + +inline int roundint(double d) +{ + return (int)(d > 0 ? d + 0.5 : d - 0.5); +} + +inline int64 roundint64(double d) +{ + return (int64)(d > 0 ? d + 0.5 : d - 0.5); +} + +template<typename T> +string HexStr(const T itbegin, const T itend, bool fSpaces=true) +{ + const unsigned char* pbegin = (const unsigned char*)&itbegin[0]; + const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]); + string str; + for (const unsigned char* p = pbegin; p != pend; p++) + str += strprintf((fSpaces && p != pend-1 ? "%02x " : "%02x"), *p); + return str; +} + +inline string HexStr(vector<unsigned char> vch, bool fSpaces=true) +{ + return HexStr(vch.begin(), vch.end(), fSpaces); +} + +template<typename T> +string HexNumStr(const T itbegin, const T itend, bool f0x=true) +{ + const unsigned char* pbegin = (const unsigned char*)&itbegin[0]; + const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]); + string str = (f0x ? "0x" : ""); + for (const unsigned char* p = pend-1; p >= pbegin; p--) + str += strprintf("%02X", *p); + return str; +} + +template<typename T> +void PrintHex(const T pbegin, const T pend, const char* pszFormat="%s", bool fSpaces=true) +{ + printf(pszFormat, HexStr(pbegin, pend, fSpaces).c_str()); +} + +inline void PrintHex(vector<unsigned char> vch, const char* pszFormat="%s", bool fSpaces=true) +{ + printf(pszFormat, HexStr(vch, fSpaces).c_str()); +} + +inline int64 PerformanceCounter() +{ + int64 nCounter = 0; +#ifdef __WXMSW__ + QueryPerformanceCounter((LARGE_INTEGER*)&nCounter); +#else + timeval t; + gettimeofday(&t, NULL); + nCounter = t.tv_sec * 1000000 + t.tv_usec; +#endif + return nCounter; +} + +inline int64 GetTimeMillis() +{ + return (posix_time::ptime(posix_time::microsec_clock::universal_time()) - + posix_time::ptime(gregorian::date(1970,1,1))).total_milliseconds(); +} + +inline string DateTimeStrFormat(const char* pszFormat, int64 nTime) +{ + time_t n = nTime; + struct tm* ptmTime = gmtime(&n); + char pszTime[200]; + strftime(pszTime, sizeof(pszTime), pszFormat, ptmTime); + return pszTime; +} + +template<typename T> +void skipspaces(T& it) +{ + while (isspace(*it)) + ++it; +} + + + + + + + + + + + + +inline void heapchk() +{ +#ifdef __WXMSW__ + /// for debugging + //if (_heapchk() != _HEAPOK) + // DebugBreak(); +#endif +} + +// Randomize the stack to help protect against buffer overrun exploits +#define IMPLEMENT_RANDOMIZE_STACK(ThreadFn) \ + { \ + static char nLoops; \ + if (nLoops <= 0) \ + nLoops = GetRand(20) + 1; \ + if (nLoops-- > 1) \ + { \ + ThreadFn; \ + return; \ + } \ + } + +#define CATCH_PRINT_EXCEPTION(pszFn) \ + catch (std::exception& e) { \ + PrintException(&e, (pszFn)); \ + } catch (...) { \ + PrintException(NULL, (pszFn)); \ + } + + + + + + + + + + +template<typename T1> +inline uint256 Hash(const T1 pbegin, const T1 pend) +{ + uint256 hash1; + SHA256((unsigned char*)&pbegin[0], (pend - pbegin) * sizeof(pbegin[0]), (unsigned char*)&hash1); + uint256 hash2; + SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); + return hash2; +} + +template<typename T1, typename T2> +inline uint256 Hash(const T1 p1begin, const T1 p1end, + const T2 p2begin, const T2 p2end) +{ + uint256 hash1; + SHA256_CTX ctx; + SHA256_Init(&ctx); + SHA256_Update(&ctx, (unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0])); + SHA256_Update(&ctx, (unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0])); + SHA256_Final((unsigned char*)&hash1, &ctx); + uint256 hash2; + SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); + return hash2; +} + +template<typename T1, typename T2, typename T3> +inline uint256 Hash(const T1 p1begin, const T1 p1end, + const T2 p2begin, const T2 p2end, + const T3 p3begin, const T3 p3end) +{ + uint256 hash1; + SHA256_CTX ctx; + SHA256_Init(&ctx); + SHA256_Update(&ctx, (unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0])); + SHA256_Update(&ctx, (unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0])); + SHA256_Update(&ctx, (unsigned char*)&p3begin[0], (p3end - p3begin) * sizeof(p3begin[0])); + SHA256_Final((unsigned char*)&hash1, &ctx); + uint256 hash2; + SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); + return hash2; +} + +template<typename T> +uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=VERSION) +{ + // Most of the time is spent allocating and deallocating CDataStream's + // buffer. If this ever needs to be optimized further, make a CStaticStream + // class with its buffer on the stack. + CDataStream ss(nType, nVersion); + ss.reserve(10000); + ss << obj; + return Hash(ss.begin(), ss.end()); +} + +inline uint160 Hash160(const vector<unsigned char>& vch) +{ + uint256 hash1; + SHA256(&vch[0], vch.size(), (unsigned char*)&hash1); + uint160 hash2; + RIPEMD160((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); + return hash2; +} + + + + + + + + + + + +// Note: It turns out we might have been able to use boost::thread +// by using TerminateThread(boost::thread.native_handle(), 0); +#ifdef __WXMSW__ +typedef HANDLE pthread_t; + +inline pthread_t CreateThread(void(*pfn)(void*), void* parg, bool fWantHandle=false) +{ + DWORD nUnused = 0; + HANDLE hthread = + CreateThread( + NULL, // default security + 0, // inherit stack size from parent + (LPTHREAD_START_ROUTINE)pfn, // function pointer + parg, // argument + 0, // creation option, start immediately + &nUnused); // thread identifier + if (hthread == NULL) + { + printf("Error: CreateThread() returned %d\n", GetLastError()); + return (pthread_t)0; + } + if (!fWantHandle) + { + CloseHandle(hthread); + return (pthread_t)-1; + } + return hthread; +} + +inline void SetThreadPriority(int nPriority) +{ + SetThreadPriority(GetCurrentThread(), nPriority); +} +#else +inline pthread_t CreateThread(void(*pfn)(void*), void* parg, bool fWantHandle=false) +{ + pthread_t hthread = 0; + int ret = pthread_create(&hthread, NULL, (void*(*)(void*))pfn, parg); + if (ret != 0) + { + printf("Error: pthread_create() returned %d\n", ret); + return (pthread_t)0; + } + if (!fWantHandle) + return (pthread_t)-1; + return hthread; +} + +#define THREAD_PRIORITY_LOWEST PRIO_MAX +#define THREAD_PRIORITY_BELOW_NORMAL 2 +#define THREAD_PRIORITY_NORMAL 0 +#define THREAD_PRIORITY_ABOVE_NORMAL 0 + +inline void SetThreadPriority(int nPriority) +{ + // It's unclear if it's even possible to change thread priorities on Linux, + // but we really and truly need it for the generation threads. +#ifdef PRIO_THREAD + setpriority(PRIO_THREAD, 0, nPriority); +#else + setpriority(PRIO_PROCESS, 0, nPriority); +#endif +} + +inline bool TerminateThread(pthread_t hthread, unsigned int nExitCode) +{ + return (pthread_cancel(hthread) == 0); +} + +inline void ExitThread(unsigned int nExitCode) +{ + pthread_exit((void*)nExitCode); +} +#endif diff --git a/xpm/addressbook16.xpm b/xpm/addressbook16.xpm index e00944ef7a..22b15aaff0 100644 --- a/xpm/addressbook16.xpm +++ b/xpm/addressbook16.xpm @@ -1,278 +1,278 @@ -/* XPM */
-static const char * addressbook16_xpm[] = {
-/* columns rows colors chars-per-pixel */
-"16 16 256 2",
-" c #FFFFFF",
-". c #F7FFFF",
-"X c #F7F7FF",
-"o c #EFF7FF",
-"O c #E6EFF7",
-"+ c #E6E6F7",
-"@ c #CEE6F7",
-"# c #DEDEEF",
-"$ c #D6DEEF",
-"% c #D6DEE6",
-"& c #CEDEF7",
-"* c #CEDEEF",
-"= c #EFF708",
-"- c #C5DEF7",
-"; c #CED6EF",
-": c None",
-"> c #C5D6E6",
-", c #BDD6F7",
-"< c #BDD6EF",
-"1 c #D6CECE",
-"2 c #BDCEE6",
-"3 c #BDC5E6",
-"4 c #B5C5DE",
-"5 c #BDD631",
-"6 c #ADBDDE",
-"7 c #B5B5BD",
-"8 c #A5B5D6",
-"9 c #00FFFF",
-"0 c #9CB5CE",
-"q c #9CADD6",
-"w c #94A5D6",
-"e c #8CA5D6",
-"r c #8CA5CE",
-"t c #8CA5C5",
-"y c #849CC5",
-"u c #7B9CD6",
-"i c #7B9CCE",
-"p c #31BDCE",
-"a c #6B9CD6",
-"s c #00F708",
-"d c #8494AD",
-"f c #7B94B5",
-"g c #6B94D6",
-"h c #6B9C84",
-"j c #7B8CAD",
-"k c #738CAD",
-"l c #638CC5",
-"z c #10CE42",
-"x c #638CBD",
-"c c #7B849C",
-"v c #73849C",
-"b c #6B84A5",
-"n c #7B7BA5",
-"m c #6B849C",
-"M c #7B8C42",
-"N c #5A84C5",
-"B c #29AD6B",
-"V c #F74A4A",
-"C c #6384A5",
-"Z c #5284C5",
-"A c #637BA5",
-"S c #637B9C",
-"D c #9C637B",
-"F c #6B7B5A",
-"G c #637394",
-"H c #52739C",
-"J c #5A7384",
-"K c #526B94",
-"L c #426B94",
-"P c #52638C",
-"I c #426B7B",
-"U c #5A5A8C",
-"Y c #524A7B",
-"T c #425273",
-"R c #21636B",
-"E c #106394",
-"W c #106B52",
-"Q c #3A4273",
-"! c #31426B",
-"~ c #523163",
-"^ c #29426B",
-"/ c #293A63",
-"( c #213A63",
-") c #193A63",
-"_ c #193163",
-"` c #19315A",
-"' c #212963",
-"] c #10315A",
-"[ c #082952",
-"{ c #FFCC33",
-"} c #33FF33",
-"| c #66FF33",
-" . c #99FF33",
-".. c #CCFF33",
-"X. c #FFFF33",
-"o. c #000066",
-"O. c #330066",
-"+. c #660066",
-"@. c #990066",
-"#. c #CC0066",
-"$. c #FF0066",
-"%. c #003366",
-"&. c #333366",
-"*. c #663366",
-"=. c #993366",
-"-. c #CC3366",
-";. c #FF3366",
-":. c #006666",
-">. c #336666",
-",. c #666666",
-"<. c #996666",
-"1. c #CC6666",
-"2. c #009966",
-"3. c #339966",
-"4. c #669966",
-"5. c #999966",
-"6. c #CC9966",
-"7. c #FF9966",
-"8. c #00CC66",
-"9. c #33CC66",
-"0. c #99CC66",
-"q. c #CCCC66",
-"w. c #FFCC66",
-"e. c #00FF66",
-"r. c #33FF66",
-"t. c #99FF66",
-"y. c #CCFF66",
-"u. c #FF00CC",
-"i. c #CC00FF",
-"p. c #009999",
-"a. c #993399",
-"s. c #990099",
-"d. c #CC0099",
-"f. c #000099",
-"g. c #333399",
-"h. c #660099",
-"j. c #CC3399",
-"k. c #FF0099",
-"l. c #006699",
-"z. c #336699",
-"x. c #663399",
-"c. c #996699",
-"v. c #CC6699",
-"b. c #FF3399",
-"n. c #339999",
-"m. c #669999",
-"M. c #999999",
-"N. c #CC9999",
-"B. c #FF9999",
-"V. c #00CC99",
-"C. c #33CC99",
-"Z. c #66CC66",
-"A. c #99CC99",
-"S. c #CCCC99",
-"D. c #FFCC99",
-"F. c #00FF99",
-"G. c #33FF99",
-"H. c #66CC99",
-"J. c #99FF99",
-"K. c #CCFF99",
-"L. c #FFFF99",
-"P. c #0000CC",
-"I. c #330099",
-"U. c #6600CC",
-"Y. c #9900CC",
-"T. c #CC00CC",
-"R. c #003399",
-"E. c #3333CC",
-"W. c #6633CC",
-"Q. c #9933CC",
-"!. c #CC33CC",
-"~. c #FF33CC",
-"^. c #0066CC",
-"/. c #3366CC",
-"(. c #666699",
-"). c #9966CC",
-"_. c #CC66CC",
-"`. c #FF6699",
-"'. c #0099CC",
-"]. c #3399CC",
-"[. c #6699CC",
-"{. c #9999CC",
-"}. c #CC99CC",
-"|. c #FF99CC",
-" X c #00CCCC",
-".X c #33CCCC",
-"XX c #66CCCC",
-"oX c #99CCCC",
-"OX c #CCCCCC",
-"+X c #FFCCCC",
-"@X c #00FFCC",
-"#X c #33FFCC",
-"$X c #66FF99",
-"%X c #99FFCC",
-"&X c #CCFFCC",
-"*X c #FFFFCC",
-"=X c #3300CC",
-"-X c #6600FF",
-";X c #9900FF",
-":X c #0033CC",
-">X c #3333FF",
-",X c #6633FF",
-"<X c #9933FF",
-"1X c #CC33FF",
-"2X c #FF33FF",
-"3X c #0066FF",
-"4X c #3366FF",
-"5X c #6666CC",
-"6X c #9966FF",
-"7X c #CC66FF",
-"8X c #FF66CC",
-"9X c #0099FF",
-"0X c #3399FF",
-"qX c #6699FF",
-"wX c #9999FF",
-"eX c #CC99FF",
-"rX c #FF99FF",
-"tX c #00CCFF",
-"yX c #33CCFF",
-"uX c #66CCFF",
-"iX c #99CCFF",
-"pX c #CCCCFF",
-"aX c #FFCCFF",
-"sX c #33FFFF",
-"dX c #66FFCC",
-"fX c #99FFFF",
-"gX c #CCFFFF",
-"hX c #FF6666",
-"jX c #66FF66",
-"kX c #FFFF66",
-"lX c #6666FF",
-"zX c #FF66FF",
-"xX c #66FFFF",
-"cX c #A50021",
-"vX c #5F5F5F",
-"bX c #777777",
-"nX c #868686",
-"mX c #969696",
-"MX c #CBCBCB",
-"NX c #B2B2B2",
-"BX c #D7D7D7",
-"VX c #DDDDDD",
-"CX c #E3E3E3",
-"ZX c #EAEAEA",
-"AX c #F1F1F1",
-"SX c #F8F8F8",
-"DX c #FFFBF0",
-"FX c #A0A0A4",
-"GX c #808080",
-"HX c #FF0000",
-"JX c #00FF00",
-"KX c #FFFF00",
-"LX c #0000FF",
-"PX c #FF00FF",
-"IX c #00FFFF",
-"UX c #FFFFFF",
-/* pixels */
-": : : : : : : : : : : : : : : : ",
-": : H H H A d : 7 G K H H : : : ",
-"n n c X 4 k j X b n n : ",
-"n 2 c $ 8 6 4 x < + 4 4 C V ~ : ",
-"n * c X o $ y N u 6 $ + b D Y : ",
-"n * c X > g , S z R : ",
-"n * c * r r y g , 6 r q S s W : ",
-"n * c X 4 N u + m B I : ",
-"n * c X ; a - S 5 F : ",
-"n * c * r r r g - S = M : ",
-"n * c X 4 N - m h J : ",
-"n * c X ; a - A 9 E : ",
-"n * ( ] ` ^ P l y T / / ( p L : ",
-"n O > 0 f ) ! t 8 % n : ",
-"U U U U U U U ' Q U U U U U U : ",
-": : : : : : : : : : : : : : : : "
-};
+/* XPM */ +static const char * addressbook16_xpm[] = { +/* columns rows colors chars-per-pixel */ +"16 16 256 2", +" c #FFFFFF", +". c #F7FFFF", +"X c #F7F7FF", +"o c #EFF7FF", +"O c #E6EFF7", +"+ c #E6E6F7", +"@ c #CEE6F7", +"# c #DEDEEF", +"$ c #D6DEEF", +"% c #D6DEE6", +"& c #CEDEF7", +"* c #CEDEEF", +"= c #EFF708", +"- c #C5DEF7", +"; c #CED6EF", +": c None", +"> c #C5D6E6", +", c #BDD6F7", +"< c #BDD6EF", +"1 c #D6CECE", +"2 c #BDCEE6", +"3 c #BDC5E6", +"4 c #B5C5DE", +"5 c #BDD631", +"6 c #ADBDDE", +"7 c #B5B5BD", +"8 c #A5B5D6", +"9 c #00FFFF", +"0 c #9CB5CE", +"q c #9CADD6", +"w c #94A5D6", +"e c #8CA5D6", +"r c #8CA5CE", +"t c #8CA5C5", +"y c #849CC5", +"u c #7B9CD6", +"i c #7B9CCE", +"p c #31BDCE", +"a c #6B9CD6", +"s c #00F708", +"d c #8494AD", +"f c #7B94B5", +"g c #6B94D6", +"h c #6B9C84", +"j c #7B8CAD", +"k c #738CAD", +"l c #638CC5", +"z c #10CE42", +"x c #638CBD", +"c c #7B849C", +"v c #73849C", +"b c #6B84A5", +"n c #7B7BA5", +"m c #6B849C", +"M c #7B8C42", +"N c #5A84C5", +"B c #29AD6B", +"V c #F74A4A", +"C c #6384A5", +"Z c #5284C5", +"A c #637BA5", +"S c #637B9C", +"D c #9C637B", +"F c #6B7B5A", +"G c #637394", +"H c #52739C", +"J c #5A7384", +"K c #526B94", +"L c #426B94", +"P c #52638C", +"I c #426B7B", +"U c #5A5A8C", +"Y c #524A7B", +"T c #425273", +"R c #21636B", +"E c #106394", +"W c #106B52", +"Q c #3A4273", +"! c #31426B", +"~ c #523163", +"^ c #29426B", +"/ c #293A63", +"( c #213A63", +") c #193A63", +"_ c #193163", +"` c #19315A", +"' c #212963", +"] c #10315A", +"[ c #082952", +"{ c #FFCC33", +"} c #33FF33", +"| c #66FF33", +" . c #99FF33", +".. c #CCFF33", +"X. c #FFFF33", +"o. c #000066", +"O. c #330066", +"+. c #660066", +"@. c #990066", +"#. c #CC0066", +"$. c #FF0066", +"%. c #003366", +"&. c #333366", +"*. c #663366", +"=. c #993366", +"-. c #CC3366", +";. c #FF3366", +":. c #006666", +">. c #336666", +",. c #666666", +"<. c #996666", +"1. c #CC6666", +"2. c #009966", +"3. c #339966", +"4. c #669966", +"5. c #999966", +"6. c #CC9966", +"7. c #FF9966", +"8. c #00CC66", +"9. c #33CC66", +"0. c #99CC66", +"q. c #CCCC66", +"w. c #FFCC66", +"e. c #00FF66", +"r. c #33FF66", +"t. c #99FF66", +"y. c #CCFF66", +"u. c #FF00CC", +"i. c #CC00FF", +"p. c #009999", +"a. c #993399", +"s. c #990099", +"d. c #CC0099", +"f. c #000099", +"g. c #333399", +"h. c #660099", +"j. c #CC3399", +"k. c #FF0099", +"l. c #006699", +"z. c #336699", +"x. c #663399", +"c. c #996699", +"v. c #CC6699", +"b. c #FF3399", +"n. c #339999", +"m. c #669999", +"M. c #999999", +"N. c #CC9999", +"B. c #FF9999", +"V. c #00CC99", +"C. c #33CC99", +"Z. c #66CC66", +"A. c #99CC99", +"S. c #CCCC99", +"D. c #FFCC99", +"F. c #00FF99", +"G. c #33FF99", +"H. c #66CC99", +"J. c #99FF99", +"K. c #CCFF99", +"L. c #FFFF99", +"P. c #0000CC", +"I. c #330099", +"U. c #6600CC", +"Y. c #9900CC", +"T. c #CC00CC", +"R. c #003399", +"E. c #3333CC", +"W. c #6633CC", +"Q. c #9933CC", +"!. c #CC33CC", +"~. c #FF33CC", +"^. c #0066CC", +"/. c #3366CC", +"(. c #666699", +"). c #9966CC", +"_. c #CC66CC", +"`. c #FF6699", +"'. c #0099CC", +"]. c #3399CC", +"[. c #6699CC", +"{. c #9999CC", +"}. c #CC99CC", +"|. c #FF99CC", +" X c #00CCCC", +".X c #33CCCC", +"XX c #66CCCC", +"oX c #99CCCC", +"OX c #CCCCCC", +"+X c #FFCCCC", +"@X c #00FFCC", +"#X c #33FFCC", +"$X c #66FF99", +"%X c #99FFCC", +"&X c #CCFFCC", +"*X c #FFFFCC", +"=X c #3300CC", +"-X c #6600FF", +";X c #9900FF", +":X c #0033CC", +">X c #3333FF", +",X c #6633FF", +"<X c #9933FF", +"1X c #CC33FF", +"2X c #FF33FF", +"3X c #0066FF", +"4X c #3366FF", +"5X c #6666CC", +"6X c #9966FF", +"7X c #CC66FF", +"8X c #FF66CC", +"9X c #0099FF", +"0X c #3399FF", +"qX c #6699FF", +"wX c #9999FF", +"eX c #CC99FF", +"rX c #FF99FF", +"tX c #00CCFF", +"yX c #33CCFF", +"uX c #66CCFF", +"iX c #99CCFF", +"pX c #CCCCFF", +"aX c #FFCCFF", +"sX c #33FFFF", +"dX c #66FFCC", +"fX c #99FFFF", +"gX c #CCFFFF", +"hX c #FF6666", +"jX c #66FF66", +"kX c #FFFF66", +"lX c #6666FF", +"zX c #FF66FF", +"xX c #66FFFF", +"cX c #A50021", +"vX c #5F5F5F", +"bX c #777777", +"nX c #868686", +"mX c #969696", +"MX c #CBCBCB", +"NX c #B2B2B2", +"BX c #D7D7D7", +"VX c #DDDDDD", +"CX c #E3E3E3", +"ZX c #EAEAEA", +"AX c #F1F1F1", +"SX c #F8F8F8", +"DX c #FFFBF0", +"FX c #A0A0A4", +"GX c #808080", +"HX c #FF0000", +"JX c #00FF00", +"KX c #FFFF00", +"LX c #0000FF", +"PX c #FF00FF", +"IX c #00FFFF", +"UX c #FFFFFF", +/* pixels */ +": : : : : : : : : : : : : : : : ", +": : H H H A d : 7 G K H H : : : ", +"n n c X 4 k j X b n n : ", +"n 2 c $ 8 6 4 x < + 4 4 C V ~ : ", +"n * c X o $ y N u 6 $ + b D Y : ", +"n * c X > g , S z R : ", +"n * c * r r y g , 6 r q S s W : ", +"n * c X 4 N u + m B I : ", +"n * c X ; a - S 5 F : ", +"n * c * r r r g - S = M : ", +"n * c X 4 N - m h J : ", +"n * c X ; a - A 9 E : ", +"n * ( ] ` ^ P l y T / / ( p L : ", +"n O > 0 f ) ! t 8 % n : ", +"U U U U U U U ' Q U U U U U U : ", +": : : : : : : : : : : : : : : : " +}; diff --git a/xpm/addressbook20.xpm b/xpm/addressbook20.xpm index 7ebd73fb2f..495ee5cac6 100644 --- a/xpm/addressbook20.xpm +++ b/xpm/addressbook20.xpm @@ -1,282 +1,282 @@ -/* XPM */
-static const char * addressbook20_xpm[] = {
-/* columns rows colors chars-per-pixel */
-"20 20 256 2",
-" c #FFFFFF",
-". c #F7FFFF",
-"X c #F7F7FF",
-"o c #EFF7FF",
-"O c #EFF7F7",
-"+ c #E6EFFF",
-"@ c #E6EFF7",
-"# c #DEEFFF",
-"$ c #DEE6F7",
-"% c #DEE6EF",
-"& c #D6E6F7",
-"* c #FFFF00",
-"= c #DEDEE6",
-"- c #D6DEE6",
-"; c #D6D6DE",
-": c #CED6E6",
-"> c None",
-", c #C5D6E6",
-"< c #C5CEE6",
-"1 c #B5CEEF",
-"2 c #C5C5C5",
-"3 c #C5DE31",
-"4 c #B5C5DE",
-"5 c #BDC5C5",
-"6 c #ADC5EF",
-"7 c #B5C5CE",
-"8 c #BDBDBD",
-"9 c #B5BDCE",
-"0 c #ADBDDE",
-"q c #ADBDD6",
-"w c #B5CE52",
-"e c #ADB5C5",
-"r c #00FFFF",
-"t c #A5B5C5",
-"y c #9CB5CE",
-"u c #94B5DE",
-"i c #9CADD6",
-"p c #A5ADB5",
-"a c #94ADDE",
-"s c #94ADD6",
-"d c #9CADBD",
-"f c #8CADDE",
-"g c #BD9CA5",
-"h c #9CA5BD",
-"j c #9CA5B5",
-"k c #29D6E6",
-"l c #8CA5CE",
-"z c #849CCE",
-"x c #6BA5C5",
-"c c #739CDE",
-"v c #00FF00",
-"b c #739CD6",
-"n c #7B94CE",
-"m c #8494AD",
-"M c #7394CE",
-"N c #7B94B5",
-"B c #4AB584",
-"V c #848CB5",
-"C c #6B94CE",
-"Z c #6394D6",
-"A c #6394CE",
-"S c #7B8CAD",
-"D c #6B8CC5",
-"F c #738CAD",
-"G c #5294B5",
-"H c #6B84C5",
-"J c #7384A5",
-"K c #73849C",
-"L c #738494",
-"P c #FF4A4A",
-"I c #FF4A42",
-"U c #737B8C",
-"Y c #637BAD",
-"T c #527BBD",
-"R c #637394",
-"E c #637352",
-"W c #5A6B8C",
-"Q c #526B9C",
-"! c #63638C",
-"~ c #5A734A",
-"^ c #4A6B9C",
-"/ c #526B63",
-"( c #0884A5",
-") c #526384",
-"_ c #52637B",
-"` c #4A6B5A",
-"' c #52636B",
-"] c #525A8C",
-"[ c #525A7B",
-"{ c #426363",
-"} c #4A5A7B",
-"| c #425A8C",
-" . c #196B94",
-".. c #3A5A8C",
-"X. c #3A5A84",
-"o. c #087B4A",
-"O. c #21636B",
-"+. c #634263",
-"@. c #3A527B",
-"#. c #424A84",
-"$. c #315284",
-"%. c #295284",
-"&. c #3A4A6B",
-"*. c #42427B",
-"=. c #424273",
-"-. c #294A84",
-";. c #3A3A73",
-":. c #194284",
-">. c #104A63",
-",. c #213A6B",
-"<. c #31316B",
-"1. c #21315A",
-"2. c #212163",
-"3. c #08295A",
-"4. c #082152",
-"5. c #101952",
-"6. c #CC9966",
-"7. c #FF9966",
-"8. c #00CC66",
-"9. c #33CC66",
-"0. c #99CC66",
-"q. c #CCCC66",
-"w. c #FFCC66",
-"e. c #00FF66",
-"r. c #33FF66",
-"t. c #99FF66",
-"y. c #CCFF66",
-"u. c #FF00CC",
-"i. c #CC00FF",
-"p. c #009999",
-"a. c #993399",
-"s. c #990099",
-"d. c #CC0099",
-"f. c #000099",
-"g. c #333399",
-"h. c #660099",
-"j. c #CC3399",
-"k. c #FF0099",
-"l. c #006699",
-"z. c #336699",
-"x. c #663399",
-"c. c #996699",
-"v. c #CC6699",
-"b. c #FF3399",
-"n. c #339999",
-"m. c #669999",
-"M. c #999999",
-"N. c #CC9999",
-"B. c #FF9999",
-"V. c #00CC99",
-"C. c #33CC99",
-"Z. c #66CC66",
-"A. c #99CC99",
-"S. c #CCCC99",
-"D. c #FFCC99",
-"F. c #00FF99",
-"G. c #33FF99",
-"H. c #66CC99",
-"J. c #99FF99",
-"K. c #CCFF99",
-"L. c #FFFF99",
-"P. c #0000CC",
-"I. c #330099",
-"U. c #6600CC",
-"Y. c #9900CC",
-"T. c #CC00CC",
-"R. c #003399",
-"E. c #3333CC",
-"W. c #6633CC",
-"Q. c #9933CC",
-"!. c #CC33CC",
-"~. c #FF33CC",
-"^. c #0066CC",
-"/. c #3366CC",
-"(. c #666699",
-"). c #9966CC",
-"_. c #CC66CC",
-"`. c #FF6699",
-"'. c #0099CC",
-"]. c #3399CC",
-"[. c #6699CC",
-"{. c #9999CC",
-"}. c #CC99CC",
-"|. c #FF99CC",
-" X c #00CCCC",
-".X c #33CCCC",
-"XX c #66CCCC",
-"oX c #99CCCC",
-"OX c #CCCCCC",
-"+X c #FFCCCC",
-"@X c #00FFCC",
-"#X c #33FFCC",
-"$X c #66FF99",
-"%X c #99FFCC",
-"&X c #CCFFCC",
-"*X c #FFFFCC",
-"=X c #3300CC",
-"-X c #6600FF",
-";X c #9900FF",
-":X c #0033CC",
-">X c #3333FF",
-",X c #6633FF",
-"<X c #9933FF",
-"1X c #CC33FF",
-"2X c #FF33FF",
-"3X c #0066FF",
-"4X c #3366FF",
-"5X c #6666CC",
-"6X c #9966FF",
-"7X c #CC66FF",
-"8X c #FF66CC",
-"9X c #0099FF",
-"0X c #3399FF",
-"qX c #6699FF",
-"wX c #9999FF",
-"eX c #CC99FF",
-"rX c #FF99FF",
-"tX c #00CCFF",
-"yX c #33CCFF",
-"uX c #66CCFF",
-"iX c #99CCFF",
-"pX c #CCCCFF",
-"aX c #FFCCFF",
-"sX c #33FFFF",
-"dX c #66FFCC",
-"fX c #99FFFF",
-"gX c #CCFFFF",
-"hX c #FF6666",
-"jX c #66FF66",
-"kX c #FFFF66",
-"lX c #6666FF",
-"zX c #FF66FF",
-"xX c #66FFFF",
-"cX c #A50021",
-"vX c #5F5F5F",
-"bX c #777777",
-"nX c #868686",
-"mX c #969696",
-"MX c #CBCBCB",
-"NX c #B2B2B2",
-"BX c #D7D7D7",
-"VX c #DDDDDD",
-"CX c #E3E3E3",
-"ZX c #EAEAEA",
-"AX c #F1F1F1",
-"SX c #F8F8F8",
-"DX c #FFFBF0",
-"FX c #A0A0A4",
-"GX c #808080",
-"HX c #FF0000",
-"JX c #00FF00",
-"KX c #FFFF00",
-"LX c #0000FF",
-"PX c #FF00FF",
-"IX c #00FFFF",
-"UX c #FFFFFF",
-/* pixels */
-"> > > > > > > > > > > > > > > > > > > > ",
-"> > > > > > > > > > > > > > > > > > > > ",
-"> > U $.| | ^ S 2 > p W | | @.L > > > > ",
-"8 5 R - < Y j S O - ) g e > > ",
-"! V K - % a Q # - +.P <.> > ",
-"! & K - 0 z n D C b f n n z q +.P <.> > ",
-"! & K - % M A 1 - %.G #.> > ",
-"! & K - % u b # - o.v >.> > ",
-"! & K - 0 z n H M b 6 z n z q o.v >.> > ",
-"! & K - X - M A a - O.B @.> > ",
-"! & K - X % u b # - ` 3 / > > ",
-"! & K - 0 l i 4 u b # - ~ * E > > ",
-"! & K - X o $ s T b # - { w ' > > ",
-"! & K - % f b # - .k -.> > ",
-"! & K m d t 7 , u b # ; 9 9 h ( r :.> > ",
-"! & h _ _ [ &.4.$.A ,.1.} _ _ F x ] > > ",
-"! @ , y N _ 3._ N y , @ ! > > ",
-"*.*.*.*.*.*.*.*.;.5.*.*.*.*.*.*.*.2.> > ",
-"> > > > > > > > > > > > > > > > > > > > ",
-"> > > > > > > > > > > > > > > > > > > > "
-};
+/* XPM */ +static const char * addressbook20_xpm[] = { +/* columns rows colors chars-per-pixel */ +"20 20 256 2", +" c #FFFFFF", +". c #F7FFFF", +"X c #F7F7FF", +"o c #EFF7FF", +"O c #EFF7F7", +"+ c #E6EFFF", +"@ c #E6EFF7", +"# c #DEEFFF", +"$ c #DEE6F7", +"% c #DEE6EF", +"& c #D6E6F7", +"* c #FFFF00", +"= c #DEDEE6", +"- c #D6DEE6", +"; c #D6D6DE", +": c #CED6E6", +"> c None", +", c #C5D6E6", +"< c #C5CEE6", +"1 c #B5CEEF", +"2 c #C5C5C5", +"3 c #C5DE31", +"4 c #B5C5DE", +"5 c #BDC5C5", +"6 c #ADC5EF", +"7 c #B5C5CE", +"8 c #BDBDBD", +"9 c #B5BDCE", +"0 c #ADBDDE", +"q c #ADBDD6", +"w c #B5CE52", +"e c #ADB5C5", +"r c #00FFFF", +"t c #A5B5C5", +"y c #9CB5CE", +"u c #94B5DE", +"i c #9CADD6", +"p c #A5ADB5", +"a c #94ADDE", +"s c #94ADD6", +"d c #9CADBD", +"f c #8CADDE", +"g c #BD9CA5", +"h c #9CA5BD", +"j c #9CA5B5", +"k c #29D6E6", +"l c #8CA5CE", +"z c #849CCE", +"x c #6BA5C5", +"c c #739CDE", +"v c #00FF00", +"b c #739CD6", +"n c #7B94CE", +"m c #8494AD", +"M c #7394CE", +"N c #7B94B5", +"B c #4AB584", +"V c #848CB5", +"C c #6B94CE", +"Z c #6394D6", +"A c #6394CE", +"S c #7B8CAD", +"D c #6B8CC5", +"F c #738CAD", +"G c #5294B5", +"H c #6B84C5", +"J c #7384A5", +"K c #73849C", +"L c #738494", +"P c #FF4A4A", +"I c #FF4A42", +"U c #737B8C", +"Y c #637BAD", +"T c #527BBD", +"R c #637394", +"E c #637352", +"W c #5A6B8C", +"Q c #526B9C", +"! c #63638C", +"~ c #5A734A", +"^ c #4A6B9C", +"/ c #526B63", +"( c #0884A5", +") c #526384", +"_ c #52637B", +"` c #4A6B5A", +"' c #52636B", +"] c #525A8C", +"[ c #525A7B", +"{ c #426363", +"} c #4A5A7B", +"| c #425A8C", +" . c #196B94", +".. c #3A5A8C", +"X. c #3A5A84", +"o. c #087B4A", +"O. c #21636B", +"+. c #634263", +"@. c #3A527B", +"#. c #424A84", +"$. c #315284", +"%. c #295284", +"&. c #3A4A6B", +"*. c #42427B", +"=. c #424273", +"-. c #294A84", +";. c #3A3A73", +":. c #194284", +">. c #104A63", +",. c #213A6B", +"<. c #31316B", +"1. c #21315A", +"2. c #212163", +"3. c #08295A", +"4. c #082152", +"5. c #101952", +"6. c #CC9966", +"7. c #FF9966", +"8. c #00CC66", +"9. c #33CC66", +"0. c #99CC66", +"q. c #CCCC66", +"w. c #FFCC66", +"e. c #00FF66", +"r. c #33FF66", +"t. c #99FF66", +"y. c #CCFF66", +"u. c #FF00CC", +"i. c #CC00FF", +"p. c #009999", +"a. c #993399", +"s. c #990099", +"d. c #CC0099", +"f. c #000099", +"g. c #333399", +"h. c #660099", +"j. c #CC3399", +"k. c #FF0099", +"l. c #006699", +"z. c #336699", +"x. c #663399", +"c. c #996699", +"v. c #CC6699", +"b. c #FF3399", +"n. c #339999", +"m. c #669999", +"M. c #999999", +"N. c #CC9999", +"B. c #FF9999", +"V. c #00CC99", +"C. c #33CC99", +"Z. c #66CC66", +"A. c #99CC99", +"S. c #CCCC99", +"D. c #FFCC99", +"F. c #00FF99", +"G. c #33FF99", +"H. c #66CC99", +"J. c #99FF99", +"K. c #CCFF99", +"L. c #FFFF99", +"P. c #0000CC", +"I. c #330099", +"U. c #6600CC", +"Y. c #9900CC", +"T. c #CC00CC", +"R. c #003399", +"E. c #3333CC", +"W. c #6633CC", +"Q. c #9933CC", +"!. c #CC33CC", +"~. c #FF33CC", +"^. c #0066CC", +"/. c #3366CC", +"(. c #666699", +"). c #9966CC", +"_. c #CC66CC", +"`. c #FF6699", +"'. c #0099CC", +"]. c #3399CC", +"[. c #6699CC", +"{. c #9999CC", +"}. c #CC99CC", +"|. c #FF99CC", +" X c #00CCCC", +".X c #33CCCC", +"XX c #66CCCC", +"oX c #99CCCC", +"OX c #CCCCCC", +"+X c #FFCCCC", +"@X c #00FFCC", +"#X c #33FFCC", +"$X c #66FF99", +"%X c #99FFCC", +"&X c #CCFFCC", +"*X c #FFFFCC", +"=X c #3300CC", +"-X c #6600FF", +";X c #9900FF", +":X c #0033CC", +">X c #3333FF", +",X c #6633FF", +"<X c #9933FF", +"1X c #CC33FF", +"2X c #FF33FF", +"3X c #0066FF", +"4X c #3366FF", +"5X c #6666CC", +"6X c #9966FF", +"7X c #CC66FF", +"8X c #FF66CC", +"9X c #0099FF", +"0X c #3399FF", +"qX c #6699FF", +"wX c #9999FF", +"eX c #CC99FF", +"rX c #FF99FF", +"tX c #00CCFF", +"yX c #33CCFF", +"uX c #66CCFF", +"iX c #99CCFF", +"pX c #CCCCFF", +"aX c #FFCCFF", +"sX c #33FFFF", +"dX c #66FFCC", +"fX c #99FFFF", +"gX c #CCFFFF", +"hX c #FF6666", +"jX c #66FF66", +"kX c #FFFF66", +"lX c #6666FF", +"zX c #FF66FF", +"xX c #66FFFF", +"cX c #A50021", +"vX c #5F5F5F", +"bX c #777777", +"nX c #868686", +"mX c #969696", +"MX c #CBCBCB", +"NX c #B2B2B2", +"BX c #D7D7D7", +"VX c #DDDDDD", +"CX c #E3E3E3", +"ZX c #EAEAEA", +"AX c #F1F1F1", +"SX c #F8F8F8", +"DX c #FFFBF0", +"FX c #A0A0A4", +"GX c #808080", +"HX c #FF0000", +"JX c #00FF00", +"KX c #FFFF00", +"LX c #0000FF", +"PX c #FF00FF", +"IX c #00FFFF", +"UX c #FFFFFF", +/* pixels */ +"> > > > > > > > > > > > > > > > > > > > ", +"> > > > > > > > > > > > > > > > > > > > ", +"> > U $.| | ^ S 2 > p W | | @.L > > > > ", +"8 5 R - < Y j S O - ) g e > > ", +"! V K - % a Q # - +.P <.> > ", +"! & K - 0 z n D C b f n n z q +.P <.> > ", +"! & K - % M A 1 - %.G #.> > ", +"! & K - % u b # - o.v >.> > ", +"! & K - 0 z n H M b 6 z n z q o.v >.> > ", +"! & K - X - M A a - O.B @.> > ", +"! & K - X % u b # - ` 3 / > > ", +"! & K - 0 l i 4 u b # - ~ * E > > ", +"! & K - X o $ s T b # - { w ' > > ", +"! & K - % f b # - .k -.> > ", +"! & K m d t 7 , u b # ; 9 9 h ( r :.> > ", +"! & h _ _ [ &.4.$.A ,.1.} _ _ F x ] > > ", +"! @ , y N _ 3._ N y , @ ! > > ", +"*.*.*.*.*.*.*.*.;.5.*.*.*.*.*.*.*.2.> > ", +"> > > > > > > > > > > > > > > > > > > > ", +"> > > > > > > > > > > > > > > > > > > > " +}; diff --git a/xpm/check.xpm b/xpm/check.xpm index e62b656961..f822a1e48e 100644 --- a/xpm/check.xpm +++ b/xpm/check.xpm @@ -1,41 +1,41 @@ -/* XPM */
-static const char * check_xpm[] = {
-/* columns rows colors chars-per-pixel */
-"32 32 3 1",
-" c #008000",
-". c #00FF00",
-"X c None",
-/* pixels */
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXX XXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXX . XXXXXXXXXXX",
-"XXXXXXXXXXXXXXXX .. XXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXX . XXXXXXXXXXXX",
-"XXXXXXXXXXXXXXX .. XXXXXXXXXXXXX",
-"XXXXXXXXXXX XX . XXXXXXXXXXXXX",
-"XXXXXXXXXXX . .. XXXXXXXXXXXXXX",
-"XXXXXXXXXXX .. . XXXXXXXXXXXXXX",
-"XXXXXXXXXXXX ... XXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXX . XXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXX XXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
-};
+/* XPM */ +static const char * check_xpm[] = { +/* columns rows colors chars-per-pixel */ +"32 32 3 1", +" c #008000", +". c #00FF00", +"X c None", +/* pixels */ +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXX XXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXX . XXXXXXXXXXX", +"XXXXXXXXXXXXXXXX .. XXXXXXXXXXXX", +"XXXXXXXXXXXXXXXX . XXXXXXXXXXXX", +"XXXXXXXXXXXXXXX .. XXXXXXXXXXXXX", +"XXXXXXXXXXX XX . XXXXXXXXXXXXX", +"XXXXXXXXXXX . .. XXXXXXXXXXXXXX", +"XXXXXXXXXXX .. . XXXXXXXXXXXXXX", +"XXXXXXXXXXXX ... XXXXXXXXXXXXXXX", +"XXXXXXXXXXXXX . XXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXX XXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" +}; diff --git a/xpm/send16.xpm b/xpm/send16.xpm index 7da44d9c56..7640797d2b 100644 --- a/xpm/send16.xpm +++ b/xpm/send16.xpm @@ -1,278 +1,278 @@ -/* XPM */
-static const char * send16_xpm[] = {
-/* columns rows colors chars-per-pixel */
-"16 16 256 2",
-" c #ADF7AD",
-". c #9CFF9C",
-"X c None",
-"o c #ADEFAD",
-"O c #94FF94",
-"+ c #D6CECE",
-"@ c #8CFF8C",
-"# c #CECECE",
-"$ c #CECEC5",
-"% c #84FF84",
-"& c #CEC5C5",
-"* c #73FF73",
-"= c #C5C5C5",
-"- c #6BFF6B",
-"; c #73F773",
-": c #C5BDBD",
-"> c #6BF76B",
-", c #BDBDBD",
-"< c #63F763",
-"1 c #B5B5B5",
-"2 c #52F752",
-"3 c #42FF42",
-"4 c #3AFF3A",
-"5 c #ADADAD",
-"6 c #ADADA5",
-"7 c #4AEF4A",
-"8 c #29FF29",
-"9 c #A5A5A5",
-"0 c #42E642",
-"q c #9CA59C",
-"w c #3AE63A",
-"e c #10FF10",
-"r c #08FF08",
-"t c #949C94",
-"y c #00FF00",
-"u c #00F700",
-"i c #8C948C",
-"p c #00EF00",
-"a c #08E608",
-"s c #10DE10",
-"d c #00E600",
-"f c #00DE00",
-"g c #19C519",
-"h c #00CE00",
-"j c #00C500",
-"k c #008C00",
-"l c #008400",
-"z c #669900",
-"x c #999900",
-"c c #CC9900",
-"v c #FF9900",
-"b c #00CC00",
-"n c #33CC00",
-"m c #66CC00",
-"M c #99CC00",
-"N c #CCCC00",
-"B c #FFCC00",
-"V c #66FF00",
-"C c #99FF00",
-"Z c #CCFF00",
-"A c #000033",
-"S c #330033",
-"D c #660033",
-"F c #990033",
-"G c #CC0033",
-"H c #FF0033",
-"J c #003333",
-"K c #333333",
-"L c #663333",
-"P c #993333",
-"I c #CC3333",
-"U c #FF3333",
-"Y c #006633",
-"T c #336633",
-"R c #666633",
-"E c #996633",
-"W c #CC6633",
-"Q c #FF6633",
-"! c #009933",
-"~ c #339933",
-"^ c #669933",
-"/ c #999933",
-"( c #CC9933",
-") c #FF9933",
-"_ c #00CC33",
-"` c #33CC33",
-"' c #66CC33",
-"] c #99CC33",
-"[ c #CCCC33",
-"{ c #FFCC33",
-"} c #33FF33",
-"| c #66FF33",
-" . c #99FF33",
-".. c #CCFF33",
-"X. c #FFFF33",
-"o. c #000066",
-"O. c #330066",
-"+. c #660066",
-"@. c #990066",
-"#. c #CC0066",
-"$. c #FF0066",
-"%. c #003366",
-"&. c #333366",
-"*. c #663366",
-"=. c #993366",
-"-. c #CC3366",
-";. c #FF3366",
-":. c #006666",
-">. c #336666",
-",. c #666666",
-"<. c #996666",
-"1. c #CC6666",
-"2. c #009966",
-"3. c #339966",
-"4. c #669966",
-"5. c #999966",
-"6. c #CC9966",
-"7. c #FF9966",
-"8. c #00CC66",
-"9. c #33CC66",
-"0. c #99CC66",
-"q. c #CCCC66",
-"w. c #FFCC66",
-"e. c #00FF66",
-"r. c #33FF66",
-"t. c #99FF66",
-"y. c #CCFF66",
-"u. c #FF00CC",
-"i. c #CC00FF",
-"p. c #009999",
-"a. c #993399",
-"s. c #990099",
-"d. c #CC0099",
-"f. c #000099",
-"g. c #333399",
-"h. c #660099",
-"j. c #CC3399",
-"k. c #FF0099",
-"l. c #006699",
-"z. c #336699",
-"x. c #663399",
-"c. c #996699",
-"v. c #CC6699",
-"b. c #FF3399",
-"n. c #339999",
-"m. c #669999",
-"M. c #999999",
-"N. c #CC9999",
-"B. c #FF9999",
-"V. c #00CC99",
-"C. c #33CC99",
-"Z. c #66CC66",
-"A. c #99CC99",
-"S. c #CCCC99",
-"D. c #FFCC99",
-"F. c #00FF99",
-"G. c #33FF99",
-"H. c #66CC99",
-"J. c #99FF99",
-"K. c #CCFF99",
-"L. c #FFFF99",
-"P. c #0000CC",
-"I. c #330099",
-"U. c #6600CC",
-"Y. c #9900CC",
-"T. c #CC00CC",
-"R. c #003399",
-"E. c #3333CC",
-"W. c #6633CC",
-"Q. c #9933CC",
-"!. c #CC33CC",
-"~. c #FF33CC",
-"^. c #0066CC",
-"/. c #3366CC",
-"(. c #666699",
-"). c #9966CC",
-"_. c #CC66CC",
-"`. c #FF6699",
-"'. c #0099CC",
-"]. c #3399CC",
-"[. c #6699CC",
-"{. c #9999CC",
-"}. c #CC99CC",
-"|. c #FF99CC",
-" X c #00CCCC",
-".X c #33CCCC",
-"XX c #66CCCC",
-"oX c #99CCCC",
-"OX c #CCCCCC",
-"+X c #FFCCCC",
-"@X c #00FFCC",
-"#X c #33FFCC",
-"$X c #66FF99",
-"%X c #99FFCC",
-"&X c #CCFFCC",
-"*X c #FFFFCC",
-"=X c #3300CC",
-"-X c #6600FF",
-";X c #9900FF",
-":X c #0033CC",
-">X c #3333FF",
-",X c #6633FF",
-"<X c #9933FF",
-"1X c #CC33FF",
-"2X c #FF33FF",
-"3X c #0066FF",
-"4X c #3366FF",
-"5X c #6666CC",
-"6X c #9966FF",
-"7X c #CC66FF",
-"8X c #FF66CC",
-"9X c #0099FF",
-"0X c #3399FF",
-"qX c #6699FF",
-"wX c #9999FF",
-"eX c #CC99FF",
-"rX c #FF99FF",
-"tX c #00CCFF",
-"yX c #33CCFF",
-"uX c #66CCFF",
-"iX c #99CCFF",
-"pX c #CCCCFF",
-"aX c #FFCCFF",
-"sX c #33FFFF",
-"dX c #66FFCC",
-"fX c #99FFFF",
-"gX c #CCFFFF",
-"hX c #FF6666",
-"jX c #66FF66",
-"kX c #FFFF66",
-"lX c #6666FF",
-"zX c #FF66FF",
-"xX c #66FFFF",
-"cX c #A50021",
-"vX c #5F5F5F",
-"bX c #777777",
-"nX c #868686",
-"mX c #969696",
-"MX c #CBCBCB",
-"NX c #B2B2B2",
-"BX c #D7D7D7",
-"VX c #DDDDDD",
-"CX c #E3E3E3",
-"ZX c #EAEAEA",
-"AX c #F1F1F1",
-"SX c #F8F8F8",
-"DX c #FFFBF0",
-"FX c #A0A0A4",
-"GX c #808080",
-"HX c #FF0000",
-"JX c #00FF00",
-"KX c #FFFF00",
-"LX c #0000FF",
-"PX c #FF00FF",
-"IX c #00FFFF",
-"UX c #FFFFFF",
-/* pixels */
-"X X X X X X X k k X X X X X X X ",
-"X X X X X X X k j k X X X X X X ",
-"X X X X X X X k o j k X X X X X ",
-"X X X X X X X k * o j k X X X X ",
-"l k k k k k k k * * . j k X X X ",
-"l @ @ @ @ @ @ @ 4 e e % j k X X ",
-"l O 3 8 e r r r r r r e ; j k X ",
-"l @ e e r r r r r u p a f < j k ",
-"l @ r u p a a a a a f f w j k i ",
-"l O ; ; ; ; ; < a f b 0 j k t : ",
-"l k k k k k k k s j 7 j k q = X ",
-"X $ = = = = = k g 7 j k 9 & X X ",
-"X X X X X X X k 2 j k 6 $ X X X ",
-"X X X X X X X k j k 5 + X X X X ",
-"X X X X X X X k k 1 + X X X X X ",
-"X X X X X X X = , X X X X X X X "
-};
+/* XPM */ +static const char * send16_xpm[] = { +/* columns rows colors chars-per-pixel */ +"16 16 256 2", +" c #ADF7AD", +". c #9CFF9C", +"X c None", +"o c #ADEFAD", +"O c #94FF94", +"+ c #D6CECE", +"@ c #8CFF8C", +"# c #CECECE", +"$ c #CECEC5", +"% c #84FF84", +"& c #CEC5C5", +"* c #73FF73", +"= c #C5C5C5", +"- c #6BFF6B", +"; c #73F773", +": c #C5BDBD", +"> c #6BF76B", +", c #BDBDBD", +"< c #63F763", +"1 c #B5B5B5", +"2 c #52F752", +"3 c #42FF42", +"4 c #3AFF3A", +"5 c #ADADAD", +"6 c #ADADA5", +"7 c #4AEF4A", +"8 c #29FF29", +"9 c #A5A5A5", +"0 c #42E642", +"q c #9CA59C", +"w c #3AE63A", +"e c #10FF10", +"r c #08FF08", +"t c #949C94", +"y c #00FF00", +"u c #00F700", +"i c #8C948C", +"p c #00EF00", +"a c #08E608", +"s c #10DE10", +"d c #00E600", +"f c #00DE00", +"g c #19C519", +"h c #00CE00", +"j c #00C500", +"k c #008C00", +"l c #008400", +"z c #669900", +"x c #999900", +"c c #CC9900", +"v c #FF9900", +"b c #00CC00", +"n c #33CC00", +"m c #66CC00", +"M c #99CC00", +"N c #CCCC00", +"B c #FFCC00", +"V c #66FF00", +"C c #99FF00", +"Z c #CCFF00", +"A c #000033", +"S c #330033", +"D c #660033", +"F c #990033", +"G c #CC0033", +"H c #FF0033", +"J c #003333", +"K c #333333", +"L c #663333", +"P c #993333", +"I c #CC3333", +"U c #FF3333", +"Y c #006633", +"T c #336633", +"R c #666633", +"E c #996633", +"W c #CC6633", +"Q c #FF6633", +"! c #009933", +"~ c #339933", +"^ c #669933", +"/ c #999933", +"( c #CC9933", +") c #FF9933", +"_ c #00CC33", +"` c #33CC33", +"' c #66CC33", +"] c #99CC33", +"[ c #CCCC33", +"{ c #FFCC33", +"} c #33FF33", +"| c #66FF33", +" . c #99FF33", +".. c #CCFF33", +"X. c #FFFF33", +"o. c #000066", +"O. c #330066", +"+. c #660066", +"@. c #990066", +"#. c #CC0066", +"$. c #FF0066", +"%. c #003366", +"&. c #333366", +"*. c #663366", +"=. c #993366", +"-. c #CC3366", +";. c #FF3366", +":. c #006666", +">. c #336666", +",. c #666666", +"<. c #996666", +"1. c #CC6666", +"2. c #009966", +"3. c #339966", +"4. c #669966", +"5. c #999966", +"6. c #CC9966", +"7. c #FF9966", +"8. c #00CC66", +"9. c #33CC66", +"0. c #99CC66", +"q. c #CCCC66", +"w. c #FFCC66", +"e. c #00FF66", +"r. c #33FF66", +"t. c #99FF66", +"y. c #CCFF66", +"u. c #FF00CC", +"i. c #CC00FF", +"p. c #009999", +"a. c #993399", +"s. c #990099", +"d. c #CC0099", +"f. c #000099", +"g. c #333399", +"h. c #660099", +"j. c #CC3399", +"k. c #FF0099", +"l. c #006699", +"z. c #336699", +"x. c #663399", +"c. c #996699", +"v. c #CC6699", +"b. c #FF3399", +"n. c #339999", +"m. c #669999", +"M. c #999999", +"N. c #CC9999", +"B. c #FF9999", +"V. c #00CC99", +"C. c #33CC99", +"Z. c #66CC66", +"A. c #99CC99", +"S. c #CCCC99", +"D. c #FFCC99", +"F. c #00FF99", +"G. c #33FF99", +"H. c #66CC99", +"J. c #99FF99", +"K. c #CCFF99", +"L. c #FFFF99", +"P. c #0000CC", +"I. c #330099", +"U. c #6600CC", +"Y. c #9900CC", +"T. c #CC00CC", +"R. c #003399", +"E. c #3333CC", +"W. c #6633CC", +"Q. c #9933CC", +"!. c #CC33CC", +"~. c #FF33CC", +"^. c #0066CC", +"/. c #3366CC", +"(. c #666699", +"). c #9966CC", +"_. c #CC66CC", +"`. c #FF6699", +"'. c #0099CC", +"]. c #3399CC", +"[. c #6699CC", +"{. c #9999CC", +"}. c #CC99CC", +"|. c #FF99CC", +" X c #00CCCC", +".X c #33CCCC", +"XX c #66CCCC", +"oX c #99CCCC", +"OX c #CCCCCC", +"+X c #FFCCCC", +"@X c #00FFCC", +"#X c #33FFCC", +"$X c #66FF99", +"%X c #99FFCC", +"&X c #CCFFCC", +"*X c #FFFFCC", +"=X c #3300CC", +"-X c #6600FF", +";X c #9900FF", +":X c #0033CC", +">X c #3333FF", +",X c #6633FF", +"<X c #9933FF", +"1X c #CC33FF", +"2X c #FF33FF", +"3X c #0066FF", +"4X c #3366FF", +"5X c #6666CC", +"6X c #9966FF", +"7X c #CC66FF", +"8X c #FF66CC", +"9X c #0099FF", +"0X c #3399FF", +"qX c #6699FF", +"wX c #9999FF", +"eX c #CC99FF", +"rX c #FF99FF", +"tX c #00CCFF", +"yX c #33CCFF", +"uX c #66CCFF", +"iX c #99CCFF", +"pX c #CCCCFF", +"aX c #FFCCFF", +"sX c #33FFFF", +"dX c #66FFCC", +"fX c #99FFFF", +"gX c #CCFFFF", +"hX c #FF6666", +"jX c #66FF66", +"kX c #FFFF66", +"lX c #6666FF", +"zX c #FF66FF", +"xX c #66FFFF", +"cX c #A50021", +"vX c #5F5F5F", +"bX c #777777", +"nX c #868686", +"mX c #969696", +"MX c #CBCBCB", +"NX c #B2B2B2", +"BX c #D7D7D7", +"VX c #DDDDDD", +"CX c #E3E3E3", +"ZX c #EAEAEA", +"AX c #F1F1F1", +"SX c #F8F8F8", +"DX c #FFFBF0", +"FX c #A0A0A4", +"GX c #808080", +"HX c #FF0000", +"JX c #00FF00", +"KX c #FFFF00", +"LX c #0000FF", +"PX c #FF00FF", +"IX c #00FFFF", +"UX c #FFFFFF", +/* pixels */ +"X X X X X X X k k X X X X X X X ", +"X X X X X X X k j k X X X X X X ", +"X X X X X X X k o j k X X X X X ", +"X X X X X X X k * o j k X X X X ", +"l k k k k k k k * * . j k X X X ", +"l @ @ @ @ @ @ @ 4 e e % j k X X ", +"l O 3 8 e r r r r r r e ; j k X ", +"l @ e e r r r r r u p a f < j k ", +"l @ r u p a a a a a f f w j k i ", +"l O ; ; ; ; ; < a f b 0 j k t : ", +"l k k k k k k k s j 7 j k q = X ", +"X $ = = = = = k g 7 j k 9 & X X ", +"X X X X X X X k 2 j k 6 $ X X X ", +"X X X X X X X k j k 5 + X X X X ", +"X X X X X X X k k 1 + X X X X X ", +"X X X X X X X = , X X X X X X X " +}; diff --git a/xpm/send16noshadow.xpm b/xpm/send16noshadow.xpm index f6cef45e0d..3d20e0d495 100644 --- a/xpm/send16noshadow.xpm +++ b/xpm/send16noshadow.xpm @@ -1,278 +1,278 @@ -/* XPM */
-static const char * send16noshadow_xpm[] = {
-/* columns rows colors chars-per-pixel */
-"16 16 256 2",
-" c #ADF7AD",
-". c #9CFF9C",
-"X c None",
-"o c #ADEFAD",
-"O c #94FF94",
-"+ c #D6CECE",
-"@ c #8CFF8C",
-"# c #CECECE",
-"$ c #CECEC5",
-"% c #84FF84",
-"& c #CEC5C5",
-"* c #73FF73",
-"= c #C5C5C5",
-"- c #6BFF6B",
-"; c #73F773",
-": c #C5BDBD",
-"> c #6BF76B",
-", c #BDBDBD",
-"< c #63F763",
-"1 c #B5B5B5",
-"2 c #52F752",
-"3 c #42FF42",
-"4 c #3AFF3A",
-"5 c #ADADAD",
-"6 c #ADADA5",
-"7 c #4AEF4A",
-"8 c #29FF29",
-"9 c #A5A5A5",
-"0 c #42E642",
-"q c #9CA59C",
-"w c #3AE63A",
-"e c #10FF10",
-"r c #08FF08",
-"t c #949C94",
-"y c #00FF00",
-"u c #00F700",
-"i c #8C948C",
-"p c #00EF00",
-"a c #08E608",
-"s c #10DE10",
-"d c #00E600",
-"f c #00DE00",
-"g c #19C519",
-"h c #00CE00",
-"j c #00C500",
-"k c #008C00",
-"l c #008400",
-"z c #669900",
-"x c #999900",
-"c c #CC9900",
-"v c #FF9900",
-"b c #00CC00",
-"n c #33CC00",
-"m c #66CC00",
-"M c #99CC00",
-"N c #CCCC00",
-"B c #FFCC00",
-"V c #66FF00",
-"C c #99FF00",
-"Z c #CCFF00",
-"A c #000033",
-"S c #330033",
-"D c #660033",
-"F c #990033",
-"G c #CC0033",
-"H c #FF0033",
-"J c #003333",
-"K c #333333",
-"L c #663333",
-"P c #993333",
-"I c #CC3333",
-"U c #FF3333",
-"Y c #006633",
-"T c #336633",
-"R c #666633",
-"E c #996633",
-"W c #CC6633",
-"Q c #FF6633",
-"! c #009933",
-"~ c #339933",
-"^ c #669933",
-"/ c #999933",
-"( c #CC9933",
-") c #FF9933",
-"_ c #00CC33",
-"` c #33CC33",
-"' c #66CC33",
-"] c #99CC33",
-"[ c #CCCC33",
-"{ c #FFCC33",
-"} c #33FF33",
-"| c #66FF33",
-" . c #99FF33",
-".. c #CCFF33",
-"X. c #FFFF33",
-"o. c #000066",
-"O. c #330066",
-"+. c #660066",
-"@. c #990066",
-"#. c #CC0066",
-"$. c #FF0066",
-"%. c #003366",
-"&. c #333366",
-"*. c #663366",
-"=. c #993366",
-"-. c #CC3366",
-";. c #FF3366",
-":. c #006666",
-">. c #336666",
-",. c #666666",
-"<. c #996666",
-"1. c #CC6666",
-"2. c #009966",
-"3. c #339966",
-"4. c #669966",
-"5. c #999966",
-"6. c #CC9966",
-"7. c #FF9966",
-"8. c #00CC66",
-"9. c #33CC66",
-"0. c #99CC66",
-"q. c #CCCC66",
-"w. c #FFCC66",
-"e. c #00FF66",
-"r. c #33FF66",
-"t. c #99FF66",
-"y. c #CCFF66",
-"u. c #FF00CC",
-"i. c #CC00FF",
-"p. c #009999",
-"a. c #993399",
-"s. c #990099",
-"d. c #CC0099",
-"f. c #000099",
-"g. c #333399",
-"h. c #660099",
-"j. c #CC3399",
-"k. c #FF0099",
-"l. c #006699",
-"z. c #336699",
-"x. c #663399",
-"c. c #996699",
-"v. c #CC6699",
-"b. c #FF3399",
-"n. c #339999",
-"m. c #669999",
-"M. c #999999",
-"N. c #CC9999",
-"B. c #FF9999",
-"V. c #00CC99",
-"C. c #33CC99",
-"Z. c #66CC66",
-"A. c #99CC99",
-"S. c #CCCC99",
-"D. c #FFCC99",
-"F. c #00FF99",
-"G. c #33FF99",
-"H. c #66CC99",
-"J. c #99FF99",
-"K. c #CCFF99",
-"L. c #FFFF99",
-"P. c #0000CC",
-"I. c #330099",
-"U. c #6600CC",
-"Y. c #9900CC",
-"T. c #CC00CC",
-"R. c #003399",
-"E. c #3333CC",
-"W. c #6633CC",
-"Q. c #9933CC",
-"!. c #CC33CC",
-"~. c #FF33CC",
-"^. c #0066CC",
-"/. c #3366CC",
-"(. c #666699",
-"). c #9966CC",
-"_. c #CC66CC",
-"`. c #FF6699",
-"'. c #0099CC",
-"]. c #3399CC",
-"[. c #6699CC",
-"{. c #9999CC",
-"}. c #CC99CC",
-"|. c #FF99CC",
-" X c #00CCCC",
-".X c #33CCCC",
-"XX c #66CCCC",
-"oX c #99CCCC",
-"OX c #CCCCCC",
-"+X c #FFCCCC",
-"@X c #00FFCC",
-"#X c #33FFCC",
-"$X c #66FF99",
-"%X c #99FFCC",
-"&X c #CCFFCC",
-"*X c #FFFFCC",
-"=X c #3300CC",
-"-X c #6600FF",
-";X c #9900FF",
-":X c #0033CC",
-">X c #3333FF",
-",X c #6633FF",
-"<X c #9933FF",
-"1X c #CC33FF",
-"2X c #FF33FF",
-"3X c #0066FF",
-"4X c #3366FF",
-"5X c #6666CC",
-"6X c #9966FF",
-"7X c #CC66FF",
-"8X c #FF66CC",
-"9X c #0099FF",
-"0X c #3399FF",
-"qX c #6699FF",
-"wX c #9999FF",
-"eX c #CC99FF",
-"rX c #FF99FF",
-"tX c #00CCFF",
-"yX c #33CCFF",
-"uX c #66CCFF",
-"iX c #99CCFF",
-"pX c #CCCCFF",
-"aX c #FFCCFF",
-"sX c #33FFFF",
-"dX c #66FFCC",
-"fX c #99FFFF",
-"gX c #CCFFFF",
-"hX c #FF6666",
-"jX c #66FF66",
-"kX c #FFFF66",
-"lX c #6666FF",
-"zX c #FF66FF",
-"xX c #66FFFF",
-"cX c #A50021",
-"vX c #5F5F5F",
-"bX c #777777",
-"nX c #868686",
-"mX c #969696",
-"MX c #CBCBCB",
-"NX c #B2B2B2",
-"BX c #D7D7D7",
-"VX c #DDDDDD",
-"CX c #E3E3E3",
-"ZX c #EAEAEA",
-"AX c #F1F1F1",
-"SX c #F8F8F8",
-"DX c #FFFBF0",
-"FX c #A0A0A4",
-"GX c #808080",
-"HX c #FF0000",
-"JX c #00FF00",
-"KX c #FFFF00",
-"LX c #0000FF",
-"PX c #FF00FF",
-"IX c #00FFFF",
-"UX c #FFFFFF",
-/* pixels */
-"X X X X X X X k k X X X X X X X ",
-"X X X X X X X k j k X X X X X X ",
-"X X X X X X X k o j k X X X X X ",
-"X X X X X X X k * o j k X X X X ",
-"l k k k k k k k * * . j k X X X ",
-"l @ @ @ @ @ @ @ 4 e e % j k X X ",
-"l O 3 8 e r r r r r r e ; j k X ",
-"l @ e e r r r r r u p a f < j k ",
-"l @ r u p a a a a a f f w j k X ",
-"l O ; ; ; ; ; < a f b 0 j k X X ",
-"l k k k k k k k s j 7 j k X X X ",
-"X X X X X X X k g 7 j k X X X X ",
-"X X X X X X X k 2 j k X X X X X ",
-"X X X X X X X k j k X X X X X X ",
-"X X X X X X X k k X X X X X X X ",
-"X X X X X X X X X X X X X X X X "
-};
+/* XPM */ +static const char * send16noshadow_xpm[] = { +/* columns rows colors chars-per-pixel */ +"16 16 256 2", +" c #ADF7AD", +". c #9CFF9C", +"X c None", +"o c #ADEFAD", +"O c #94FF94", +"+ c #D6CECE", +"@ c #8CFF8C", +"# c #CECECE", +"$ c #CECEC5", +"% c #84FF84", +"& c #CEC5C5", +"* c #73FF73", +"= c #C5C5C5", +"- c #6BFF6B", +"; c #73F773", +": c #C5BDBD", +"> c #6BF76B", +", c #BDBDBD", +"< c #63F763", +"1 c #B5B5B5", +"2 c #52F752", +"3 c #42FF42", +"4 c #3AFF3A", +"5 c #ADADAD", +"6 c #ADADA5", +"7 c #4AEF4A", +"8 c #29FF29", +"9 c #A5A5A5", +"0 c #42E642", +"q c #9CA59C", +"w c #3AE63A", +"e c #10FF10", +"r c #08FF08", +"t c #949C94", +"y c #00FF00", +"u c #00F700", +"i c #8C948C", +"p c #00EF00", +"a c #08E608", +"s c #10DE10", +"d c #00E600", +"f c #00DE00", +"g c #19C519", +"h c #00CE00", +"j c #00C500", +"k c #008C00", +"l c #008400", +"z c #669900", +"x c #999900", +"c c #CC9900", +"v c #FF9900", +"b c #00CC00", +"n c #33CC00", +"m c #66CC00", +"M c #99CC00", +"N c #CCCC00", +"B c #FFCC00", +"V c #66FF00", +"C c #99FF00", +"Z c #CCFF00", +"A c #000033", +"S c #330033", +"D c #660033", +"F c #990033", +"G c #CC0033", +"H c #FF0033", +"J c #003333", +"K c #333333", +"L c #663333", +"P c #993333", +"I c #CC3333", +"U c #FF3333", +"Y c #006633", +"T c #336633", +"R c #666633", +"E c #996633", +"W c #CC6633", +"Q c #FF6633", +"! c #009933", +"~ c #339933", +"^ c #669933", +"/ c #999933", +"( c #CC9933", +") c #FF9933", +"_ c #00CC33", +"` c #33CC33", +"' c #66CC33", +"] c #99CC33", +"[ c #CCCC33", +"{ c #FFCC33", +"} c #33FF33", +"| c #66FF33", +" . c #99FF33", +".. c #CCFF33", +"X. c #FFFF33", +"o. c #000066", +"O. c #330066", +"+. c #660066", +"@. c #990066", +"#. c #CC0066", +"$. c #FF0066", +"%. c #003366", +"&. c #333366", +"*. c #663366", +"=. c #993366", +"-. c #CC3366", +";. c #FF3366", +":. c #006666", +">. c #336666", +",. c #666666", +"<. c #996666", +"1. c #CC6666", +"2. c #009966", +"3. c #339966", +"4. c #669966", +"5. c #999966", +"6. c #CC9966", +"7. c #FF9966", +"8. c #00CC66", +"9. c #33CC66", +"0. c #99CC66", +"q. c #CCCC66", +"w. c #FFCC66", +"e. c #00FF66", +"r. c #33FF66", +"t. c #99FF66", +"y. c #CCFF66", +"u. c #FF00CC", +"i. c #CC00FF", +"p. c #009999", +"a. c #993399", +"s. c #990099", +"d. c #CC0099", +"f. c #000099", +"g. c #333399", +"h. c #660099", +"j. c #CC3399", +"k. c #FF0099", +"l. c #006699", +"z. c #336699", +"x. c #663399", +"c. c #996699", +"v. c #CC6699", +"b. c #FF3399", +"n. c #339999", +"m. c #669999", +"M. c #999999", +"N. c #CC9999", +"B. c #FF9999", +"V. c #00CC99", +"C. c #33CC99", +"Z. c #66CC66", +"A. c #99CC99", +"S. c #CCCC99", +"D. c #FFCC99", +"F. c #00FF99", +"G. c #33FF99", +"H. c #66CC99", +"J. c #99FF99", +"K. c #CCFF99", +"L. c #FFFF99", +"P. c #0000CC", +"I. c #330099", +"U. c #6600CC", +"Y. c #9900CC", +"T. c #CC00CC", +"R. c #003399", +"E. c #3333CC", +"W. c #6633CC", +"Q. c #9933CC", +"!. c #CC33CC", +"~. c #FF33CC", +"^. c #0066CC", +"/. c #3366CC", +"(. c #666699", +"). c #9966CC", +"_. c #CC66CC", +"`. c #FF6699", +"'. c #0099CC", +"]. c #3399CC", +"[. c #6699CC", +"{. c #9999CC", +"}. c #CC99CC", +"|. c #FF99CC", +" X c #00CCCC", +".X c #33CCCC", +"XX c #66CCCC", +"oX c #99CCCC", +"OX c #CCCCCC", +"+X c #FFCCCC", +"@X c #00FFCC", +"#X c #33FFCC", +"$X c #66FF99", +"%X c #99FFCC", +"&X c #CCFFCC", +"*X c #FFFFCC", +"=X c #3300CC", +"-X c #6600FF", +";X c #9900FF", +":X c #0033CC", +">X c #3333FF", +",X c #6633FF", +"<X c #9933FF", +"1X c #CC33FF", +"2X c #FF33FF", +"3X c #0066FF", +"4X c #3366FF", +"5X c #6666CC", +"6X c #9966FF", +"7X c #CC66FF", +"8X c #FF66CC", +"9X c #0099FF", +"0X c #3399FF", +"qX c #6699FF", +"wX c #9999FF", +"eX c #CC99FF", +"rX c #FF99FF", +"tX c #00CCFF", +"yX c #33CCFF", +"uX c #66CCFF", +"iX c #99CCFF", +"pX c #CCCCFF", +"aX c #FFCCFF", +"sX c #33FFFF", +"dX c #66FFCC", +"fX c #99FFFF", +"gX c #CCFFFF", +"hX c #FF6666", +"jX c #66FF66", +"kX c #FFFF66", +"lX c #6666FF", +"zX c #FF66FF", +"xX c #66FFFF", +"cX c #A50021", +"vX c #5F5F5F", +"bX c #777777", +"nX c #868686", +"mX c #969696", +"MX c #CBCBCB", +"NX c #B2B2B2", +"BX c #D7D7D7", +"VX c #DDDDDD", +"CX c #E3E3E3", +"ZX c #EAEAEA", +"AX c #F1F1F1", +"SX c #F8F8F8", +"DX c #FFFBF0", +"FX c #A0A0A4", +"GX c #808080", +"HX c #FF0000", +"JX c #00FF00", +"KX c #FFFF00", +"LX c #0000FF", +"PX c #FF00FF", +"IX c #00FFFF", +"UX c #FFFFFF", +/* pixels */ +"X X X X X X X k k X X X X X X X ", +"X X X X X X X k j k X X X X X X ", +"X X X X X X X k o j k X X X X X ", +"X X X X X X X k * o j k X X X X ", +"l k k k k k k k * * . j k X X X ", +"l @ @ @ @ @ @ @ 4 e e % j k X X ", +"l O 3 8 e r r r r r r e ; j k X ", +"l @ e e r r r r r u p a f < j k ", +"l @ r u p a a a a a f f w j k X ", +"l O ; ; ; ; ; < a f b 0 j k X X ", +"l k k k k k k k s j 7 j k X X X ", +"X X X X X X X k g 7 j k X X X X ", +"X X X X X X X k 2 j k X X X X X ", +"X X X X X X X k j k X X X X X X ", +"X X X X X X X k k X X X X X X X ", +"X X X X X X X X X X X X X X X X " +}; diff --git a/xpm/send20.xpm b/xpm/send20.xpm index 68e7b1379a..08e726db8e 100644 --- a/xpm/send20.xpm +++ b/xpm/send20.xpm @@ -1,282 +1,282 @@ -/* XPM */
-static const char * send20_xpm[] = {
-/* columns rows colors chars-per-pixel */
-"20 20 256 2",
-" c #CEFFCE",
-". c #BDFFBD",
-"X c #C5F7C5",
-"o c #B5FFB5",
-"O c #ADFFAD",
-"+ c #A5FFA5",
-"@ c #9CFF9C",
-"# c None",
-"$ c #94FF94",
-"% c #D6CECE",
-"& c #8CFF8C",
-"* c #CECEC5",
-"= c #84FF84",
-"- c #94EF94",
-"; c #7BFF7B",
-": c #CEC5C5",
-"> c #73FF73",
-", c #C5C5C5",
-"< c #C5C5BD",
-"1 c #6BFF6B",
-"2 c #BDC5B5",
-"3 c #63FF63",
-"4 c #6BF76B",
-"5 c #BDBDBD",
-"6 c #BDBDB5",
-"7 c #5AFF5A",
-"8 c #63F763",
-"9 c #B5BDB5",
-"0 c #B5BDAD",
-"q c #52FF52",
-"w c #BDB5B5",
-"e c #5AF75A",
-"r c #B5B5B5",
-"t c #B5B5AD",
-"y c #52F752",
-"u c #42FF42",
-"i c #52EF52",
-"p c #ADADAD",
-"a c #ADADA5",
-"s c #4AEF4A",
-"d c #31FF31",
-"f c #29FF29",
-"g c #A5A5A5",
-"h c #21FF21",
-"j c #5AD65A",
-"k c #42E642",
-"l c #94AD94",
-"z c #4ADE4A",
-"x c #3AE63A",
-"c c #5ACE5A",
-"v c #10FF10",
-"b c #9C9C9C",
-"n c #31E631",
-"m c #08FF08",
-"M c #949C94",
-"N c #84A584",
-"B c #00FF00",
-"V c #3AD63A",
-"C c #52C552",
-"Z c #00F700",
-"A c #8C948C",
-"S c #849484",
-"D c #00EF00",
-"F c #739C73",
-"G c #08E608",
-"H c #4AB54A",
-"J c #31C531",
-"K c #00E600",
-"L c #739473",
-"P c #00DE00",
-"I c #63945A",
-"U c #6B8C6B",
-"Y c #00D600",
-"T c #42A542",
-"R c #638C63",
-"E c #00CE00",
-"W c #21B521",
-"Q c #5A8C5A",
-"! c #00C500",
-"~ c #528C52",
-"^ c #3A9C3A",
-"/ c #4A8C4A",
-"( c #00BD00",
-") c #319431",
-"_ c #219C21",
-"` c #318C31",
-"' c #3A843A",
-"] c #219421",
-"[ c #298C29",
-"{ c #318431",
-"} c #218C21",
-"| c #218C19",
-" . c #198C19",
-".. c #218421",
-"X. c #297B29",
-"o. c #198419",
-"O. c #217B21",
-"+. c #108410",
-"@. c #197B19",
-"#. c #CC0066",
-"$. c #FF0066",
-"%. c #003366",
-"&. c #333366",
-"*. c #663366",
-"=. c #993366",
-"-. c #CC3366",
-";. c #FF3366",
-":. c #006666",
-">. c #336666",
-",. c #666666",
-"<. c #996666",
-"1. c #CC6666",
-"2. c #009966",
-"3. c #339966",
-"4. c #669966",
-"5. c #999966",
-"6. c #CC9966",
-"7. c #FF9966",
-"8. c #00CC66",
-"9. c #33CC66",
-"0. c #99CC66",
-"q. c #CCCC66",
-"w. c #FFCC66",
-"e. c #00FF66",
-"r. c #33FF66",
-"t. c #99FF66",
-"y. c #CCFF66",
-"u. c #FF00CC",
-"i. c #CC00FF",
-"p. c #009999",
-"a. c #993399",
-"s. c #990099",
-"d. c #CC0099",
-"f. c #000099",
-"g. c #333399",
-"h. c #660099",
-"j. c #CC3399",
-"k. c #FF0099",
-"l. c #006699",
-"z. c #336699",
-"x. c #663399",
-"c. c #996699",
-"v. c #CC6699",
-"b. c #FF3399",
-"n. c #339999",
-"m. c #669999",
-"M. c #999999",
-"N. c #CC9999",
-"B. c #FF9999",
-"V. c #00CC99",
-"C. c #33CC99",
-"Z. c #66CC66",
-"A. c #99CC99",
-"S. c #CCCC99",
-"D. c #FFCC99",
-"F. c #00FF99",
-"G. c #33FF99",
-"H. c #66CC99",
-"J. c #99FF99",
-"K. c #CCFF99",
-"L. c #FFFF99",
-"P. c #0000CC",
-"I. c #330099",
-"U. c #6600CC",
-"Y. c #9900CC",
-"T. c #CC00CC",
-"R. c #003399",
-"E. c #3333CC",
-"W. c #6633CC",
-"Q. c #9933CC",
-"!. c #CC33CC",
-"~. c #FF33CC",
-"^. c #0066CC",
-"/. c #3366CC",
-"(. c #666699",
-"). c #9966CC",
-"_. c #CC66CC",
-"`. c #FF6699",
-"'. c #0099CC",
-"]. c #3399CC",
-"[. c #6699CC",
-"{. c #9999CC",
-"}. c #CC99CC",
-"|. c #FF99CC",
-" X c #00CCCC",
-".X c #33CCCC",
-"XX c #66CCCC",
-"oX c #99CCCC",
-"OX c #CCCCCC",
-"+X c #FFCCCC",
-"@X c #00FFCC",
-"#X c #33FFCC",
-"$X c #66FF99",
-"%X c #99FFCC",
-"&X c #CCFFCC",
-"*X c #FFFFCC",
-"=X c #3300CC",
-"-X c #6600FF",
-";X c #9900FF",
-":X c #0033CC",
-">X c #3333FF",
-",X c #6633FF",
-"<X c #9933FF",
-"1X c #CC33FF",
-"2X c #FF33FF",
-"3X c #0066FF",
-"4X c #3366FF",
-"5X c #6666CC",
-"6X c #9966FF",
-"7X c #CC66FF",
-"8X c #FF66CC",
-"9X c #0099FF",
-"0X c #3399FF",
-"qX c #6699FF",
-"wX c #9999FF",
-"eX c #CC99FF",
-"rX c #FF99FF",
-"tX c #00CCFF",
-"yX c #33CCFF",
-"uX c #66CCFF",
-"iX c #99CCFF",
-"pX c #CCCCFF",
-"aX c #FFCCFF",
-"sX c #33FFFF",
-"dX c #66FFCC",
-"fX c #99FFFF",
-"gX c #CCFFFF",
-"hX c #FF6666",
-"jX c #66FF66",
-"kX c #FFFF66",
-"lX c #6666FF",
-"zX c #FF66FF",
-"xX c #66FFFF",
-"cX c #A50021",
-"vX c #5F5F5F",
-"bX c #777777",
-"nX c #868686",
-"mX c #969696",
-"MX c #CBCBCB",
-"NX c #B2B2B2",
-"BX c #D7D7D7",
-"VX c #DDDDDD",
-"CX c #E3E3E3",
-"ZX c #EAEAEA",
-"AX c #F1F1F1",
-"SX c #F8F8F8",
-"DX c #FFFBF0",
-"FX c #A0A0A4",
-"GX c #808080",
-"HX c #FF0000",
-"JX c #00FF00",
-"KX c #FFFF00",
-"LX c #0000FF",
-"PX c #FF00FF",
-"IX c #00FFFF",
-"UX c #FFFFFF",
-/* pixels */
-"# # # # # # # # # # # # # # # # # # # # ",
-"# # # # # # # ` 0 # # # # # # # # # # # ",
-"# # # # # # # ..` l # # # # # # # # # # ",
-"# # # # # # # [ X ) N # # # # # # # # # ",
-"# # # # # # # [ &X. ^ F # # # # # # # # ",
-"# # # # # # # } o & o T I : # # # # # # ",
-"` ` ` ` ` ` ` ` + 7 ; + H ~ < # # # # # ",
-"` = = = = = = - @ d v h $ C ' 5 # # # # ",
-"` = = 3 u h v v v m m m v ; c { 6 # # # ",
-"` = f v v m m m m m m Z G G 4 j ..t # # ",
-"` = v m m m Z Z D D G G G P n ; _ R 5 # ",
-"` = m Z G G G G G G G P Y x 4 _ Q g # # ",
-"` = $ $ $ $ $ & e P P E k 8 .U g # # # ",
-"..[ ......[ [ ] e Y ! s i o.L p # # # # ",
-"# # 5 6 6 6 9 ..i ( i z o.S t # # # # # ",
-"# # # # # # # } i i V O.A r # # # # # # ",
-"# # # # # # # } 7 J X.M 6 # # # # # # # ",
-"# # # # # # # | W ' b < # # # # # # # # ",
-"# # # # # # # @.~ g , # # # # # # # # # ",
-"# # # # # # # 6 < , # # # # # # # # # # "
-};
+/* XPM */ +static const char * send20_xpm[] = { +/* columns rows colors chars-per-pixel */ +"20 20 256 2", +" c #CEFFCE", +". c #BDFFBD", +"X c #C5F7C5", +"o c #B5FFB5", +"O c #ADFFAD", +"+ c #A5FFA5", +"@ c #9CFF9C", +"# c None", +"$ c #94FF94", +"% c #D6CECE", +"& c #8CFF8C", +"* c #CECEC5", +"= c #84FF84", +"- c #94EF94", +"; c #7BFF7B", +": c #CEC5C5", +"> c #73FF73", +", c #C5C5C5", +"< c #C5C5BD", +"1 c #6BFF6B", +"2 c #BDC5B5", +"3 c #63FF63", +"4 c #6BF76B", +"5 c #BDBDBD", +"6 c #BDBDB5", +"7 c #5AFF5A", +"8 c #63F763", +"9 c #B5BDB5", +"0 c #B5BDAD", +"q c #52FF52", +"w c #BDB5B5", +"e c #5AF75A", +"r c #B5B5B5", +"t c #B5B5AD", +"y c #52F752", +"u c #42FF42", +"i c #52EF52", +"p c #ADADAD", +"a c #ADADA5", +"s c #4AEF4A", +"d c #31FF31", +"f c #29FF29", +"g c #A5A5A5", +"h c #21FF21", +"j c #5AD65A", +"k c #42E642", +"l c #94AD94", +"z c #4ADE4A", +"x c #3AE63A", +"c c #5ACE5A", +"v c #10FF10", +"b c #9C9C9C", +"n c #31E631", +"m c #08FF08", +"M c #949C94", +"N c #84A584", +"B c #00FF00", +"V c #3AD63A", +"C c #52C552", +"Z c #00F700", +"A c #8C948C", +"S c #849484", +"D c #00EF00", +"F c #739C73", +"G c #08E608", +"H c #4AB54A", +"J c #31C531", +"K c #00E600", +"L c #739473", +"P c #00DE00", +"I c #63945A", +"U c #6B8C6B", +"Y c #00D600", +"T c #42A542", +"R c #638C63", +"E c #00CE00", +"W c #21B521", +"Q c #5A8C5A", +"! c #00C500", +"~ c #528C52", +"^ c #3A9C3A", +"/ c #4A8C4A", +"( c #00BD00", +") c #319431", +"_ c #219C21", +"` c #318C31", +"' c #3A843A", +"] c #219421", +"[ c #298C29", +"{ c #318431", +"} c #218C21", +"| c #218C19", +" . c #198C19", +".. c #218421", +"X. c #297B29", +"o. c #198419", +"O. c #217B21", +"+. c #108410", +"@. c #197B19", +"#. c #CC0066", +"$. c #FF0066", +"%. c #003366", +"&. c #333366", +"*. c #663366", +"=. c #993366", +"-. c #CC3366", +";. c #FF3366", +":. c #006666", +">. c #336666", +",. c #666666", +"<. c #996666", +"1. c #CC6666", +"2. c #009966", +"3. c #339966", +"4. c #669966", +"5. c #999966", +"6. c #CC9966", +"7. c #FF9966", +"8. c #00CC66", +"9. c #33CC66", +"0. c #99CC66", +"q. c #CCCC66", +"w. c #FFCC66", +"e. c #00FF66", +"r. c #33FF66", +"t. c #99FF66", +"y. c #CCFF66", +"u. c #FF00CC", +"i. c #CC00FF", +"p. c #009999", +"a. c #993399", +"s. c #990099", +"d. c #CC0099", +"f. c #000099", +"g. c #333399", +"h. c #660099", +"j. c #CC3399", +"k. c #FF0099", +"l. c #006699", +"z. c #336699", +"x. c #663399", +"c. c #996699", +"v. c #CC6699", +"b. c #FF3399", +"n. c #339999", +"m. c #669999", +"M. c #999999", +"N. c #CC9999", +"B. c #FF9999", +"V. c #00CC99", +"C. c #33CC99", +"Z. c #66CC66", +"A. c #99CC99", +"S. c #CCCC99", +"D. c #FFCC99", +"F. c #00FF99", +"G. c #33FF99", +"H. c #66CC99", +"J. c #99FF99", +"K. c #CCFF99", +"L. c #FFFF99", +"P. c #0000CC", +"I. c #330099", +"U. c #6600CC", +"Y. c #9900CC", +"T. c #CC00CC", +"R. c #003399", +"E. c #3333CC", +"W. c #6633CC", +"Q. c #9933CC", +"!. c #CC33CC", +"~. c #FF33CC", +"^. c #0066CC", +"/. c #3366CC", +"(. c #666699", +"). c #9966CC", +"_. c #CC66CC", +"`. c #FF6699", +"'. c #0099CC", +"]. c #3399CC", +"[. c #6699CC", +"{. c #9999CC", +"}. c #CC99CC", +"|. c #FF99CC", +" X c #00CCCC", +".X c #33CCCC", +"XX c #66CCCC", +"oX c #99CCCC", +"OX c #CCCCCC", +"+X c #FFCCCC", +"@X c #00FFCC", +"#X c #33FFCC", +"$X c #66FF99", +"%X c #99FFCC", +"&X c #CCFFCC", +"*X c #FFFFCC", +"=X c #3300CC", +"-X c #6600FF", +";X c #9900FF", +":X c #0033CC", +">X c #3333FF", +",X c #6633FF", +"<X c #9933FF", +"1X c #CC33FF", +"2X c #FF33FF", +"3X c #0066FF", +"4X c #3366FF", +"5X c #6666CC", +"6X c #9966FF", +"7X c #CC66FF", +"8X c #FF66CC", +"9X c #0099FF", +"0X c #3399FF", +"qX c #6699FF", +"wX c #9999FF", +"eX c #CC99FF", +"rX c #FF99FF", +"tX c #00CCFF", +"yX c #33CCFF", +"uX c #66CCFF", +"iX c #99CCFF", +"pX c #CCCCFF", +"aX c #FFCCFF", +"sX c #33FFFF", +"dX c #66FFCC", +"fX c #99FFFF", +"gX c #CCFFFF", +"hX c #FF6666", +"jX c #66FF66", +"kX c #FFFF66", +"lX c #6666FF", +"zX c #FF66FF", +"xX c #66FFFF", +"cX c #A50021", +"vX c #5F5F5F", +"bX c #777777", +"nX c #868686", +"mX c #969696", +"MX c #CBCBCB", +"NX c #B2B2B2", +"BX c #D7D7D7", +"VX c #DDDDDD", +"CX c #E3E3E3", +"ZX c #EAEAEA", +"AX c #F1F1F1", +"SX c #F8F8F8", +"DX c #FFFBF0", +"FX c #A0A0A4", +"GX c #808080", +"HX c #FF0000", +"JX c #00FF00", +"KX c #FFFF00", +"LX c #0000FF", +"PX c #FF00FF", +"IX c #00FFFF", +"UX c #FFFFFF", +/* pixels */ +"# # # # # # # # # # # # # # # # # # # # ", +"# # # # # # # ` 0 # # # # # # # # # # # ", +"# # # # # # # ..` l # # # # # # # # # # ", +"# # # # # # # [ X ) N # # # # # # # # # ", +"# # # # # # # [ &X. ^ F # # # # # # # # ", +"# # # # # # # } o & o T I : # # # # # # ", +"` ` ` ` ` ` ` ` + 7 ; + H ~ < # # # # # ", +"` = = = = = = - @ d v h $ C ' 5 # # # # ", +"` = = 3 u h v v v m m m v ; c { 6 # # # ", +"` = f v v m m m m m m Z G G 4 j ..t # # ", +"` = v m m m Z Z D D G G G P n ; _ R 5 # ", +"` = m Z G G G G G G G P Y x 4 _ Q g # # ", +"` = $ $ $ $ $ & e P P E k 8 .U g # # # ", +"..[ ......[ [ ] e Y ! s i o.L p # # # # ", +"# # 5 6 6 6 9 ..i ( i z o.S t # # # # # ", +"# # # # # # # } i i V O.A r # # # # # # ", +"# # # # # # # } 7 J X.M 6 # # # # # # # ", +"# # # # # # # | W ' b < # # # # # # # # ", +"# # # # # # # @.~ g , # # # # # # # # # ", +"# # # # # # # 6 < , # # # # # # # # # # " +}; |