Advertisement
Guest User

bitcoin

a guest
Sep 7th, 2013
2,320
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 414.77 KB | None | 0 0
  1. static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
  2. inline string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend)
  3. {
  4.     CAutoBN_CTX pctx;
  5.     CBigNum bn58 = 58;
  6.     CBigNum bn0 = 0;
  7.     vector<unsigned char> vchTmp(pend-pbegin+1, 0);
  8.     reverse_copy(pbegin, pend, vchTmp.begin());
  9.     CBigNum bn;
  10.     bn.setvch(vchTmp);
  11.     string str;
  12.     str.reserve((pend - pbegin) * 138 / 100 + 1);
  13.     CBigNum dv;
  14.     CBigNum rem;
  15.     while (bn > bn0)
  16.     {
  17.         if (!BN_div(&dv, &rem, &bn, &bn58, pctx))
  18.             throw bignum_error("EncodeBase58 : BN_div failed");
  19.         bn = dv;
  20.         unsigned int c = rem.getulong();
  21.         str += pszBase58[c];
  22.     }
  23.     for (const unsigned char* p = pbegin; p < pend && *p == 0; p++)
  24.         str += pszBase58[0];
  25.     reverse(str.begin(), str.end());
  26.     return str;
  27. }
  28. inline string EncodeBase58(const vector<unsigned char>& vch)
  29. {
  30.     return EncodeBase58(&vch[0], &vch[0] + vch.size());
  31. }
  32. inline bool DecodeBase58(const char* psz, vector<unsigned char>& vchRet)
  33. {
  34.     CAutoBN_CTX pctx;
  35.     vchRet.clear();
  36.     CBigNum bn58 = 58;
  37.     CBigNum bn = 0;
  38.     CBigNum bnChar;
  39.     while (isspace(*psz))
  40.         psz++;
  41.     for (const char* p = psz; *p; p++)
  42.     {
  43.         const char* p1 = strchr(pszBase58, *p);
  44.         if (p1 == NULL)
  45.         {
  46.             while (isspace(*p))
  47.                 p++;
  48.             if (*p != '\0')
  49.                 return false;
  50.             break;
  51.         }
  52.         bnChar.setulong(p1 - pszBase58);
  53.         if (!BN_mul(&bn, &bn, &bn58, pctx))
  54.             throw bignum_error("DecodeBase58 : BN_mul failed");
  55.         bn += bnChar;
  56.     }
  57.     vector<unsigned char> vchTmp = bn.getvch();
  58.     if (vchTmp.size() >= 2 && vchTmp.end()[-1] == 0 && vchTmp.end()[-2] >= 0x80)
  59.         vchTmp.erase(vchTmp.end()-1);
  60.     int nLeadingZeros = 0;
  61.     for (const char* p = psz; *p == pszBase58[0]; p++)
  62.         nLeadingZeros++;
  63.     vchRet.assign(nLeadingZeros + vchTmp.size(), 0);
  64.     reverse_copy(vchTmp.begin(), vchTmp.end(), vchRet.end() - vchTmp.size());
  65.     return true;
  66. }
  67. inline bool DecodeBase58(const string& str, vector<unsigned char>& vchRet)
  68. {
  69.     return DecodeBase58(str.c_str(), vchRet);
  70. }
  71. inline string EncodeBase58Check(const vector<unsigned char>& vchIn)
  72. {
  73.     vector<unsigned char> vch(vchIn);
  74.     uint256 hash = Hash(vch.begin(), vch.end());
  75.     vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4);
  76.     return EncodeBase58(vch);
  77. }
  78. inline bool DecodeBase58Check(const char* psz, vector<unsigned char>& vchRet)
  79. {
  80.     if (!DecodeBase58(psz, vchRet))
  81.         return false;
  82.     if (vchRet.size() < 4)
  83.     {
  84.         vchRet.clear();
  85.         return false;
  86.     }
  87.     uint256 hash = Hash(vchRet.begin(), vchRet.end()-4);
  88.     if (memcmp(&hash, &vchRet.end()[-4], 4) != 0)
  89.     {
  90.         vchRet.clear();
  91.         return false;
  92.     }
  93.     vchRet.resize(vchRet.size()-4);
  94.     return true;
  95. }
  96. inline bool DecodeBase58Check(const string& str, vector<unsigned char>& vchRet)
  97. {
  98.     return DecodeBase58Check(str.c_str(), vchRet);
  99. }
  100. static const unsigned char ADDRESSVERSION = 0;
  101. inline string Hash160ToAddress(uint160 hash160)
  102. {
  103.     vector<unsigned char> vch(1, ADDRESSVERSION);
  104.     vch.insert(vch.end(), UBEGIN(hash160), UEND(hash160));
  105.     return EncodeBase58Check(vch);
  106. }
  107. inline bool AddressToHash160(const char* psz, uint160& hash160Ret)
  108. {
  109.     vector<unsigned char> vch;
  110.     if (!DecodeBase58Check(psz, vch))
  111.         return false;
  112.     if (vch.empty())
  113.         return false;
  114.     unsigned char nVersion = vch[0];
  115.     if (vch.size() != sizeof(hash160Ret) + 1)
  116.         return false;
  117.     memcpy(&hash160Ret, &vch[1], sizeof(hash160Ret));
  118.     return (nVersion <= ADDRESSVERSION);
  119. }
  120. inline bool AddressToHash160(const string& str, uint160& hash160Ret)
  121. {
  122.     return AddressToHash160(str.c_str(), hash160Ret);
  123. }
  124. inline bool IsValidBitcoinAddress(const char* psz)
  125. {
  126.     uint160 hash160;
  127.     return AddressToHash160(psz, hash160);
  128. }
  129. inline bool IsValidBitcoinAddress(const string& str)
  130. {
  131.     return IsValidBitcoinAddress(str.c_str());
  132. }
  133. inline string PubKeyToAddress(const vector<unsigned char>& vchPubKey)
  134. {
  135.     return Hash160ToAddress(Hash160(vchPubKey));
  136. }
  137. #include <stdexcept>
  138. #include <vector>
  139. #include <openssl/bn.h>
  140. class bignum_error : public std::runtime_error
  141. {
  142. public:
  143.     explicit bignum_error(const std::string& str) : std::runtime_error(str) {}
  144. };
  145. class CAutoBN_CTX
  146. {
  147. protected:
  148.     BN_CTX* pctx;
  149.     BN_CTX* operator=(BN_CTX* pnew) { return pctx = pnew; }
  150. public:
  151.     CAutoBN_CTX()
  152.     {
  153.         pctx = BN_CTX_new();
  154.         if (pctx == NULL)
  155.             throw bignum_error("CAutoBN_CTX : BN_CTX_new() returned NULL");
  156.     }
  157.     ~CAutoBN_CTX()
  158.     {
  159.         if (pctx != NULL)
  160.             BN_CTX_free(pctx);
  161.     }
  162.     operator BN_CTX*() { return pctx; }
  163.     BN_CTX& operator*() { return *pctx; }
  164.     BN_CTX** operator&() { return &pctx; }
  165.     bool operator!() { return (pctx == NULL); }
  166. };
  167. class CBigNum : public BIGNUM
  168. {
  169. public:
  170.     CBigNum()
  171.     {
  172.         BN_init(this);
  173.     }
  174.     CBigNum(const CBigNum& b)
  175.     {
  176.         BN_init(this);
  177.         if (!BN_copy(this, &b))
  178.         {
  179.             BN_clear_free(this);
  180.             throw bignum_error("CBigNum::CBigNum(const CBigNum&) : BN_copy failed");
  181.         }
  182.     }
  183.     explicit CBigNum(const std::string& str)
  184.     {
  185.         BN_init(this);
  186.         SetHex(str);
  187.     }
  188.     CBigNum& operator=(const CBigNum& b)
  189.     {
  190.         if (!BN_copy(this, &b))
  191.             throw bignum_error("CBigNum::operator= : BN_copy failed");
  192.         return (*this);
  193.     }
  194.     ~CBigNum()
  195.     {
  196.         BN_clear_free(this);
  197.     }
  198.     CBigNum(char n)             { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
  199.     CBigNum(short n)            { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
  200.     CBigNum(int n)              { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
  201.     CBigNum(long n)             { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
  202.     CBigNum(int64 n)            { BN_init(this); setint64(n); }
  203.     CBigNum(unsigned char n)    { BN_init(this); setulong(n); }
  204.     CBigNum(unsigned short n)   { BN_init(this); setulong(n); }
  205.     CBigNum(unsigned int n)     { BN_init(this); setulong(n); }
  206.     CBigNum(unsigned long n)    { BN_init(this); setulong(n); }
  207.     CBigNum(uint64 n)           { BN_init(this); setuint64(n); }
  208.     explicit CBigNum(uint256 n) { BN_init(this); setuint256(n); }
  209.     explicit CBigNum(const std::vector<unsigned char>& vch)
  210.     {
  211.         BN_init(this);
  212.         setvch(vch);
  213.     }
  214.     void setulong(unsigned long n)
  215.     {
  216.         if (!BN_set_word(this, n))
  217.             throw bignum_error("CBigNum conversion from unsigned long : BN_set_word failed");
  218.     }
  219.     unsigned long getulong() const
  220.     {
  221.         return BN_get_word(this);
  222.     }
  223.     unsigned int getuint() const
  224.     {
  225.         return BN_get_word(this);
  226.     }
  227.     int getint() const
  228.     {
  229.         unsigned long n = BN_get_word(this);
  230.         if (!BN_is_negative(this))
  231.             return (n > INT_MAX ? INT_MAX : n);
  232.         else
  233.             return (n > INT_MAX ? INT_MIN : -(int)n);
  234.     }
  235.     void setint64(int64 n)
  236.     {
  237.         unsigned char pch[sizeof(n) + 6];
  238.         unsigned char* p = pch + 4;
  239.         bool fNegative = false;
  240.         if (n < (int64)0)
  241.         {
  242.             n = -n;
  243.             fNegative = true;
  244.         }
  245.         bool fLeadingZeroes = true;
  246.         for (int i = 0; i < 8; i++)
  247.         {
  248.             unsigned char c = (n >> 56) & 0xff;
  249.             n <<= 8;
  250.             if (fLeadingZeroes)
  251.             {
  252.                 if (c == 0)
  253.                     continue;
  254.                 if (c & 0x80)
  255.                     *p++ = (fNegative ? 0x80 : 0);
  256.                 else if (fNegative)
  257.                     c |= 0x80;
  258.                 fLeadingZeroes = false;
  259.             }
  260.             *p++ = c;
  261.         }
  262.         unsigned int nSize = p - (pch + 4);
  263.         pch[0] = (nSize >> 24) & 0xff;
  264.         pch[1] = (nSize >> 16) & 0xff;
  265.         pch[2] = (nSize >> 8) & 0xff;
  266.         pch[3] = (nSize) & 0xff;
  267.         BN_mpi2bn(pch, p - pch, this);
  268.     }
  269.     void setuint64(uint64 n)
  270.     {
  271.         unsigned char pch[sizeof(n) + 6];
  272.         unsigned char* p = pch + 4;
  273.         bool fLeadingZeroes = true;
  274.         for (int i = 0; i < 8; i++)
  275.         {
  276.             unsigned char c = (n >> 56) & 0xff;
  277.             n <<= 8;
  278.             if (fLeadingZeroes)
  279.             {
  280.                 if (c == 0)
  281.                     continue;
  282.                 if (c & 0x80)
  283.                     *p++ = 0;
  284.                 fLeadingZeroes = false;
  285.             }
  286.             *p++ = c;
  287.         }
  288.         unsigned int nSize = p - (pch + 4);
  289.         pch[0] = (nSize >> 24) & 0xff;
  290.         pch[1] = (nSize >> 16) & 0xff;
  291.         pch[2] = (nSize >> 8) & 0xff;
  292.         pch[3] = (nSize) & 0xff;
  293.         BN_mpi2bn(pch, p - pch, this);
  294.     }
  295.     void setuint256(uint256 n)
  296.     {
  297.         unsigned char pch[sizeof(n) + 6];
  298.         unsigned char* p = pch + 4;
  299.         bool fLeadingZeroes = true;
  300.         unsigned char* pbegin = (unsigned char*)&n;
  301.         unsigned char* psrc = pbegin + sizeof(n);
  302.         while (psrc != pbegin)
  303.         {
  304.             unsigned char c = *(--psrc);
  305.             if (fLeadingZeroes)
  306.             {
  307.                 if (c == 0)
  308.                     continue;
  309.                 if (c & 0x80)
  310.                     *p++ = 0;
  311.                 fLeadingZeroes = false;
  312.             }
  313.             *p++ = c;
  314.         }
  315.         unsigned int nSize = p - (pch + 4);
  316.         pch[0] = (nSize >> 24) & 0xff;
  317.         pch[1] = (nSize >> 16) & 0xff;
  318.         pch[2] = (nSize >> 8) & 0xff;
  319.         pch[3] = (nSize >> 0) & 0xff;
  320.         BN_mpi2bn(pch, p - pch, this);
  321.     }
  322.     uint256 getuint256()
  323.     {
  324.         unsigned int nSize = BN_bn2mpi(this, NULL);
  325.         if (nSize < 4)
  326.             return 0;
  327.         std::vector<unsigned char> vch(nSize);
  328.         BN_bn2mpi(this, &vch[0]);
  329.         if (vch.size() > 4)
  330.             vch[4] &= 0x7f;
  331.         uint256 n = 0;
  332.         for (int i = 0, j = vch.size()-1; i < sizeof(n) && j >= 4; i++, j--)
  333.             ((unsigned char*)&n)[i] = vch[j];
  334.         return n;
  335.     }
  336.     void setvch(const std::vector<unsigned char>& vch)
  337.     {
  338.         std::vector<unsigned char> vch2(vch.size() + 4);
  339.         unsigned int nSize = vch.size();
  340.         vch2[0] = (nSize >> 24) & 0xff;
  341.         vch2[1] = (nSize >> 16) & 0xff;
  342.         vch2[2] = (nSize >> 8) & 0xff;
  343.         vch2[3] = (nSize >> 0) & 0xff;
  344.         reverse_copy(vch.begin(), vch.end(), vch2.begin() + 4);
  345.         BN_mpi2bn(&vch2[0], vch2.size(), this);
  346.     }
  347.     std::vector<unsigned char> getvch() const
  348.     {
  349.         unsigned int nSize = BN_bn2mpi(this, NULL);
  350.         if (nSize < 4)
  351.             return std::vector<unsigned char>();
  352.         std::vector<unsigned char> vch(nSize);
  353.         BN_bn2mpi(this, &vch[0]);
  354.         vch.erase(vch.begin(), vch.begin() + 4);
  355.         reverse(vch.begin(), vch.end());
  356.         return vch;
  357.     }
  358.     CBigNum& SetCompact(unsigned int nCompact)
  359.     {
  360.         unsigned int nSize = nCompact >> 24;
  361.         std::vector<unsigned char> vch(4 + nSize);
  362.         vch[3] = nSize;
  363.         if (nSize >= 1) vch[4] = (nCompact >> 16) & 0xff;
  364.         if (nSize >= 2) vch[5] = (nCompact >> 8) & 0xff;
  365.         if (nSize >= 3) vch[6] = (nCompact >> 0) & 0xff;
  366.         BN_mpi2bn(&vch[0], vch.size(), this);
  367.         return *this;
  368.     }
  369.     unsigned int GetCompact() const
  370.     {
  371.         unsigned int nSize = BN_bn2mpi(this, NULL);
  372.         std::vector<unsigned char> vch(nSize);
  373.         nSize -= 4;
  374.         BN_bn2mpi(this, &vch[0]);
  375.         unsigned int nCompact = nSize << 24;
  376.         if (nSize >= 1) nCompact |= (vch[4] << 16);
  377.         if (nSize >= 2) nCompact |= (vch[5] << 8);
  378.         if (nSize >= 3) nCompact |= (vch[6] << 0);
  379.         return nCompact;
  380.     }
  381.     void SetHex(const std::string& str)
  382.     {
  383.         const char* psz = str.c_str();
  384.         while (isspace(*psz))
  385.             psz++;
  386.         bool fNegative = false;
  387.         if (*psz == '-')
  388.         {
  389.             fNegative = true;
  390.             psz++;
  391.         }
  392.         if (psz[0] == '0' && tolower(psz[1]) == 'x')
  393.             psz += 2;
  394.         while (isspace(*psz))
  395.             psz++;
  396.         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 };
  397.         *this = 0;
  398.         while (isxdigit(*psz))
  399.         {
  400.             *this <<= 4;
  401.             int n = phexdigit[*psz++];
  402.             *this += n;
  403.         }
  404.         if (fNegative)
  405.             *this = 0 - *this;
  406.     }
  407.     unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const
  408.     {
  409.         return ::GetSerializeSize(getvch(), nType, nVersion);
  410.     }
  411.     template<typename Stream>
  412.     void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const
  413.     {
  414.         ::Serialize(s, getvch(), nType, nVersion);
  415.     }
  416.     template<typename Stream>
  417.     void Unserialize(Stream& s, int nType=0, int nVersion=VERSION)
  418.     {
  419.         vector<unsigned char> vch;
  420.         ::Unserialize(s, vch, nType, nVersion);
  421.         setvch(vch);
  422.     }
  423.     bool operator!() const
  424.     {
  425.         return BN_is_zero(this);
  426.     }
  427.     CBigNum& operator+=(const CBigNum& b)
  428.     {
  429.         if (!BN_add(this, this, &b))
  430.             throw bignum_error("CBigNum::operator+= : BN_add failed");
  431.         return *this;
  432.     }
  433.     CBigNum& operator-=(const CBigNum& b)
  434.     {
  435.         *this = *this - b;
  436.         return *this;
  437.     }
  438.     CBigNum& operator*=(const CBigNum& b)
  439.     {
  440.         CAutoBN_CTX pctx;
  441.         if (!BN_mul(this, this, &b, pctx))
  442.             throw bignum_error("CBigNum::operator*= : BN_mul failed");
  443.         return *this;
  444.     }
  445.     CBigNum& operator/=(const CBigNum& b)
  446.     {
  447.         *this = *this / b;
  448.         return *this;
  449.     }
  450.     CBigNum& operator%=(const CBigNum& b)
  451.     {
  452.         *this = *this % b;
  453.         return *this;
  454.     }
  455.     CBigNum& operator<<=(unsigned int shift)
  456.     {
  457.         if (!BN_lshift(this, this, shift))
  458.             throw bignum_error("CBigNum:operator<<= : BN_lshift failed");
  459.         return *this;
  460.     }
  461.     CBigNum& operator>>=(unsigned int shift)
  462.     {
  463.         if (!BN_rshift(this, this, shift))
  464.             throw bignum_error("CBigNum:operator>>= : BN_rshift failed");
  465.         return *this;
  466.     }
  467.     CBigNum& operator++()
  468.     {
  469.         if (!BN_add(this, this, BN_value_one()))
  470.             throw bignum_error("CBigNum::operator++ : BN_add failed");
  471.         return *this;
  472.     }
  473.     const CBigNum operator++(int)
  474.     {
  475.         const CBigNum ret = *this;
  476.         ++(*this);
  477.         return ret;
  478.     }
  479.     CBigNum& operator--()
  480.     {
  481.         CBigNum r;
  482.         if (!BN_sub(&r, this, BN_value_one()))
  483.             throw bignum_error("CBigNum::operator-- : BN_sub failed");
  484.         *this = r;
  485.         return *this;
  486.     }
  487.     const CBigNum operator--(int)
  488.     {
  489.         const CBigNum ret = *this;
  490.         --(*this);
  491.         return ret;
  492.     }
  493.     friend inline const CBigNum operator-(const CBigNum& a, const CBigNum& b);
  494.     friend inline const CBigNum operator/(const CBigNum& a, const CBigNum& b);
  495.     friend inline const CBigNum operator%(const CBigNum& a, const CBigNum& b);
  496. };
  497. inline const CBigNum operator+(const CBigNum& a, const CBigNum& b)
  498. {
  499.     CBigNum r;
  500.     if (!BN_add(&r, &a, &b))
  501.         throw bignum_error("CBigNum::operator+ : BN_add failed");
  502.     return r;
  503. }
  504. inline const CBigNum operator-(const CBigNum& a, const CBigNum& b)
  505. {
  506.     CBigNum r;
  507.     if (!BN_sub(&r, &a, &b))
  508.         throw bignum_error("CBigNum::operator- : BN_sub failed");
  509.     return r;
  510. }
  511. inline const CBigNum operator-(const CBigNum& a)
  512. {
  513.     CBigNum r(a);
  514.     BN_set_negative(&r, !BN_is_negative(&r));
  515.     return r;
  516. }
  517. inline const CBigNum operator*(const CBigNum& a, const CBigNum& b)
  518. {
  519.     CAutoBN_CTX pctx;
  520.     CBigNum r;
  521.     if (!BN_mul(&r, &a, &b, pctx))
  522.         throw bignum_error("CBigNum::operator* : BN_mul failed");
  523.     return r;
  524. }
  525. inline const CBigNum operator/(const CBigNum& a, const CBigNum& b)
  526. {
  527.     CAutoBN_CTX pctx;
  528.     CBigNum r;
  529.     if (!BN_div(&r, NULL, &a, &b, pctx))
  530.         throw bignum_error("CBigNum::operator/ : BN_div failed");
  531.     return r;
  532. }
  533. inline const CBigNum operator%(const CBigNum& a, const CBigNum& b)
  534. {
  535.     CAutoBN_CTX pctx;
  536.     CBigNum r;
  537.     if (!BN_mod(&r, &a, &b, pctx))
  538.         throw bignum_error("CBigNum::operator% : BN_div failed");
  539.     return r;
  540. }
  541. inline const CBigNum operator<<(const CBigNum& a, unsigned int shift)
  542. {
  543.     CBigNum r;
  544.     if (!BN_lshift(&r, &a, shift))
  545.         throw bignum_error("CBigNum:operator<< : BN_lshift failed");
  546.     return r;
  547. }
  548. inline const CBigNum operator>>(const CBigNum& a, unsigned int shift)
  549. {
  550.     CBigNum r;
  551.     if (!BN_rshift(&r, &a, shift))
  552.         throw bignum_error("CBigNum:operator>> : BN_rshift failed");
  553.     return r;
  554. }
  555. inline bool operator==(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) == 0); }
  556. inline bool operator!=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) != 0); }
  557. inline bool operator<=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) <= 0); }
  558. inline bool operator>=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) >= 0); }
  559. inline bool operator<(const CBigNum& a, const CBigNum& b)  { return (BN_cmp(&a, &b) < 0); }
  560. inline bool operator>(const CBigNum& a, const CBigNum& b)  { return (BN_cmp(&a, &b) > 0); }
  561. #include "headers.h"
  562. static CCriticalSection cs_db;
  563. static bool fDbEnvInit = false;
  564. DbEnv dbenv(0);
  565. static map<string, int> mapFileUseCount;
  566. class CDBInit
  567. {
  568. public:
  569.     CDBInit()
  570.     {
  571.     }
  572.     ~CDBInit()
  573.     {
  574.         if (fDbEnvInit)
  575.         {
  576.             dbenv.close(0);
  577.             fDbEnvInit = false;
  578.         }
  579.     }
  580. }
  581. instance_of_cdbinit;
  582. CDB::CDB(const char* pszFile, const char* pszMode, bool fTxn) : pdb(NULL)
  583. {
  584.     int ret;
  585.     if (pszFile == NULL)
  586.         return;
  587.  
  588.     bool fCreate = strchr(pszMode, 'c');
  589.     bool fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w'));
  590.     unsigned int nFlags = DB_THREAD;
  591.     if (fCreate)
  592.         nFlags |= DB_CREATE;
  593.     else if (fReadOnly)
  594.         nFlags |= DB_RDONLY;
  595.     if (!fReadOnly || fTxn)
  596.         nFlags |= DB_AUTO_COMMIT;
  597.     CRITICAL_BLOCK(cs_db)
  598.     {
  599.         if (!fDbEnvInit)
  600.         {
  601.             string strAppDir = GetAppDir();
  602.             string strLogDir = strAppDir + "\\database";
  603.             _mkdir(strLogDir.c_str());
  604.             printf("dbenv.open strAppDir=%s\n", strAppDir.c_str());
  605.             dbenv.set_lg_dir(strLogDir.c_str());
  606.             dbenv.set_lg_max(10000000);
  607.             dbenv.set_lk_max_locks(10000);
  608.             dbenv.set_lk_max_objects(10000);
  609.             dbenv.set_errfile(fopen("db.log", "a"));
  610.             ret = dbenv.open(strAppDir.c_str(),
  611.                              DB_CREATE     |
  612.                              DB_INIT_LOCK  |
  613.                              DB_INIT_LOG   |
  614.                              DB_INIT_MPOOL |
  615.                              DB_INIT_TXN   |
  616.                              DB_THREAD     |
  617.                              DB_PRIVATE    |
  618.                              DB_RECOVER,
  619.                              0);
  620.             if (ret > 0)
  621.                 throw runtime_error(strprintf("CDB() : error %d opening database environment\n", ret));
  622.             fDbEnvInit = true;
  623.         }
  624.         strFile = pszFile;
  625.         ++mapFileUseCount[strFile];
  626.     }
  627.     pdb = new Db(&dbenv, 0);
  628.     ret = pdb->open(NULL,      
  629.                     pszFile,  
  630.                     "main",    
  631.                     DB_BTREE,  
  632.                     nFlags,    
  633.                     0);
  634.     if (ret > 0)
  635.     {
  636.         delete pdb;
  637.         pdb = NULL;
  638.         CRITICAL_BLOCK(cs_db)
  639.             --mapFileUseCount[strFile];
  640.         strFile = "";
  641.         throw runtime_error(strprintf("CDB() : can't open database file %s, error %d\n", pszFile, ret));
  642.     }
  643.     if (fCreate && !Exists(string("version")))
  644.         WriteVersion(VERSION);
  645.     RandAddSeed();
  646. }
  647. void CDB::Close()
  648. {
  649.     if (!pdb)
  650.         return;
  651.     if (!vTxn.empty())
  652.         vTxn.front()->abort();
  653.     vTxn.clear();
  654.     pdb->close(0);
  655.     delete pdb;
  656.     pdb = NULL;
  657.     dbenv.txn_checkpoint(0, 0, 0);
  658.     CRITICAL_BLOCK(cs_db)
  659.         --mapFileUseCount[strFile];
  660.     RandAddSeed();
  661. }
  662. void DBFlush(bool fShutdown)
  663. {
  664.     printf("DBFlush(%s)\n", fShutdown ? "true" : "false");
  665.     CRITICAL_BLOCK(cs_db)
  666.     {
  667.         dbenv.txn_checkpoint(0, 0, 0);
  668.         map<string, int>::iterator mi = mapFileUseCount.begin();
  669.         while (mi != mapFileUseCount.end())
  670.         {
  671.             string strFile = (*mi).first;
  672.             int nRefCount = (*mi).second;
  673.             if (nRefCount == 0)
  674.             {
  675.                 dbenv.lsn_reset(strFile.c_str(), 0);
  676.                 mapFileUseCount.erase(mi++);
  677.             }
  678.             else
  679.                 mi++;
  680.         }
  681.         if (fShutdown)
  682.         {
  683.             char** listp;
  684.             if (mapFileUseCount.empty())
  685.                 dbenv.log_archive(&listp, DB_ARCH_REMOVE);
  686.             dbenv.close(0);
  687.             fDbEnvInit = false;
  688.         }
  689.     }
  690. }
  691. bool CTxDB::ReadTxIndex(uint256 hash, CTxIndex& txindex)
  692. {
  693.     assert(!fClient);
  694.     txindex.SetNull();
  695.     return Read(make_pair(string("tx"), hash), txindex);
  696. }
  697. bool CTxDB::UpdateTxIndex(uint256 hash, const CTxIndex& txindex)
  698. {
  699.     assert(!fClient);
  700.     return Write(make_pair(string("tx"), hash), txindex);
  701. }
  702. bool CTxDB::AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight)
  703. {
  704.     assert(!fClient);
  705.     uint256 hash = tx.GetHash();
  706.     CTxIndex txindex(pos, tx.vout.size());
  707.     return Write(make_pair(string("tx"), hash), txindex);
  708. }
  709. bool CTxDB::EraseTxIndex(const CTransaction& tx)
  710. {
  711.     assert(!fClient);
  712.     uint256 hash = tx.GetHash();
  713.     return Erase(make_pair(string("tx"), hash));
  714. }
  715. bool CTxDB::ContainsTx(uint256 hash)
  716. {
  717.     assert(!fClient);
  718.     return Exists(make_pair(string("tx"), hash));
  719. }
  720. bool CTxDB::ReadOwnerTxes(uint160 hash160, int nMinHeight, vector<CTransaction>& vtx)
  721. {
  722.     assert(!fClient);
  723.     vtx.clear();
  724.     Dbc* pcursor = GetCursor();
  725.     if (!pcursor)
  726.         return false;
  727.     unsigned int fFlags = DB_SET_RANGE;
  728.     loop
  729.     {
  730.         CDataStream ssKey;
  731.         if (fFlags == DB_SET_RANGE)
  732.             ssKey << string("owner") << hash160 << CDiskTxPos(0, 0, 0);
  733.         CDataStream ssValue;
  734.         int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags);
  735.         fFlags = DB_NEXT;
  736.         if (ret == DB_NOTFOUND)
  737.             break;
  738.         else if (ret != 0)
  739.             return false;
  740.         string strType;
  741.         uint160 hashItem;
  742.         CDiskTxPos pos;
  743.         ssKey >> strType >> hashItem >> pos;
  744.         int nItemHeight;
  745.         ssValue >> nItemHeight;
  746.         if (strType != "owner" || hashItem != hash160)
  747.             break;
  748.         if (nItemHeight >= nMinHeight)
  749.         {
  750.             vtx.resize(vtx.size()+1);
  751.             if (!vtx.back().ReadFromDisk(pos))
  752.                 return false;
  753.         }
  754.     }
  755.     return true;
  756. }
  757. bool CTxDB::ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex)
  758. {
  759.     assert(!fClient);
  760.     tx.SetNull();
  761.     if (!ReadTxIndex(hash, txindex))
  762.         return false;
  763.     return (tx.ReadFromDisk(txindex.pos));
  764. }
  765. bool CTxDB::ReadDiskTx(uint256 hash, CTransaction& tx)
  766. {
  767.     CTxIndex txindex;
  768.     return ReadDiskTx(hash, tx, txindex);
  769. }
  770. bool CTxDB::ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex)
  771. {
  772.     return ReadDiskTx(outpoint.hash, tx, txindex);
  773. }
  774. bool CTxDB::ReadDiskTx(COutPoint outpoint, CTransaction& tx)
  775. {
  776.     CTxIndex txindex;
  777.     return ReadDiskTx(outpoint.hash, tx, txindex);
  778. }
  779. bool CTxDB::WriteBlockIndex(const CDiskBlockIndex& blockindex)
  780. {
  781.     return Write(make_pair(string("blockindex"), blockindex.GetBlockHash()), blockindex);
  782. }
  783. bool CTxDB::EraseBlockIndex(uint256 hash)
  784. {
  785.     return Erase(make_pair(string("blockindex"), hash));
  786. }
  787. bool CTxDB::ReadHashBestChain(uint256& hashBestChain)
  788. {
  789.     return Read(string("hashBestChain"), hashBestChain);
  790. }
  791. bool CTxDB::WriteHashBestChain(uint256 hashBestChain)
  792. {
  793.     return Write(string("hashBestChain"), hashBestChain);
  794. }
  795. CBlockIndex* InsertBlockIndex(uint256 hash)
  796. {
  797.     if (hash == 0)
  798.         return NULL;
  799.     map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
  800.     if (mi != mapBlockIndex.end())
  801.         return (*mi).second;
  802.     CBlockIndex* pindexNew = new CBlockIndex();
  803.     if (!pindexNew)
  804.         throw runtime_error("LoadBlockIndex() : new CBlockIndex failed");
  805.     mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
  806.     pindexNew->phashBlock = &((*mi).first);
  807.     return pindexNew;
  808. }
  809. bool CTxDB::LoadBlockIndex()
  810. {
  811.     Dbc* pcursor = GetCursor();
  812.     if (!pcursor)
  813.         return false;
  814.     unsigned int fFlags = DB_SET_RANGE;
  815.     loop
  816.     {
  817.         CDataStream ssKey;
  818.         if (fFlags == DB_SET_RANGE)
  819.             ssKey << make_pair(string("blockindex"), uint256(0));
  820.         CDataStream ssValue;
  821.         int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags);
  822.         fFlags = DB_NEXT;
  823.         if (ret == DB_NOTFOUND)
  824.             break;
  825.         else if (ret != 0)
  826.             return false;
  827.         string strType;
  828.         ssKey >> strType;
  829.         if (strType == "blockindex")
  830.         {
  831.             CDiskBlockIndex diskindex;
  832.             ssValue >> diskindex;
  833.             CBlockIndex* pindexNew = InsertBlockIndex(diskindex.GetBlockHash());
  834.             pindexNew->pprev          = InsertBlockIndex(diskindex.hashPrev);
  835.             pindexNew->pnext          = InsertBlockIndex(diskindex.hashNext);
  836.             pindexNew->nFile          = diskindex.nFile;
  837.             pindexNew->nBlockPos      = diskindex.nBlockPos;
  838.             pindexNew->nHeight        = diskindex.nHeight;
  839.             pindexNew->nVersion       = diskindex.nVersion;
  840.             pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot;
  841.             pindexNew->nTime          = diskindex.nTime;
  842.             pindexNew->nBits          = diskindex.nBits;
  843.             pindexNew->nNonce         = diskindex.nNonce;
  844.             if (pindexGenesisBlock == NULL && diskindex.GetBlockHash() == hashGenesisBlock)
  845.                 pindexGenesisBlock = pindexNew;
  846.         }
  847.         else
  848.         {
  849.             break;
  850.         }
  851.     }
  852.     if (!ReadHashBestChain(hashBestChain))
  853.     {
  854.         if (pindexGenesisBlock == NULL)
  855.             return true;
  856.         return error("CTxDB::LoadBlockIndex() : hashBestChain not found\n");
  857.     }
  858.     if (!mapBlockIndex.count(hashBestChain))
  859.         return error("CTxDB::LoadBlockIndex() : blockindex for hashBestChain not found\n");
  860.     pindexBest = mapBlockIndex[hashBestChain];
  861.     nBestHeight = pindexBest->nHeight;
  862.     printf("LoadBlockIndex(): hashBestChain=%s  height=%d\n", hashBestChain.ToString().substr(0,14).c_str(), nBestHeight);
  863.     return true;
  864. }
  865. bool CAddrDB::WriteAddress(const CAddress& addr)
  866. {
  867.     return Write(make_pair(string("addr"), addr.GetKey()), addr);
  868. }
  869. bool CAddrDB::LoadAddresses()
  870. {
  871.     CRITICAL_BLOCK(cs_mapAddresses)
  872.     {
  873.         CAutoFile filein = fopen("addr.txt", "rt");
  874.         if (filein)
  875.         {
  876.             try
  877.             {
  878.                 char psz[1000];
  879.                 while (fgets(psz, sizeof(psz), filein))
  880.                 {
  881.                     CAddress addr(psz, NODE_NETWORK);
  882.                     if (addr.ip != 0)
  883.                         AddAddress(*this, addr);
  884.                 }
  885.             }
  886.             catch (...) { }
  887.         }
  888.         Dbc* pcursor = GetCursor();
  889.         if (!pcursor)
  890.             return false;
  891.         loop
  892.         {
  893.             CDataStream ssKey;
  894.             CDataStream ssValue;
  895.             int ret = ReadAtCursor(pcursor, ssKey, ssValue);
  896.             if (ret == DB_NOTFOUND)
  897.                 break;
  898.             else if (ret != 0)
  899.                 return false;
  900.             string strType;
  901.             ssKey >> strType;
  902.             if (strType == "addr")
  903.             {
  904.                 CAddress addr;
  905.                 ssValue >> addr;
  906.                 mapAddresses.insert(make_pair(addr.GetKey(), addr));
  907.             }
  908.         }
  909.         printf("mapAddresses:\n");
  910.         foreach(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
  911.             item.second.print();
  912.         printf("-----\n");
  913.     }
  914.     return true;
  915. }
  916. bool LoadAddresses()
  917. {
  918.     return CAddrDB("cr+").LoadAddresses();
  919. }
  920. bool CReviewDB::ReadReviews(uint256 hash, vector<CReview>& vReviews)
  921. {
  922.     vReviews.size();
  923.     return Read(make_pair(string("reviews"), hash), vReviews);
  924. }
  925. bool CReviewDB::WriteReviews(uint256 hash, const vector<CReview>& vReviews)
  926. {
  927.     return Write(make_pair(string("reviews"), hash), vReviews);
  928. }
  929. bool CWalletDB::LoadWallet(vector<unsigned char>& vchDefaultKeyRet)
  930. {
  931.     vchDefaultKeyRet.clear();
  932.     CRITICAL_BLOCK(cs_mapKeys)
  933.     CRITICAL_BLOCK(cs_mapWallet)
  934.     {
  935.         Dbc* pcursor = GetCursor();
  936.         if (!pcursor)
  937.             return false;
  938.         loop
  939.         {
  940.             CDataStream ssKey;
  941.             CDataStream ssValue;
  942.             int ret = ReadAtCursor(pcursor, ssKey, ssValue);
  943.             if (ret == DB_NOTFOUND)
  944.                 break;
  945.             else if (ret != 0)
  946.                 return false;
  947.             string strType;
  948.             ssKey >> strType;
  949.             if (strType == "name")
  950.             {
  951.                 string strAddress;
  952.                 ssKey >> strAddress;
  953.                 ssValue >> mapAddressBook[strAddress];
  954.             }
  955.             else if (strType == "tx")
  956.             {
  957.                 uint256 hash;
  958.                 ssKey >> hash;
  959.                 CWalletTx& wtx = mapWallet[hash];
  960.                 ssValue >> wtx;
  961.  
  962.                 if (wtx.GetHash() != hash)
  963.                     printf("Error in wallet.dat, hash mismatch\n");
  964.             }
  965.             else if (strType == "key")
  966.             {
  967.                 vector<unsigned char> vchPubKey;
  968.                 ssKey >> vchPubKey;
  969.                 CPrivKey vchPrivKey;
  970.                 ssValue >> vchPrivKey;
  971.                 mapKeys[vchPubKey] = vchPrivKey;
  972.                 mapPubKeys[Hash160(vchPubKey)] = vchPubKey;
  973.             }
  974.             else if (strType == "defaultkey")
  975.             {
  976.                 ssValue >> vchDefaultKeyRet;
  977.             }
  978.             else if (strType == "setting")
  979.             {
  980.                 string strKey;
  981.                 ssKey >> strKey;
  982.                 if (strKey == "fGenerateBitcoins")  ssValue >> fGenerateBitcoins;
  983.                 if (strKey == "nTransactionFee")    ssValue >> nTransactionFee;
  984.                 if (strKey == "addrIncoming")       ssValue >> addrIncoming;
  985.             }
  986.         }
  987.     }
  988.     printf("fGenerateBitcoins = %d\n", fGenerateBitcoins);
  989.     printf("nTransactionFee = %I64d\n", nTransactionFee);
  990.     printf("addrIncoming = %s\n", addrIncoming.ToString().c_str());
  991.     return true;
  992. }
  993. bool LoadWallet()
  994. {
  995.     vector<unsigned char> vchDefaultKey;
  996.     if (!CWalletDB("cr").LoadWallet(vchDefaultKey))
  997.         return false;
  998.     if (mapKeys.count(vchDefaultKey))
  999.     {
  1000.         keyUser.SetPubKey(vchDefaultKey);
  1001.         keyUser.SetPrivKey(mapKeys[vchDefaultKey]);
  1002.     }
  1003.     else
  1004.     {
  1005.         keyUser.MakeNewKey();
  1006.         if (!AddKey(keyUser))
  1007.             return false;
  1008.         if (!SetAddressBookName(PubKeyToAddress(keyUser.GetPubKey()), "Your Address"))
  1009.             return false;
  1010.         CWalletDB().WriteDefaultKey(keyUser.GetPubKey());
  1011.     }
  1012.     return true;
  1013. }
  1014. #include <db_cxx.h>
  1015. class CTransaction;
  1016. class CTxIndex;
  1017. class CDiskBlockIndex;
  1018. class CDiskTxPos;
  1019. class COutPoint;
  1020. class CUser;
  1021. class CReview;
  1022. class CAddress;
  1023. class CWalletTx;
  1024. extern map<string, string> mapAddressBook;
  1025. extern bool fClient;
  1026. extern DbEnv dbenv;
  1027. extern void DBFlush(bool fShutdown);
  1028. class CDB
  1029. {
  1030. protected:
  1031.     Db* pdb;
  1032.     string strFile;
  1033.     vector<DbTxn*> vTxn;
  1034.     explicit CDB(const char* pszFile, const char* pszMode="r+", bool fTxn=false);
  1035.     ~CDB() { Close(); }
  1036. public:
  1037.     void Close();
  1038. private:
  1039.     CDB(const CDB&);
  1040.     void operator=(const CDB&);
  1041. protected:
  1042.     template<typename K, typename T>
  1043.     bool Read(const K& key, T& value)
  1044.     {
  1045.         if (!pdb)
  1046.             return false;
  1047.         CDataStream ssKey(SER_DISK);
  1048.         ssKey.reserve(1000);
  1049.         ssKey << key;
  1050.         Dbt datKey(&ssKey[0], ssKey.size());
  1051.         Dbt datValue;
  1052.         datValue.set_flags(DB_DBT_MALLOC);
  1053.         int ret = pdb->get(GetTxn(), &datKey, &datValue, 0);
  1054.         memset(datKey.get_data(), 0, datKey.get_size());
  1055.         if (datValue.get_data() == NULL)
  1056.             return false;
  1057.         CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK);
  1058.         ssValue >> value;
  1059.         memset(datValue.get_data(), 0, datValue.get_size());
  1060.         free(datValue.get_data());
  1061.         return (ret == 0);
  1062.     }
  1063.     template<typename K, typename T>
  1064.     bool Write(const K& key, const T& value, bool fOverwrite=true)
  1065.     {
  1066.         if (!pdb)
  1067.             return false;
  1068.         CDataStream ssKey(SER_DISK);
  1069.         ssKey.reserve(1000);
  1070.         ssKey << key;
  1071.         Dbt datKey(&ssKey[0], ssKey.size());
  1072.         CDataStream ssValue(SER_DISK);
  1073.         ssValue.reserve(10000);
  1074.         ssValue << value;
  1075.         Dbt datValue(&ssValue[0], ssValue.size());
  1076.         int ret = pdb->put(GetTxn(), &datKey, &datValue, (fOverwrite ? 0 : DB_NOOVERWRITE));
  1077.         memset(datKey.get_data(), 0, datKey.get_size());
  1078.         memset(datValue.get_data(), 0, datValue.get_size());
  1079.         return (ret == 0);
  1080.     }
  1081.     template<typename K>
  1082.     bool Erase(const K& key)
  1083.     {
  1084.         if (!pdb)
  1085.             return false;
  1086.         CDataStream ssKey(SER_DISK);
  1087.         ssKey.reserve(1000);
  1088.         ssKey << key;
  1089.         Dbt datKey(&ssKey[0], ssKey.size());
  1090.         int ret = pdb->del(GetTxn(), &datKey, 0);
  1091.         memset(datKey.get_data(), 0, datKey.get_size());
  1092.         return (ret == 0 || ret == DB_NOTFOUND);
  1093.     }
  1094.     template<typename K>
  1095.     bool Exists(const K& key)
  1096.     {
  1097.         if (!pdb)
  1098.             return false;
  1099.         CDataStream ssKey(SER_DISK);
  1100.         ssKey.reserve(1000);
  1101.         ssKey << key;
  1102.         Dbt datKey(&ssKey[0], ssKey.size());
  1103.         int ret = pdb->exists(GetTxn(), &datKey, 0);
  1104.         memset(datKey.get_data(), 0, datKey.get_size());
  1105.         return (ret == 0);
  1106.     }
  1107.     Dbc* GetCursor()
  1108.     {
  1109.         if (!pdb)
  1110.             return NULL;
  1111.         Dbc* pcursor = NULL;
  1112.         int ret = pdb->cursor(NULL, &pcursor, 0);
  1113.         if (ret != 0)
  1114.             return NULL;
  1115.         return pcursor;
  1116.     }
  1117.     int ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue, unsigned int fFlags=DB_NEXT)
  1118.     {
  1119.         Dbt datKey;
  1120.         if (fFlags == DB_SET || fFlags == DB_SET_RANGE || fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)
  1121.         {
  1122.             datKey.set_data(&ssKey[0]);
  1123.             datKey.set_size(ssKey.size());
  1124.         }
  1125.         Dbt datValue;
  1126.         if (fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)
  1127.         {
  1128.             datValue.set_data(&ssValue[0]);
  1129.             datValue.set_size(ssValue.size());
  1130.         }
  1131.         datKey.set_flags(DB_DBT_MALLOC);
  1132.         datValue.set_flags(DB_DBT_MALLOC);
  1133.         int ret = pcursor->get(&datKey, &datValue, fFlags);
  1134.         if (ret != 0)
  1135.             return ret;
  1136.         else if (datKey.get_data() == NULL || datValue.get_data() == NULL)
  1137.             return 99999;
  1138.         ssKey.SetType(SER_DISK);
  1139.         ssKey.clear();
  1140.         ssKey.write((char*)datKey.get_data(), datKey.get_size());
  1141.         ssValue.SetType(SER_DISK);
  1142.         ssValue.clear();
  1143.         ssValue.write((char*)datValue.get_data(), datValue.get_size());
  1144.         memset(datKey.get_data(), 0, datKey.get_size());
  1145.         memset(datValue.get_data(), 0, datValue.get_size());
  1146.         free(datKey.get_data());
  1147.         free(datValue.get_data());
  1148.         return 0;
  1149.     }
  1150.     DbTxn* GetTxn()
  1151.     {
  1152.         if (!vTxn.empty())
  1153.             return vTxn.back();
  1154.         else
  1155.             return NULL;
  1156.     }
  1157. public:
  1158.     bool TxnBegin()
  1159.     {
  1160.         if (!pdb)
  1161.             return false;
  1162.         DbTxn* ptxn = NULL;
  1163.         int ret = dbenv.txn_begin(GetTxn(), &ptxn, 0);
  1164.         if (!ptxn || ret != 0)
  1165.             return false;
  1166.         vTxn.push_back(ptxn);
  1167.         return true;
  1168.     }
  1169.     bool TxnCommit()
  1170.     {
  1171.         if (!pdb)
  1172.             return false;
  1173.         if (vTxn.empty())
  1174.             return false;
  1175.         int ret = vTxn.back()->commit(0);
  1176.         vTxn.pop_back();
  1177.         return (ret == 0);
  1178.     }
  1179.     bool TxnAbort()
  1180.     {
  1181.         if (!pdb)
  1182.             return false;
  1183.         if (vTxn.empty())
  1184.             return false;
  1185.         int ret = vTxn.back()->abort();
  1186.         vTxn.pop_back();
  1187.         return (ret == 0);
  1188.     }
  1189.     bool ReadVersion(int& nVersion)
  1190.     {
  1191.         nVersion = 0;
  1192.         return Read(string("version"), nVersion);
  1193.     }
  1194.     bool WriteVersion(int nVersion)
  1195.     {
  1196.         return Write(string("version"), nVersion);
  1197.     }
  1198. };
  1199. class CTxDB : public CDB
  1200. {
  1201. public:
  1202.     CTxDB(const char* pszMode="r+", bool fTxn=false) : CDB(!fClient ? "blkindex.dat" : NULL, pszMode, fTxn) { }
  1203. private:
  1204.     CTxDB(const CTxDB&);
  1205.     void operator=(const CTxDB&);
  1206. public:
  1207.     bool ReadTxIndex(uint256 hash, CTxIndex& txindex);
  1208.     bool UpdateTxIndex(uint256 hash, const CTxIndex& txindex);
  1209.     bool AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight);
  1210.     bool EraseTxIndex(const CTransaction& tx);
  1211.     bool ContainsTx(uint256 hash);
  1212.     bool ReadOwnerTxes(uint160 hash160, int nHeight, vector<CTransaction>& vtx);
  1213.     bool ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex);
  1214.     bool ReadDiskTx(uint256 hash, CTransaction& tx);
  1215.     bool ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex);
  1216.     bool ReadDiskTx(COutPoint outpoint, CTransaction& tx);
  1217.     bool WriteBlockIndex(const CDiskBlockIndex& blockindex);
  1218.     bool EraseBlockIndex(uint256 hash);
  1219.     bool ReadHashBestChain(uint256& hashBestChain);
  1220.     bool WriteHashBestChain(uint256 hashBestChain);
  1221.     bool LoadBlockIndex();
  1222. };
  1223. class CReviewDB : public CDB
  1224. {
  1225. public:
  1226.     CReviewDB(const char* pszMode="r+", bool fTxn=false) : CDB("reviews.dat", pszMode, fTxn) { }
  1227. private:
  1228.     CReviewDB(const CReviewDB&);
  1229.     void operator=(const CReviewDB&);
  1230. public:
  1231.     bool ReadUser(uint256 hash, CUser& user)
  1232.     {
  1233.         return Read(make_pair(string("user"), hash), user);
  1234.     }
  1235.     bool WriteUser(uint256 hash, const CUser& user)
  1236.     {
  1237.         return Write(make_pair(string("user"), hash), user);
  1238.     }
  1239.     bool ReadReviews(uint256 hash, vector<CReview>& vReviews);
  1240.     bool WriteReviews(uint256 hash, const vector<CReview>& vReviews);
  1241. };
  1242. class CMarketDB : public CDB
  1243. {
  1244. public:
  1245.     CMarketDB(const char* pszMode="r+", bool fTxn=false) : CDB("market.dat", pszMode, fTxn) { }
  1246. private:
  1247.     CMarketDB(const CMarketDB&);
  1248.     void operator=(const CMarketDB&);
  1249. };
  1250. class CAddrDB : public CDB
  1251. {
  1252. public:
  1253.     CAddrDB(const char* pszMode="r+", bool fTxn=false) : CDB("addr.dat", pszMode, fTxn) { }
  1254. private:
  1255.     CAddrDB(const CAddrDB&);
  1256.     void operator=(const CAddrDB&);
  1257. public:
  1258.     bool WriteAddress(const CAddress& addr);
  1259.     bool LoadAddresses();
  1260. };
  1261. bool LoadAddresses();
  1262. class CWalletDB : public CDB
  1263. {
  1264. public:
  1265.     CWalletDB(const char* pszMode="r+", bool fTxn=false) : CDB("wallet.dat", pszMode, fTxn) { }
  1266. private:
  1267.     CWalletDB(const CWalletDB&);
  1268.     void operator=(const CWalletDB&);
  1269. public:
  1270.     bool ReadName(const string& strAddress, string& strName)
  1271.     {
  1272.         strName = "";
  1273.         return Read(make_pair(string("name"), strAddress), strName);
  1274.     }
  1275.     bool WriteName(const string& strAddress, const string& strName)
  1276.     {
  1277.         mapAddressBook[strAddress] = strName;
  1278.         return Write(make_pair(string("name"), strAddress), strName);
  1279.     }
  1280.     bool EraseName(const string& strAddress)
  1281.     {
  1282.         mapAddressBook.erase(strAddress);
  1283.         return Erase(make_pair(string("name"), strAddress));
  1284.     }
  1285.     bool ReadTx(uint256 hash, CWalletTx& wtx)
  1286.     {
  1287.         return Read(make_pair(string("tx"), hash), wtx);
  1288.     }
  1289.     bool WriteTx(uint256 hash, const CWalletTx& wtx)
  1290.     {
  1291.         return Write(make_pair(string("tx"), hash), wtx);
  1292.     }
  1293.     bool EraseTx(uint256 hash)
  1294.     {
  1295.         return Erase(make_pair(string("tx"), hash));
  1296.     }
  1297.     bool ReadKey(const vector<unsigned char>& vchPubKey, CPrivKey& vchPrivKey)
  1298.     {
  1299.         vchPrivKey.clear();
  1300.         return Read(make_pair(string("key"), vchPubKey), vchPrivKey);
  1301.     }
  1302.     bool WriteKey(const vector<unsigned char>& vchPubKey, const CPrivKey& vchPrivKey)
  1303.     {
  1304.         return Write(make_pair(string("key"), vchPubKey), vchPrivKey, false);
  1305.     }
  1306.     bool ReadDefaultKey(vector<unsigned char>& vchPubKey)
  1307.     {
  1308.         vchPubKey.clear();
  1309.         return Read(string("defaultkey"), vchPubKey);
  1310.     }
  1311.     bool WriteDefaultKey(const vector<unsigned char>& vchPubKey)
  1312.     {
  1313.         return Write(string("defaultkey"), vchPubKey);
  1314.     }
  1315.     template<typename T>
  1316.     bool ReadSetting(const string& strKey, T& value)
  1317.     {
  1318.         return Read(make_pair(string("setting"), strKey), value);
  1319.     }
  1320.     template<typename T>
  1321.     bool WriteSetting(const string& strKey, const T& value)
  1322.     {
  1323.         return Write(make_pair(string("setting"), strKey), value);
  1324.     }
  1325.     bool LoadWallet(vector<unsigned char>& vchDefaultKeyRet);
  1326. };
  1327. bool LoadWallet();
  1328. inline bool SetAddressBookName(const string& strAddress, const string& strName)
  1329. {
  1330.     return CWalletDB().WriteName(strAddress, strName);
  1331. }
  1332. #ifdef _MSC_VER
  1333. #pragma warning(disable:4786)
  1334. #pragma warning(disable:4804)
  1335. #pragma warning(disable:4717)
  1336. #endif
  1337. #ifdef _WIN32_WINNT
  1338. #undef _WIN32_WINNT
  1339. #endif
  1340. #define _WIN32_WINNT 0x0400
  1341. #define WIN32_LEAN_AND_MEAN 1
  1342. #include <wx/wx.h>
  1343. #include <wx/clipbrd.h>
  1344. #include <wx/snglinst.h>
  1345. #include <openssl/ecdsa.h>
  1346. #include <openssl/evp.h>
  1347. #include <openssl/rand.h>
  1348. #include <openssl/sha.h>
  1349. #include <openssl/ripemd.h>
  1350. #include <windows.h>
  1351. #include <winsock2.h>
  1352. #include <mswsock.h>
  1353. #include <stdio.h>
  1354. #include <stdlib.h>
  1355. #include <io.h>
  1356. #include <math.h>
  1357. #include <limits.h>
  1358. #include <float.h>
  1359. #include <assert.h>
  1360. #include <process.h>
  1361. #include <malloc.h>
  1362. #include <memory>
  1363. #define BOUNDSCHECK 1
  1364. #include <sstream>
  1365. #include <string>
  1366. #include <vector>
  1367. #include <list>
  1368. #include <deque>
  1369. #include <map>
  1370. #include <set>
  1371. #include <algorithm>
  1372. #include <numeric>
  1373. #include <boost/foreach.hpp>
  1374. #include <boost/lexical_cast.hpp>
  1375. #include <boost/tuple/tuple.hpp>
  1376. #include <boost/tuple/tuple_comparison.hpp>
  1377. #include <boost/tuple/tuple_io.hpp>
  1378. #include <boost/array.hpp>
  1379. #pragma hdrstop
  1380. using namespace std;
  1381. using namespace boost;
  1382. #include "serialize.h"
  1383. #include "uint256.h"
  1384. #include "util.h"
  1385. #include "key.h"
  1386. #include "bignum.h"
  1387. #include "base58.h"
  1388. #include "script.h"
  1389. #include "db.h"
  1390. #include "net.h"
  1391. #include "irc.h"
  1392. #include "main.h"
  1393. #include "market.h"
  1394. #include "uibase.h"
  1395. #include "ui.h"
  1396. #include "headers.h"
  1397. #pragma pack(1)
  1398. struct ircaddr
  1399. {
  1400.     int ip;
  1401.     short port;
  1402. };
  1403. string EncodeAddress(const CAddress& addr)
  1404. {
  1405.     struct ircaddr tmp;
  1406.     tmp.ip    = addr.ip;
  1407.     tmp.port  = addr.port;
  1408.     vector<unsigned char> vch(UBEGIN(tmp), UEND(tmp));
  1409.     return string("u") + EncodeBase58Check(vch);
  1410. }
  1411. bool DecodeAddress(string str, CAddress& addr)
  1412. {
  1413.     vector<unsigned char> vch;
  1414.     if (!DecodeBase58Check(str.substr(1), vch))
  1415.         return false;
  1416.     struct ircaddr tmp;
  1417.     if (vch.size() != sizeof(tmp))
  1418.         return false;
  1419.     memcpy(&tmp, &vch[0], sizeof(tmp));
  1420.     addr  = CAddress(tmp.ip, tmp.port);
  1421.     return true;
  1422. }
  1423. static bool Send(SOCKET hSocket, const char* pszSend)
  1424. {
  1425.     if (strstr(pszSend, "PONG") != pszSend)
  1426.         printf("SENDING: %s\n", pszSend);
  1427.     const char* psz = pszSend;
  1428.     const char* pszEnd = psz + strlen(psz);
  1429.     while (psz < pszEnd)
  1430.     {
  1431.         int ret = send(hSocket, psz, pszEnd - psz, 0);
  1432.         if (ret < 0)
  1433.             return false;
  1434.         psz += ret;
  1435.     }
  1436.     return true;
  1437. }
  1438. bool RecvLine(SOCKET hSocket, string& strLine)
  1439. {
  1440.     strLine = "";
  1441.     loop
  1442.     {
  1443.         char c;
  1444.         int nBytes = recv(hSocket, &c, 1, 0);
  1445.         if (nBytes > 0)
  1446.         {
  1447.             if (c == '\n')
  1448.                 continue;
  1449.             if (c == '\r')
  1450.                 return true;
  1451.             strLine += c;
  1452.         }
  1453.         else if (nBytes <= 0)
  1454.         {
  1455.             if (!strLine.empty())
  1456.                 return true;
  1457.             printf("IRC socket closed\n");
  1458.             return false;
  1459.         }
  1460.         else
  1461.         {
  1462.             int nErr = WSAGetLastError();
  1463.             if (nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
  1464.             {
  1465.                 printf("IRC recv failed: %d\n", nErr);
  1466.                 return false;
  1467.             }
  1468.         }
  1469.     }
  1470. }
  1471. bool RecvLineIRC(SOCKET hSocket, string& strLine)
  1472. {
  1473.     loop
  1474.     {
  1475.         bool fRet = RecvLine(hSocket, strLine);
  1476.         if (fRet)
  1477.         {
  1478.             if (fShutdown)
  1479.                 return false;
  1480.             vector<string> vWords;
  1481.             ParseString(strLine, ' ', vWords);
  1482.             if (vWords[0] == "PING")
  1483.             {
  1484.                 strLine[1] = 'O';
  1485.                 strLine += '\r';
  1486.                 Send(hSocket, strLine.c_str());
  1487.                 continue;
  1488.             }
  1489.         }
  1490.         return fRet;
  1491.     }
  1492. }
  1493. bool RecvUntil(SOCKET hSocket, const char* psz1, const char* psz2=NULL, const char* psz3=NULL)
  1494. {
  1495.     loop
  1496.     {
  1497.         string strLine;
  1498.         if (!RecvLineIRC(hSocket, strLine))
  1499.             return false;
  1500.         printf("IRC %s\n", strLine.c_str());
  1501.         if (psz1 && strLine.find(psz1) != -1)
  1502.             return true;
  1503.         if (psz2 && strLine.find(psz2) != -1)
  1504.             return true;
  1505.         if (psz3 && strLine.find(psz3) != -1)
  1506.             return true;
  1507.     }
  1508. }
  1509. bool fRestartIRCSeed = false;
  1510. void ThreadIRCSeed(void* parg)
  1511. {
  1512.     loop
  1513.     {
  1514.         struct hostent* phostent = gethostbyname("chat.freenode.net");
  1515.         CAddress addrConnect(*(u_long*)phostent->h_addr_list[0], htons(6667));
  1516.         SOCKET hSocket;
  1517.         if (!ConnectSocket(addrConnect, hSocket))
  1518.         {
  1519.             printf("IRC connect failed\n");
  1520.             return;
  1521.         }
  1522.         if (!RecvUntil(hSocket, "Found your hostname", "using your IP address instead", "Couldn't look up your hostname"))
  1523.         {
  1524.             closesocket(hSocket);
  1525.             return;
  1526.         }
  1527.         string strMyName = EncodeAddress(addrLocalHost);
  1528.         if (!addrLocalHost.IsRoutable())
  1529.             strMyName = strprintf("x%u", GetRand(1000000000));
  1530.         Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str());
  1531.         Send(hSocket, strprintf("USER %s 8 * : %s\r", strMyName.c_str(), strMyName.c_str()).c_str());
  1532.         if (!RecvUntil(hSocket, " 004 "))
  1533.         {
  1534.             closesocket(hSocket);
  1535.             return;
  1536.         }
  1537.         Sleep(500);
  1538.         Send(hSocket, "JOIN #bitcoin\r");
  1539.         Send(hSocket, "WHO #bitcoin\r");
  1540.         while (!fRestartIRCSeed)
  1541.         {
  1542.             string strLine;
  1543.             if (fShutdown || !RecvLineIRC(hSocket, strLine))
  1544.             {
  1545.                 closesocket(hSocket);
  1546.                 return;
  1547.             }
  1548.             if (strLine.empty() || strLine[0] != ':')
  1549.                 continue;
  1550.             printf("IRC %s\n", strLine.c_str());
  1551.             vector<string> vWords;
  1552.             ParseString(strLine, ' ', vWords);
  1553.             if (vWords.size() < 2)
  1554.                 continue;
  1555.             char pszName[10000];
  1556.             pszName[0] = '\0';
  1557.             if (vWords[1] == "352" && vWords.size() >= 8)
  1558.             {            
  1559.                 strcpy(pszName, vWords[7].c_str());
  1560.                 printf("GOT WHO: [%s]  ", pszName);
  1561.             }
  1562.             if (vWords[1] == "JOIN")
  1563.             {
  1564.                 strcpy(pszName, vWords[0].c_str() + 1);
  1565.                 if (strchr(pszName, '!'))
  1566.                     *strchr(pszName, '!') = '\0';
  1567.                 printf("GOT JOIN: [%s]  ", pszName);
  1568.             }
  1569.             if (pszName[0] == 'u')
  1570.             {
  1571.                 CAddress addr;
  1572.                 if (DecodeAddress(pszName, addr))
  1573.                 {
  1574.                     CAddrDB addrdb;
  1575.                     if (AddAddress(addrdb, addr))
  1576.                         printf("new  ");
  1577.                     addr.print();
  1578.                 }
  1579.                 else
  1580.                 {
  1581.                     printf("decode failed\n");
  1582.                 }
  1583.             }
  1584.         }
  1585.         fRestartIRCSeed = false;
  1586.         closesocket(hSocket);
  1587.     }
  1588. }
  1589. #ifdef TEST
  1590. int main(int argc, char *argv[])
  1591. {
  1592.     WSADATA wsadata;
  1593.     if (WSAStartup(MAKEWORD(2,2), &wsadata) != NO_ERROR)
  1594.     {
  1595.         printf("Error at WSAStartup()\n");
  1596.         return false;
  1597.     }
  1598.     ThreadIRCSeed(NULL);
  1599.     WSACleanup();
  1600.     return 0;
  1601. }
  1602. #endif
  1603. extern bool RecvLine(SOCKET hSocket, string& strLine);
  1604. extern void ThreadIRCSeed(void* parg);
  1605. extern bool fRestartIRCSeed;
  1606. class key_error : public std::runtime_error
  1607. {
  1608. public:
  1609.     explicit key_error(const std::string& str) : std::runtime_error(str) {}
  1610. };
  1611. typedef vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
  1612. class CKey
  1613. {
  1614. protected:
  1615.     EC_KEY* pkey;
  1616. public:
  1617.     CKey()
  1618.     {
  1619.         pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
  1620.         if (pkey == NULL)
  1621.             throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed");
  1622.     }
  1623.     CKey(const CKey& b)
  1624.     {
  1625.         pkey = EC_KEY_dup(b.pkey);
  1626.         if (pkey == NULL)
  1627.             throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed");
  1628.     }
  1629.     CKey& operator=(const CKey& b)
  1630.     {
  1631.         if (!EC_KEY_copy(pkey, b.pkey))
  1632.             throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed");
  1633.         return (*this);
  1634.     }
  1635.     ~CKey()
  1636.     {
  1637.         EC_KEY_free(pkey);
  1638.     }
  1639.     void MakeNewKey()
  1640.     {
  1641.         if (!EC_KEY_generate_key(pkey))
  1642.             throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed");
  1643.     }
  1644.     bool SetPrivKey(const CPrivKey& vchPrivKey)
  1645.     {
  1646.         const unsigned char* pbegin = &vchPrivKey[0];
  1647.         if (!d2i_ECPrivateKey(&pkey, &pbegin, vchPrivKey.size()))
  1648.             return false;
  1649.         return true;
  1650.     }
  1651.     CPrivKey GetPrivKey() const
  1652.     {
  1653.         unsigned int nSize = i2d_ECPrivateKey(pkey, NULL);
  1654.         if (!nSize)
  1655.             throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey failed");
  1656.         CPrivKey vchPrivKey(nSize, 0);
  1657.         unsigned char* pbegin = &vchPrivKey[0];
  1658.         if (i2d_ECPrivateKey(pkey, &pbegin) != nSize)
  1659.             throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey returned unexpected size");
  1660.         return vchPrivKey;
  1661.     }
  1662.     bool SetPubKey(const vector<unsigned char>& vchPubKey)
  1663.     {
  1664.         const unsigned char* pbegin = &vchPubKey[0];
  1665.         if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size()))
  1666.             return false;
  1667.         return true;
  1668.     }
  1669.     vector<unsigned char> GetPubKey() const
  1670.     {
  1671.         unsigned int nSize = i2o_ECPublicKey(pkey, NULL);
  1672.         if (!nSize)
  1673.             throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed");
  1674.         vector<unsigned char> vchPubKey(nSize, 0);
  1675.         unsigned char* pbegin = &vchPubKey[0];
  1676.         if (i2o_ECPublicKey(pkey, &pbegin) != nSize)
  1677.             throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size");
  1678.         return vchPubKey;
  1679.     }
  1680.     bool Sign(uint256 hash, vector<unsigned char>& vchSig)
  1681.     {
  1682.         vchSig.clear();
  1683.         unsigned char pchSig[10000];
  1684.         unsigned int nSize = 0;
  1685.         if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), pchSig, &nSize, pkey))
  1686.             return false;
  1687.         vchSig.resize(nSize);
  1688.         memcpy(&vchSig[0], pchSig, nSize);
  1689.         return true;
  1690.     }
  1691.     bool Verify(uint256 hash, const vector<unsigned char>& vchSig)
  1692.     {
  1693.         if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1)
  1694.             return false;
  1695.         return true;
  1696.     }
  1697.     static bool Sign(const CPrivKey& vchPrivKey, uint256 hash, vector<unsigned char>& vchSig)
  1698.     {
  1699.         CKey key;
  1700.         if (!key.SetPrivKey(vchPrivKey))
  1701.             return false;
  1702.         return key.Sign(hash, vchSig);
  1703.     }
  1704.     static bool Verify(const vector<unsigned char>& vchPubKey, uint256 hash, const vector<unsigned char>& vchSig)
  1705.     {
  1706.         CKey key;
  1707.         if (!key.SetPubKey(vchPubKey))
  1708.             return false;
  1709.         return key.Verify(hash, vchSig);
  1710.     }
  1711. };
  1712. #include "headers.h"
  1713. #include "sha.h"
  1714. CCriticalSection cs_main;
  1715. map<uint256, CTransaction> mapTransactions;
  1716. CCriticalSection cs_mapTransactions;
  1717. unsigned int nTransactionsUpdated = 0;
  1718. map<COutPoint, CInPoint> mapNextTx;
  1719. map<uint256, CBlockIndex*> mapBlockIndex;
  1720. const uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f");
  1721. CBlockIndex* pindexGenesisBlock = NULL;
  1722. int nBestHeight = -1;
  1723. uint256 hashBestChain = 0;
  1724. CBlockIndex* pindexBest = NULL;
  1725. map<uint256, CBlock*> mapOrphanBlocks;
  1726. multimap<uint256, CBlock*> mapOrphanBlocksByPrev;
  1727. map<uint256, CDataStream*> mapOrphanTransactions;
  1728. multimap<uint256, CDataStream*> mapOrphanTransactionsByPrev;
  1729. map<uint256, CWalletTx> mapWallet;
  1730. vector<pair<uint256, bool> > vWalletUpdated;
  1731. CCriticalSection cs_mapWallet;
  1732. map<vector<unsigned char>, CPrivKey> mapKeys;
  1733. map<uint160, vector<unsigned char> > mapPubKeys;
  1734. CCriticalSection cs_mapKeys;
  1735. CKey keyUser;
  1736. string strSetDataDir;
  1737. int nDropMessagesTest = 0;
  1738. int fGenerateBitcoins;
  1739. int64 nTransactionFee = 0;
  1740. CAddress addrIncoming;
  1741. bool AddKey(const CKey& key)
  1742. {
  1743.     CRITICAL_BLOCK(cs_mapKeys)
  1744.     {
  1745.         mapKeys[key.GetPubKey()] = key.GetPrivKey();
  1746.         mapPubKeys[Hash160(key.GetPubKey())] = key.GetPubKey();
  1747.     }
  1748.     return CWalletDB().WriteKey(key.GetPubKey(), key.GetPrivKey());
  1749. }
  1750. vector<unsigned char> GenerateNewKey()
  1751. {
  1752.     CKey key;
  1753.     key.MakeNewKey();
  1754.     if (!AddKey(key))
  1755.         throw runtime_error("GenerateNewKey() : AddKey failed\n");
  1756.     return key.GetPubKey();
  1757. }
  1758. bool AddToWallet(const CWalletTx& wtxIn)
  1759. {
  1760.     uint256 hash = wtxIn.GetHash();
  1761.     CRITICAL_BLOCK(cs_mapWallet)
  1762.     {
  1763.         pair<map<uint256, CWalletTx>::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn));
  1764.         CWalletTx& wtx = (*ret.first).second;
  1765.         bool fInsertedNew = ret.second;
  1766.         if (fInsertedNew)
  1767.             wtx.nTimeReceived = GetAdjustedTime();
  1768.         printf("AddToWallet %s  %s\n", wtxIn.GetHash().ToString().substr(0,6).c_str(), fInsertedNew ? "new" : "update");
  1769.         if (!fInsertedNew)
  1770.         {
  1771.             bool fUpdated = false;
  1772.             if (wtxIn.hashBlock != 0 && wtxIn.hashBlock != wtx.hashBlock)
  1773.             {
  1774.                 wtx.hashBlock = wtxIn.hashBlock;
  1775.                 fUpdated = true;
  1776.             }
  1777.             if (wtxIn.nIndex != -1 && (wtxIn.vMerkleBranch != wtx.vMerkleBranch || wtxIn.nIndex != wtx.nIndex))
  1778.             {
  1779.                 wtx.vMerkleBranch = wtxIn.vMerkleBranch;
  1780.                 wtx.nIndex = wtxIn.nIndex;
  1781.                 fUpdated = true;
  1782.             }
  1783.             if (wtxIn.fFromMe && wtxIn.fFromMe != wtx.fFromMe)
  1784.             {
  1785.                 wtx.fFromMe = wtxIn.fFromMe;
  1786.                 fUpdated = true;
  1787.             }
  1788.             if (wtxIn.fSpent && wtxIn.fSpent != wtx.fSpent)
  1789.             {
  1790.                 wtx.fSpent = wtxIn.fSpent;
  1791.                 fUpdated = true;
  1792.             }
  1793.             if (!fUpdated)
  1794.                 return true;
  1795.         }
  1796.         if (!wtx.WriteToDisk())
  1797.             return false;
  1798.         vWalletUpdated.push_back(make_pair(hash, fInsertedNew));
  1799.     }
  1800.     MainFrameRepaint();
  1801.     return true;
  1802. }
  1803. bool AddToWalletIfMine(const CTransaction& tx, const CBlock* pblock)
  1804. {
  1805.     if (tx.IsMine() || mapWallet.count(tx.GetHash()))
  1806.     {
  1807.         CWalletTx wtx(tx);
  1808.         if (pblock)
  1809.             wtx.SetMerkleBranch(pblock);
  1810.         return AddToWallet(wtx);
  1811.     }
  1812.     return true;
  1813. }
  1814. bool EraseFromWallet(uint256 hash)
  1815. {
  1816.     CRITICAL_BLOCK(cs_mapWallet)
  1817.     {
  1818.         if (mapWallet.erase(hash))
  1819.             CWalletDB().EraseTx(hash);
  1820.     }
  1821.     return true;
  1822. }
  1823. void AddOrphanTx(const CDataStream& vMsg)
  1824. {
  1825.     CTransaction tx;
  1826.     CDataStream(vMsg) >> tx;
  1827.     uint256 hash = tx.GetHash();
  1828.     if (mapOrphanTransactions.count(hash))
  1829.         return;
  1830.     CDataStream* pvMsg = mapOrphanTransactions[hash] = new CDataStream(vMsg);
  1831.     foreach(const CTxIn& txin, tx.vin)
  1832.         mapOrphanTransactionsByPrev.insert(make_pair(txin.prevout.hash, pvMsg));
  1833. }
  1834. void EraseOrphanTx(uint256 hash)
  1835. {
  1836.     if (!mapOrphanTransactions.count(hash))
  1837.         return;
  1838.     const CDataStream* pvMsg = mapOrphanTransactions[hash];
  1839.     CTransaction tx;
  1840.     CDataStream(*pvMsg) >> tx;
  1841.     foreach(const CTxIn& txin, tx.vin)
  1842.     {
  1843.         for (multimap<uint256, CDataStream*>::iterator mi = mapOrphanTransactionsByPrev.lower_bound(txin.prevout.hash);
  1844.              mi != mapOrphanTransactionsByPrev.upper_bound(txin.prevout.hash);)
  1845.         {
  1846.             if ((*mi).second == pvMsg)
  1847.                 mapOrphanTransactionsByPrev.erase(mi++);
  1848.             else
  1849.                 mi++;
  1850.         }
  1851.     }
  1852.     delete pvMsg;
  1853.     mapOrphanTransactions.erase(hash);
  1854. }
  1855. bool CTxIn::IsMine() const
  1856. {
  1857.     CRITICAL_BLOCK(cs_mapWallet)
  1858.     {
  1859.         map<uint256, CWalletTx>::iterator mi = mapWallet.find(prevout.hash);
  1860.         if (mi != mapWallet.end())
  1861.         {
  1862.             const CWalletTx& prev = (*mi).second;
  1863.             if (prevout.n < prev.vout.size())
  1864.                 if (prev.vout[prevout.n].IsMine())
  1865.                     return true;
  1866.         }
  1867.     }
  1868.     return false;
  1869. }
  1870. int64 CTxIn::GetDebit() const
  1871. {
  1872.     CRITICAL_BLOCK(cs_mapWallet)
  1873.     {
  1874.         map<uint256, CWalletTx>::iterator mi = mapWallet.find(prevout.hash);
  1875.         if (mi != mapWallet.end())
  1876.         {
  1877.             const CWalletTx& prev = (*mi).second;
  1878.             if (prevout.n < prev.vout.size())
  1879.                 if (prev.vout[prevout.n].IsMine())
  1880.                     return prev.vout[prevout.n].nValue;
  1881.         }
  1882.     }
  1883.     return 0;
  1884. }
  1885. int64 CWalletTx::GetTxTime() const
  1886. {
  1887.     if (!fTimeReceivedIsTxTime && hashBlock != 0)
  1888.     {
  1889.         map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
  1890.         if (mi != mapBlockIndex.end())
  1891.         {
  1892.             CBlockIndex* pindex = (*mi).second;
  1893.             if (pindex)
  1894.                 return pindex->GetMedianTime();
  1895.         }
  1896.     }
  1897.     return nTimeReceived;
  1898. }
  1899. int CMerkleTx::SetMerkleBranch(const CBlock* pblock)
  1900. {
  1901.     if (fClient)
  1902.     {
  1903.         if (hashBlock == 0)
  1904.             return 0;
  1905.     }
  1906.     else
  1907.     {
  1908.         CBlock blockTmp;
  1909.         if (pblock == NULL)
  1910.         {
  1911.             CTxIndex txindex;
  1912.             if (!CTxDB("r").ReadTxIndex(GetHash(), txindex))
  1913.                 return 0;
  1914.             if (!blockTmp.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, true))
  1915.                 return 0;
  1916.             pblock = &blockTmp;
  1917.         }
  1918.         hashBlock = pblock->GetHash();
  1919.         for (nIndex = 0; nIndex < pblock->vtx.size(); nIndex++)
  1920.             if (pblock->vtx[nIndex] == *(CTransaction*)this)
  1921.                 break;
  1922.         if (nIndex == pblock->vtx.size())
  1923.         {
  1924.             vMerkleBranch.clear();
  1925.             nIndex = -1;
  1926.             printf("ERROR: SetMerkleBranch() : couldn't find tx in block\n");
  1927.             return 0;
  1928.         }
  1929.         vMerkleBranch = pblock->GetMerkleBranch(nIndex);
  1930.     }
  1931.     map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
  1932.     if (mi == mapBlockIndex.end())
  1933.         return 0;
  1934.     CBlockIndex* pindex = (*mi).second;
  1935.     if (!pindex || !pindex->IsInMainChain())
  1936.         return 0;
  1937.     return pindexBest->nHeight - pindex->nHeight + 1;
  1938. }
  1939. void CWalletTx::AddSupportingTransactions(CTxDB& txdb)
  1940. {
  1941.     vtxPrev.clear();
  1942.     const int COPY_DEPTH = 3;
  1943.     if (SetMerkleBranch() < COPY_DEPTH)
  1944.     {
  1945.         vector<uint256> vWorkQueue;
  1946.         foreach(const CTxIn& txin, vin)
  1947.         vWorkQueue.push_back(txin.prevout.hash);
  1948.         CRITICAL_BLOCK(cs_mapWallet)
  1949.         {
  1950.             map<uint256, const CMerkleTx*> mapWalletPrev;
  1951.             set<uint256> setAlreadyDone;
  1952.             for (int i = 0; i < vWorkQueue.size(); i++)
  1953.             {
  1954.                 uint256 hash = vWorkQueue[i];
  1955.                 if (setAlreadyDone.count(hash))
  1956.                     continue;
  1957.                 setAlreadyDone.insert(hash);
  1958.                 CMerkleTx tx;
  1959.                 if (mapWallet.count(hash))
  1960.                 {
  1961.                     tx = mapWallet[hash];
  1962.                     foreach(const CMerkleTx& txWalletPrev, mapWallet[hash].vtxPrev)
  1963.                         mapWalletPrev[txWalletPrev.GetHash()] = &txWalletPrev;
  1964.                 }
  1965.                 else if (mapWalletPrev.count(hash))
  1966.                 {
  1967.                     tx = *mapWalletPrev[hash];
  1968.                 }
  1969.                 else if (!fClient && txdb.ReadDiskTx(hash, tx))
  1970.                 {
  1971.                     ;
  1972.                 }
  1973.                 else
  1974.                 {
  1975.                     printf("ERROR: AddSupportingTransactions() : unsupported transaction\n");
  1976.                     continue;
  1977.                 }
  1978.                 int nDepth = tx.SetMerkleBranch();
  1979.                 vtxPrev.push_back(tx);
  1980.                 if (nDepth < COPY_DEPTH)
  1981.                     foreach(const CTxIn& txin, tx.vin)
  1982.                         vWorkQueue.push_back(txin.prevout.hash);
  1983.             }
  1984.         }
  1985.     }
  1986.     reverse(vtxPrev.begin(), vtxPrev.end());
  1987. }
  1988. bool CTransaction::AcceptTransaction(CTxDB& txdb, bool fCheckInputs, bool* pfMissingInputs)
  1989. {
  1990.     if (pfMissingInputs)
  1991.         *pfMissingInputs = false;
  1992.     if (IsCoinBase())
  1993.         return error("AcceptTransaction() : coinbase as individual tx");
  1994.     if (!CheckTransaction())
  1995.         return error("AcceptTransaction() : CheckTransaction failed");
  1996.     uint256 hash = GetHash();
  1997.     CRITICAL_BLOCK(cs_mapTransactions)
  1998.         if (mapTransactions.count(hash))
  1999.             return false;
  2000.     if (fCheckInputs)
  2001.         if (txdb.ContainsTx(hash))
  2002.             return false;
  2003.     CTransaction* ptxOld = NULL;
  2004.     for (int i = 0; i < vin.size(); i++)
  2005.     {
  2006.         COutPoint outpoint = vin[i].prevout;
  2007.         if (mapNextTx.count(outpoint))
  2008.         {
  2009.             if (i != 0)
  2010.                 return false;
  2011.             ptxOld = mapNextTx[outpoint].ptx;
  2012.             if (!IsNewerThan(*ptxOld))
  2013.                 return false;
  2014.             for (int i = 0; i < vin.size(); i++)
  2015.             {
  2016.                 COutPoint outpoint = vin[i].prevout;
  2017.                 if (!mapNextTx.count(outpoint) || mapNextTx[outpoint].ptx != ptxOld)
  2018.                     return false;
  2019.             }
  2020.             break;
  2021.         }
  2022.     }
  2023.     map<uint256, CTxIndex> mapUnused;
  2024.     int64 nFees = 0;
  2025.     if (fCheckInputs && !ConnectInputs(txdb, mapUnused, CDiskTxPos(1,1,1), 0, nFees, false, false))
  2026.     {
  2027.         if (pfMissingInputs)
  2028.             *pfMissingInputs = true;
  2029.         return error("AcceptTransaction() : ConnectInputs failed %s", hash.ToString().substr(0,6).c_str());
  2030.     }
  2031.     CRITICAL_BLOCK(cs_mapTransactions)
  2032.     {
  2033.         if (ptxOld)
  2034.         {
  2035.             printf("mapTransaction.erase(%s) replacing with new version\n", ptxOld->GetHash().ToString().c_str());
  2036.             mapTransactions.erase(ptxOld->GetHash());
  2037.         }
  2038.         AddToMemoryPool();
  2039.     }
  2040.     if (ptxOld)
  2041.         EraseFromWallet(ptxOld->GetHash());
  2042.     printf("AcceptTransaction(): accepted %s\n", hash.ToString().substr(0,6).c_str());
  2043.     return true;
  2044. }
  2045. bool CTransaction::AddToMemoryPool()
  2046. {
  2047.     CRITICAL_BLOCK(cs_mapTransactions)
  2048.     {
  2049.         uint256 hash = GetHash();
  2050.         mapTransactions[hash] = *this;
  2051.         for (int i = 0; i < vin.size(); i++)
  2052.             mapNextTx[vin[i].prevout] = CInPoint(&mapTransactions[hash], i);
  2053.         nTransactionsUpdated++;
  2054.     }
  2055.     return true;
  2056. }
  2057. bool CTransaction::RemoveFromMemoryPool()
  2058. {
  2059.     CRITICAL_BLOCK(cs_mapTransactions)
  2060.     {
  2061.         foreach(const CTxIn& txin, vin)
  2062.             mapNextTx.erase(txin.prevout);
  2063.         mapTransactions.erase(GetHash());
  2064.         nTransactionsUpdated++;
  2065.     }
  2066.     return true;
  2067. }
  2068. int CMerkleTx::GetDepthInMainChain() const
  2069. {
  2070.     if (hashBlock == 0 || nIndex == -1)
  2071.         return 0;
  2072.     map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
  2073.     if (mi == mapBlockIndex.end())
  2074.         return 0;
  2075.     CBlockIndex* pindex = (*mi).second;
  2076.     if (!pindex || !pindex->IsInMainChain())
  2077.         return 0;
  2078.     if (!fMerkleVerified)
  2079.     {
  2080.         if (CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex) != pindex->hashMerkleRoot)
  2081.             return 0;
  2082.         fMerkleVerified = true;
  2083.     }
  2084.     return pindexBest->nHeight - pindex->nHeight + 1;
  2085. }
  2086. int CMerkleTx::GetBlocksToMaturity() const
  2087. {
  2088.     if (!IsCoinBase())
  2089.         return 0;
  2090.     return max(0, (COINBASE_MATURITY+20) - GetDepthInMainChain());
  2091. }
  2092. bool CMerkleTx::AcceptTransaction(CTxDB& txdb, bool fCheckInputs)
  2093. {
  2094.     if (fClient)
  2095.     {
  2096.         if (!IsInMainChain() && !ClientConnectInputs())
  2097.             return false;
  2098.         return CTransaction::AcceptTransaction(txdb, false);
  2099.     }
  2100.     else
  2101.     {
  2102.         return CTransaction::AcceptTransaction(txdb, fCheckInputs);
  2103.     }
  2104. }
  2105. bool CWalletTx::AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs)
  2106. {
  2107.     CRITICAL_BLOCK(cs_mapTransactions)
  2108.     {
  2109.         foreach(CMerkleTx& tx, vtxPrev)
  2110.         {
  2111.             if (!tx.IsCoinBase())
  2112.             {
  2113.                 uint256 hash = tx.GetHash();
  2114.                 if (!mapTransactions.count(hash) && !txdb.ContainsTx(hash))
  2115.                     tx.AcceptTransaction(txdb, fCheckInputs);
  2116.             }
  2117.         }
  2118.         if (!IsCoinBase())
  2119.             return AcceptTransaction(txdb, fCheckInputs);
  2120.     }
  2121.     return true;
  2122. }
  2123. void ReacceptWalletTransactions()
  2124. {
  2125.     CTxDB txdb("r");
  2126.     CRITICAL_BLOCK(cs_mapWallet)
  2127.     {
  2128.         foreach(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
  2129.         {
  2130.             CWalletTx& wtx = item.second;
  2131.             if (!wtx.IsCoinBase() && !txdb.ContainsTx(wtx.GetHash()))
  2132.                 wtx.AcceptWalletTransaction(txdb, false);
  2133.         }
  2134.     }
  2135. }
  2136. void CWalletTx::RelayWalletTransaction(CTxDB& txdb)
  2137. {
  2138.     foreach(const CMerkleTx& tx, vtxPrev)
  2139.     {
  2140.         if (!tx.IsCoinBase())
  2141.         {
  2142.             uint256 hash = tx.GetHash();
  2143.             if (!txdb.ContainsTx(hash))
  2144.                 RelayMessage(CInv(MSG_TX, hash), (CTransaction)tx);
  2145.         }
  2146.     }
  2147.     if (!IsCoinBase())
  2148.     {
  2149.         uint256 hash = GetHash();
  2150.         if (!txdb.ContainsTx(hash))
  2151.         {
  2152.             printf("Relaying wtx %s\n", hash.ToString().substr(0,6).c_str());
  2153.             RelayMessage(CInv(MSG_TX, hash), (CTransaction)*this);
  2154.         }
  2155.     }
  2156. }
  2157. void RelayWalletTransactions()
  2158. {
  2159.     static int64 nLastTime;
  2160.     if (GetTime() - nLastTime < 10 * 60)
  2161.         return;
  2162.     nLastTime = GetTime();
  2163.     printf("RelayWalletTransactions()\n");
  2164.     CTxDB txdb("r");
  2165.     CRITICAL_BLOCK(cs_mapWallet)
  2166.     {
  2167.         multimap<unsigned int, CWalletTx*> mapSorted;
  2168.         foreach(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
  2169.         {
  2170.             CWalletTx& wtx = item.second;
  2171.             mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx));
  2172.         }
  2173.         foreach(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted)
  2174.         {
  2175.             CWalletTx& wtx = *item.second;
  2176.             wtx.RelayWalletTransaction(txdb);
  2177.         }
  2178.     }
  2179. }
  2180. bool CBlock::ReadFromDisk(const CBlockIndex* pblockindex, bool fReadTransactions)
  2181. {
  2182.     return ReadFromDisk(pblockindex->nFile, pblockindex->nBlockPos, fReadTransactions);
  2183. }
  2184. uint256 GetOrphanRoot(const CBlock* pblock)
  2185. {
  2186.     while (mapOrphanBlocks.count(pblock->hashPrevBlock))
  2187.         pblock = mapOrphanBlocks[pblock->hashPrevBlock];
  2188.     return pblock->GetHash();
  2189. }
  2190. int64 CBlock::GetBlockValue(int64 nFees) const
  2191. {
  2192.     int64 nSubsidy = 50 * COIN;
  2193.     nSubsidy >>= (nBestHeight / 210000);
  2194.     return nSubsidy + nFees;
  2195. }
  2196. unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast)
  2197. {
  2198.     const unsigned int nTargetTimespan = 14 * 24 * 60 * 60;
  2199.     const unsigned int nTargetSpacing = 10 * 60;
  2200.     const unsigned int nInterval = nTargetTimespan / nTargetSpacing;
  2201.     if (pindexLast == NULL)
  2202.         return bnProofOfWorkLimit.GetCompact();
  2203.     if ((pindexLast->nHeight+1) % nInterval != 0)
  2204.         return pindexLast->nBits;
  2205.     const CBlockIndex* pindexFirst = pindexLast;
  2206.     for (int i = 0; pindexFirst && i < nInterval-1; i++)
  2207.         pindexFirst = pindexFirst->pprev;
  2208.     assert(pindexFirst);
  2209.     unsigned int nActualTimespan = pindexLast->nTime - pindexFirst->nTime;
  2210.     printf("  nActualTimespan = %d  before bounds\n", nActualTimespan);
  2211.     if (nActualTimespan < nTargetTimespan/4)
  2212.         nActualTimespan = nTargetTimespan/4;
  2213.     if (nActualTimespan > nTargetTimespan*4)
  2214.         nActualTimespan = nTargetTimespan*4;
  2215.     CBigNum bnNew;
  2216.     bnNew.SetCompact(pindexLast->nBits);
  2217.     bnNew *= nActualTimespan;
  2218.     bnNew /= nTargetTimespan;
  2219.     if (bnNew > bnProofOfWorkLimit)
  2220.         bnNew = bnProofOfWorkLimit;
  2221.     printf("\n\n\nGetNextWorkRequired RETARGET *****\n");
  2222.     printf("nTargetTimespan = %d    nActualTimespan = %d\n", nTargetTimespan, nActualTimespan);
  2223.     printf("Before: %08x  %s\n", pindexLast->nBits, CBigNum().SetCompact(pindexLast->nBits).getuint256().ToString().c_str());
  2224.     printf("After:  %08x  %s\n", bnNew.GetCompact(), bnNew.getuint256().ToString().c_str());
  2225.     return bnNew.GetCompact();
  2226. }
  2227. bool CTransaction::DisconnectInputs(CTxDB& txdb)
  2228. {
  2229.     if (!IsCoinBase())
  2230.     {
  2231.         foreach(const CTxIn& txin, vin)
  2232.         {
  2233.             COutPoint prevout = txin.prevout;
  2234.             CTxIndex txindex;
  2235.             if (!txdb.ReadTxIndex(prevout.hash, txindex))
  2236.                 return error("DisconnectInputs() : ReadTxIndex failed");
  2237.             if (prevout.n >= txindex.vSpent.size())
  2238.                 return error("DisconnectInputs() : prevout.n out of range");
  2239.             txindex.vSpent[prevout.n].SetNull();
  2240.             txdb.UpdateTxIndex(prevout.hash, txindex);
  2241.         }
  2242.     }
  2243.     if (!txdb.EraseTxIndex(*this))
  2244.         return error("DisconnectInputs() : EraseTxPos failed");
  2245.     return true;
  2246. }
  2247. bool CTransaction::ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPool, CDiskTxPos posThisTx, int nHeight, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee)
  2248. {
  2249.     if (!IsCoinBase())
  2250.     {
  2251.         int64 nValueIn = 0;
  2252.         for (int i = 0; i < vin.size(); i++)
  2253.         {
  2254.             COutPoint prevout = vin[i].prevout;
  2255.             CTxIndex txindex;
  2256.             bool fFound = true;
  2257.             if (fMiner && mapTestPool.count(prevout.hash))
  2258.             {
  2259.                 txindex = mapTestPool[prevout.hash];
  2260.             }
  2261.             else
  2262.             {
  2263.                 fFound = txdb.ReadTxIndex(prevout.hash, txindex);
  2264.             }
  2265.             if (!fFound && (fBlock || fMiner))
  2266.                 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());
  2267.             CTransaction txPrev;
  2268.             if (!fFound || txindex.pos == CDiskTxPos(1,1,1))
  2269.             {
  2270.                 CRITICAL_BLOCK(cs_mapTransactions)
  2271.                 {
  2272.                     if (!mapTransactions.count(prevout.hash))
  2273.                         return error("ConnectInputs() : %s mapTransactions prev not found %s", GetHash().ToString().substr(0,6).c_str(),  prevout.hash.ToString().substr(0,6).c_str());
  2274.                     txPrev = mapTransactions[prevout.hash];
  2275.                 }
  2276.                 if (!fFound)
  2277.                     txindex.vSpent.resize(txPrev.vout.size());
  2278.             }
  2279.             else
  2280.             {
  2281.                 if (!txPrev.ReadFromDisk(txindex.pos))
  2282.                     return error("ConnectInputs() : %s ReadFromDisk prev tx %s failed", GetHash().ToString().substr(0,6).c_str(),  prevout.hash.ToString().substr(0,6).c_str());
  2283.             }
  2284.             if (prevout.n >= txPrev.vout.size() || prevout.n >= txindex.vSpent.size())
  2285.                 return error("ConnectInputs() : %s prevout.n out of range %d %d %d", GetHash().ToString().substr(0,6).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size());
  2286.             if (txPrev.IsCoinBase())
  2287.                 for (CBlockIndex* pindex = pindexBest; pindex && nBestHeight - pindex->nHeight < COINBASE_MATURITY-1; pindex = pindex->pprev)
  2288.                     if (pindex->nBlockPos == txindex.pos.nBlockPos && pindex->nFile == txindex.pos.nFile)
  2289.                         return error("ConnectInputs() : tried to spend coinbase at depth %d", nBestHeight - pindex->nHeight);
  2290.             if (!VerifySignature(txPrev, *this, i))
  2291.                 return error("ConnectInputs() : %s VerifySignature failed", GetHash().ToString().substr(0,6).c_str());
  2292.             if (!txindex.vSpent[prevout.n].IsNull())
  2293.                 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());
  2294.             txindex.vSpent[prevout.n] = posThisTx;
  2295.             if (fBlock)
  2296.                 txdb.UpdateTxIndex(prevout.hash, txindex);
  2297.             else if (fMiner)
  2298.                 mapTestPool[prevout.hash] = txindex;
  2299.             nValueIn += txPrev.vout[prevout.n].nValue;
  2300.         }
  2301.         int64 nTxFee = nValueIn - GetValueOut();
  2302.         if (nTxFee < 0)
  2303.             return error("ConnectInputs() : %s nTxFee < 0", GetHash().ToString().substr(0,6).c_str());
  2304.         if (nTxFee < nMinFee)
  2305.             return false;
  2306.         nFees += nTxFee;
  2307.     }
  2308.     if (fBlock)
  2309.     {
  2310.         if (!txdb.AddTxIndex(*this, posThisTx, nHeight))
  2311.             return error("ConnectInputs() : AddTxPos failed");
  2312.     }
  2313.     else if (fMiner)
  2314.     {
  2315.         mapTestPool[GetHash()] = CTxIndex(CDiskTxPos(1,1,1), vout.size());
  2316.     }
  2317.     return true;
  2318. }
  2319. bool CTransaction::ClientConnectInputs()
  2320. {
  2321.     if (IsCoinBase())
  2322.         return false;
  2323.     CRITICAL_BLOCK(cs_mapTransactions)
  2324.     {
  2325.         int64 nValueIn = 0;
  2326.         for (int i = 0; i < vin.size(); i++)
  2327.         {
  2328.             COutPoint prevout = vin[i].prevout;
  2329.             if (!mapTransactions.count(prevout.hash))
  2330.                 return false;
  2331.             CTransaction& txPrev = mapTransactions[prevout.hash];
  2332.             if (prevout.n >= txPrev.vout.size())
  2333.                 return false;
  2334.             if (!VerifySignature(txPrev, *this, i))
  2335.                 return error("ConnectInputs() : VerifySignature failed");
  2336.             nValueIn += txPrev.vout[prevout.n].nValue;
  2337.         }
  2338.         if (GetValueOut() > nValueIn)
  2339.             return false;
  2340.     }
  2341.     return true;
  2342. }
  2343. bool CBlock::DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex)
  2344. {
  2345.     for (int i = vtx.size()-1; i >= 0; i--)
  2346.         if (!vtx[i].DisconnectInputs(txdb))
  2347.             return false;
  2348.     if (pindex->pprev)
  2349.     {
  2350.         CDiskBlockIndex blockindexPrev(pindex->pprev);
  2351.         blockindexPrev.hashNext = 0;
  2352.         txdb.WriteBlockIndex(blockindexPrev);
  2353.     }
  2354.     return true;
  2355. }
  2356. bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex)
  2357. {
  2358.     unsigned int nTxPos = pindex->nBlockPos + ::GetSerializeSize(CBlock(), SER_DISK) - 1 + GetSizeOfCompactSize(vtx.size());
  2359.     map<uint256, CTxIndex> mapUnused;
  2360.     int64 nFees = 0;
  2361.     foreach(CTransaction& tx, vtx)
  2362.     {
  2363.         CDiskTxPos posThisTx(pindex->nFile, pindex->nBlockPos, nTxPos);
  2364.         nTxPos += ::GetSerializeSize(tx, SER_DISK);
  2365.         if (!tx.ConnectInputs(txdb, mapUnused, posThisTx, pindex->nHeight, nFees, true, false))
  2366.             return false;
  2367.     }
  2368.     if (vtx[0].GetValueOut() > GetBlockValue(nFees))
  2369.         return false;
  2370.     if (pindex->pprev)
  2371.     {
  2372.         CDiskBlockIndex blockindexPrev(pindex->pprev);
  2373.         blockindexPrev.hashNext = pindex->GetBlockHash();
  2374.         txdb.WriteBlockIndex(blockindexPrev);
  2375.     }
  2376.     foreach(CTransaction& tx, vtx)
  2377.         AddToWalletIfMine(tx, this);
  2378.     return true;
  2379. }
  2380. bool Reorganize(CTxDB& txdb, CBlockIndex* pindexNew)
  2381. {
  2382.     printf("*** REORGANIZE ***\n");
  2383.     CBlockIndex* pfork = pindexBest;
  2384.     CBlockIndex* plonger = pindexNew;
  2385.     while (pfork != plonger)
  2386.     {
  2387.         if (!(pfork = pfork->pprev))
  2388.             return error("Reorganize() : pfork->pprev is null");
  2389.         while (plonger->nHeight > pfork->nHeight)
  2390.             if (!(plonger = plonger->pprev))
  2391.                 return error("Reorganize() : plonger->pprev is null");
  2392.     }
  2393.     vector<CBlockIndex*> vDisconnect;
  2394.     for (CBlockIndex* pindex = pindexBest; pindex != pfork; pindex = pindex->pprev)
  2395.         vDisconnect.push_back(pindex);
  2396.     vector<CBlockIndex*> vConnect;
  2397.     for (CBlockIndex* pindex = pindexNew; pindex != pfork; pindex = pindex->pprev)
  2398.         vConnect.push_back(pindex);
  2399.     reverse(vConnect.begin(), vConnect.end());
  2400.     vector<CTransaction> vResurrect;
  2401.     foreach(CBlockIndex* pindex, vDisconnect)
  2402.     {
  2403.         CBlock block;
  2404.         if (!block.ReadFromDisk(pindex->nFile, pindex->nBlockPos, true))
  2405.             return error("Reorganize() : ReadFromDisk for disconnect failed");
  2406.         if (!block.DisconnectBlock(txdb, pindex))
  2407.             return error("Reorganize() : DisconnectBlock failed");
  2408.         foreach(const CTransaction& tx, block.vtx)
  2409.             if (!tx.IsCoinBase())
  2410.                 vResurrect.push_back(tx);
  2411.     }
  2412.     vector<CTransaction> vDelete;
  2413.     for (int i = 0; i < vConnect.size(); i++)
  2414.     {
  2415.         CBlockIndex* pindex = vConnect[i];
  2416.         CBlock block;
  2417.         if (!block.ReadFromDisk(pindex->nFile, pindex->nBlockPos, true))
  2418.             return error("Reorganize() : ReadFromDisk for connect failed");
  2419.         if (!block.ConnectBlock(txdb, pindex))
  2420.         {
  2421.             txdb.TxnAbort();
  2422.             for (int j = i; j < vConnect.size(); j++)
  2423.             {
  2424.                 CBlockIndex* pindex = vConnect[j];
  2425.                 pindex->EraseBlockFromDisk();
  2426.                 txdb.EraseBlockIndex(pindex->GetBlockHash());
  2427.                 mapBlockIndex.erase(pindex->GetBlockHash());
  2428.                 delete pindex;
  2429.             }
  2430.             return error("Reorganize() : ConnectBlock failed");
  2431.         }
  2432.         foreach(const CTransaction& tx, block.vtx)
  2433.             vDelete.push_back(tx);
  2434.     }
  2435.     if (!txdb.WriteHashBestChain(pindexNew->GetBlockHash()))
  2436.         return error("Reorganize() : WriteHashBestChain failed");
  2437.     txdb.TxnCommit();
  2438.     foreach(CBlockIndex* pindex, vDisconnect)
  2439.         if (pindex->pprev)
  2440.             pindex->pprev->pnext = NULL;
  2441.     foreach(CBlockIndex* pindex, vConnect)
  2442.         if (pindex->pprev)
  2443.             pindex->pprev->pnext = pindex;
  2444.     foreach(CTransaction& tx, vResurrect)
  2445.         tx.AcceptTransaction(txdb, false);
  2446.     foreach(CTransaction& tx, vDelete)
  2447.         tx.RemoveFromMemoryPool();
  2448.     return true;
  2449. }
  2450. bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
  2451. {
  2452.     uint256 hash = GetHash();
  2453.     if (mapBlockIndex.count(hash))
  2454.         return error("AddToBlockIndex() : %s already exists", hash.ToString().substr(0,14).c_str());
  2455.     CBlockIndex* pindexNew = new CBlockIndex(nFile, nBlockPos, *this);
  2456.     if (!pindexNew)
  2457.         return error("AddToBlockIndex() : new CBlockIndex failed");
  2458.     map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
  2459.     pindexNew->phashBlock = &((*mi).first);
  2460.     map<uint256, CBlockIndex*>::iterator miPrev = mapBlockIndex.find(hashPrevBlock);
  2461.     if (miPrev != mapBlockIndex.end())
  2462.     {
  2463.         pindexNew->pprev = (*miPrev).second;
  2464.         pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
  2465.     }
  2466.     CTxDB txdb;
  2467.     txdb.TxnBegin();
  2468.     txdb.WriteBlockIndex(CDiskBlockIndex(pindexNew));
  2469.     if (pindexNew->nHeight > nBestHeight)
  2470.     {
  2471.         if (pindexGenesisBlock == NULL && hash == hashGenesisBlock)
  2472.         {
  2473.             pindexGenesisBlock = pindexNew;
  2474.             txdb.WriteHashBestChain(hash);
  2475.         }
  2476.         else if (hashPrevBlock == hashBestChain)
  2477.         {
  2478.             if (!ConnectBlock(txdb, pindexNew) || !txdb.WriteHashBestChain(hash))
  2479.             {
  2480.                 txdb.TxnAbort();
  2481.                 pindexNew->EraseBlockFromDisk();
  2482.                 mapBlockIndex.erase(pindexNew->GetBlockHash());
  2483.                 delete pindexNew;
  2484.                 return error("AddToBlockIndex() : ConnectBlock failed");
  2485.             }
  2486.             txdb.TxnCommit();
  2487.             pindexNew->pprev->pnext = pindexNew;
  2488.             foreach(CTransaction& tx, vtx)
  2489.                 tx.RemoveFromMemoryPool();
  2490.         }
  2491.         else
  2492.         {
  2493.             if (!Reorganize(txdb, pindexNew))
  2494.             {
  2495.                 txdb.TxnAbort();
  2496.                 return error("AddToBlockIndex() : Reorganize failed");
  2497.             }
  2498.         }
  2499.         hashBestChain = hash;
  2500.         pindexBest = pindexNew;
  2501.         nBestHeight = pindexBest->nHeight;
  2502.         nTransactionsUpdated++;
  2503.         printf("AddToBlockIndex: new best=%s  height=%d\n", hashBestChain.ToString().substr(0,14).c_str(), nBestHeight);
  2504.     }
  2505.     txdb.TxnCommit();
  2506.     txdb.Close();
  2507.     if (pindexNew == pindexBest)
  2508.         RelayWalletTransactions();
  2509.     MainFrameRepaint();
  2510.     return true;
  2511. }
  2512. bool CBlock::CheckBlock() const
  2513. {
  2514.     if (vtx.empty() || vtx.size() > MAX_SIZE || ::GetSerializeSize(*this, SER_DISK) > MAX_SIZE)
  2515.         return error("CheckBlock() : size limits failed");
  2516.     if (nTime > GetAdjustedTime() + 2 * 60 * 60)
  2517.         return error("CheckBlock() : block timestamp too far in the future");
  2518.     if (vtx.empty() || !vtx[0].IsCoinBase())
  2519.         return error("CheckBlock() : first tx is not coinbase");
  2520.     for (int i = 1; i < vtx.size(); i++)
  2521.         if (vtx[i].IsCoinBase())
  2522.             return error("CheckBlock() : more than one coinbase");
  2523.     foreach(const CTransaction& tx, vtx)
  2524.         if (!tx.CheckTransaction())
  2525.             return error("CheckBlock() : CheckTransaction failed");
  2526.     if (CBigNum().SetCompact(nBits) > bnProofOfWorkLimit)
  2527.         return error("CheckBlock() : nBits below minimum work");
  2528.     if (GetHash() > CBigNum().SetCompact(nBits).getuint256())
  2529.         return error("CheckBlock() : hash doesn't match nBits");
  2530.     if (hashMerkleRoot != BuildMerkleTree())
  2531.         return error("CheckBlock() : hashMerkleRoot mismatch");
  2532.     return true;
  2533. }
  2534. bool CBlock::AcceptBlock()
  2535. {
  2536.     uint256 hash = GetHash();
  2537.     if (mapBlockIndex.count(hash))
  2538.         return error("AcceptBlock() : block already in mapBlockIndex");
  2539.     map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashPrevBlock);
  2540.     if (mi == mapBlockIndex.end())
  2541.         return error("AcceptBlock() : prev block not found");
  2542.     CBlockIndex* pindexPrev = (*mi).second;
  2543.     if (nTime <= pindexPrev->GetMedianTimePast())
  2544.         return error("AcceptBlock() : block's timestamp is too early");
  2545.     if (nBits != GetNextWorkRequired(pindexPrev))
  2546.         return error("AcceptBlock() : incorrect proof of work");
  2547.     unsigned int nFile;
  2548.     unsigned int nBlockPos;
  2549.     if (!WriteToDisk(!fClient, nFile, nBlockPos))
  2550.         return error("AcceptBlock() : WriteToDisk failed");
  2551.     if (!AddToBlockIndex(nFile, nBlockPos))
  2552.         return error("AcceptBlock() : AddToBlockIndex failed");
  2553.     if (hashBestChain == hash)
  2554.         RelayInventory(CInv(MSG_BLOCK, hash));
  2555.     return true;
  2556. }
  2557. bool ProcessBlock(CNode* pfrom, CBlock* pblock)
  2558. {
  2559.     uint256 hash = pblock->GetHash();
  2560.     if (mapBlockIndex.count(hash))
  2561.         return error("ProcessBlock() : already have block %d %s", mapBlockIndex[hash]->nHeight, hash.ToString().substr(0,14).c_str());
  2562.     if (mapOrphanBlocks.count(hash))
  2563.         return error("ProcessBlock() : already have block (orphan) %s", hash.ToString().substr(0,14).c_str());
  2564.     if (!pblock->CheckBlock())
  2565.     {
  2566.         delete pblock;
  2567.         return error("ProcessBlock() : CheckBlock FAILED");
  2568.     }
  2569.     if (!mapBlockIndex.count(pblock->hashPrevBlock))
  2570.     {
  2571.         printf("ProcessBlock: ORPHAN BLOCK, prev=%s\n", pblock->hashPrevBlock.ToString().substr(0,14).c_str());
  2572.         mapOrphanBlocks.insert(make_pair(hash, pblock));
  2573.         mapOrphanBlocksByPrev.insert(make_pair(pblock->hashPrevBlock, pblock));
  2574.         if (pfrom)
  2575.             pfrom->PushMessage("getblocks", CBlockLocator(pindexBest), GetOrphanRoot(pblock));
  2576.         return true;
  2577.     }
  2578.     if (!pblock->AcceptBlock())
  2579.     {
  2580.         delete pblock;
  2581.         return error("ProcessBlock() : AcceptBlock FAILED");
  2582.     }
  2583.     delete pblock;
  2584.     vector<uint256> vWorkQueue;
  2585.     vWorkQueue.push_back(hash);
  2586.     for (int i = 0; i < vWorkQueue.size(); i++)
  2587.     {
  2588.         uint256 hashPrev = vWorkQueue[i];
  2589.         for (multimap<uint256, CBlock*>::iterator mi = mapOrphanBlocksByPrev.lower_bound(hashPrev);
  2590.              mi != mapOrphanBlocksByPrev.upper_bound(hashPrev);
  2591.              ++mi)
  2592.         {
  2593.             CBlock* pblockOrphan = (*mi).second;
  2594.             if (pblockOrphan->AcceptBlock())
  2595.                 vWorkQueue.push_back(pblockOrphan->GetHash());
  2596.             mapOrphanBlocks.erase(pblockOrphan->GetHash());
  2597.             delete pblockOrphan;
  2598.         }
  2599.         mapOrphanBlocksByPrev.erase(hashPrev);
  2600.     }
  2601.     printf("ProcessBlock: ACCEPTED\n");
  2602.     return true;
  2603. }
  2604. template<typename Stream>
  2605. bool ScanMessageStart(Stream& s)
  2606. {
  2607.     s.clear(0);
  2608.     short prevmask = s.exceptions(0);
  2609.     const char* p = BEGIN(pchMessageStart);
  2610.     try
  2611.     {
  2612.         loop
  2613.         {
  2614.             char c;
  2615.             s.read(&c, 1);
  2616.             if (s.fail())
  2617.             {
  2618.                 s.clear(0);
  2619.                 s.exceptions(prevmask);
  2620.                 return false;
  2621.             }
  2622.             if (*p != c)
  2623.                 p = BEGIN(pchMessageStart);
  2624.             if (*p == c)
  2625.             {
  2626.                 if (++p == END(pchMessageStart))
  2627.                 {
  2628.                     s.clear(0);
  2629.                     s.exceptions(prevmask);
  2630.                     return true;
  2631.                 }
  2632.             }
  2633.         }
  2634.     }
  2635.     catch (...)
  2636.     {
  2637.         s.clear(0);
  2638.         s.exceptions(prevmask);
  2639.         return false;
  2640.     }
  2641. }
  2642. string GetAppDir()
  2643. {
  2644.     string strDir;
  2645.     if (!strSetDataDir.empty())
  2646.     {
  2647.         strDir = strSetDataDir;
  2648.     }
  2649.     else if (getenv("APPDATA"))
  2650.     {
  2651.         strDir = strprintf("%s\\Bitcoin", getenv("APPDATA"));
  2652.     }
  2653.     else if (getenv("USERPROFILE"))
  2654.     {
  2655.         string strAppData = strprintf("%s\\Application Data", getenv("USERPROFILE"));
  2656.         static bool fMkdirDone;
  2657.         if (!fMkdirDone)
  2658.         {
  2659.             fMkdirDone = true;
  2660.             _mkdir(strAppData.c_str());
  2661.         }
  2662.         strDir = strprintf("%s\\Bitcoin", strAppData.c_str());
  2663.     }
  2664.     else
  2665.     {
  2666.         return ".";
  2667.     }
  2668.     static bool fMkdirDone;
  2669.     if (!fMkdirDone)
  2670.     {
  2671.         fMkdirDone = true;
  2672.         _mkdir(strDir.c_str());
  2673.     }
  2674.     return strDir;
  2675. }
  2676. FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode)
  2677. {
  2678.     if (nFile == -1)
  2679.         return NULL;
  2680.     FILE* file = fopen(strprintf("%s\\blk%04d.dat", GetAppDir().c_str(), nFile).c_str(), pszMode);
  2681.     if (!file)
  2682.         return NULL;
  2683.     if (nBlockPos != 0 && !strchr(pszMode, 'a') && !strchr(pszMode, 'w'))
  2684.     {
  2685.         if (fseek(file, nBlockPos, SEEK_SET) != 0)
  2686.         {
  2687.             fclose(file);
  2688.             return NULL;
  2689.         }
  2690.     }
  2691.     return file;
  2692. }
  2693. static unsigned int nCurrentBlockFile = 1;
  2694. FILE* AppendBlockFile(unsigned int& nFileRet)
  2695. {
  2696.     nFileRet = 0;
  2697.     loop
  2698.     {
  2699.         FILE* file = OpenBlockFile(nCurrentBlockFile, 0, "ab");
  2700.         if (!file)
  2701.             return NULL;
  2702.         if (fseek(file, 0, SEEK_END) != 0)
  2703.             return NULL;
  2704.         if (ftell(file) < 0x7F000000 - MAX_SIZE)
  2705.         {
  2706.             nFileRet = nCurrentBlockFile;
  2707.             return file;
  2708.         }
  2709.         fclose(file);
  2710.         nCurrentBlockFile++;
  2711.     }
  2712. }
  2713. bool LoadBlockIndex(bool fAllowNew)
  2714. {
  2715.     CTxDB txdb("cr");
  2716.     if (!txdb.LoadBlockIndex())
  2717.         return false;
  2718.     txdb.Close();
  2719.     if (mapBlockIndex.empty())
  2720.     {
  2721.         if (!fAllowNew)
  2722.             return false;
  2723.         char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks";
  2724.         CTransaction txNew;
  2725.         txNew.vin.resize(1);
  2726.         txNew.vout.resize(1);
  2727.         txNew.vin[0].scriptSig     = CScript() << 486604799 << CBigNum(4) << vector<unsigned char>((unsigned char*)pszTimestamp, (unsigned char*)pszTimestamp + strlen(pszTimestamp));
  2728.         txNew.vout[0].nValue       = 50 * COIN;
  2729.         txNew.vout[0].scriptPubKey = CScript() << CBigNum("0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704") << OP_CHECKSIG;
  2730.         CBlock block;
  2731.         block.vtx.push_back(txNew);
  2732.         block.hashPrevBlock = 0;
  2733.         block.hashMerkleRoot = block.BuildMerkleTree();
  2734.         block.nVersion = 1;
  2735.         block.nTime    = 1231006505;
  2736.         block.nBits    = 0x1d00ffff;
  2737.         block.nNonce   = 2083236893;
  2738.             printf("%s\n", block.GetHash().ToString().c_str());
  2739.             printf("%s\n", block.hashMerkleRoot.ToString().c_str());
  2740.             printf("%s\n", hashGenesisBlock.ToString().c_str());
  2741.             txNew.vout[0].scriptPubKey.print();
  2742.             block.print();
  2743.             assert(block.hashMerkleRoot == uint256("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
  2744.         assert(block.GetHash() == hashGenesisBlock);
  2745.         unsigned int nFile;
  2746.         unsigned int nBlockPos;
  2747.         if (!block.WriteToDisk(!fClient, nFile, nBlockPos))
  2748.             return error("LoadBlockIndex() : writing genesis block to disk failed");
  2749.         if (!block.AddToBlockIndex(nFile, nBlockPos))
  2750.             return error("LoadBlockIndex() : genesis block not accepted");
  2751.     }
  2752.     return true;
  2753. }
  2754. void PrintBlockTree()
  2755. {
  2756.     map<CBlockIndex*, vector<CBlockIndex*> > mapNext;
  2757.     for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi)
  2758.     {
  2759.         CBlockIndex* pindex = (*mi).second;
  2760.         mapNext[pindex->pprev].push_back(pindex);
  2761.     }
  2762.     vector<pair<int, CBlockIndex*> > vStack;
  2763.     vStack.push_back(make_pair(0, pindexGenesisBlock));
  2764.     int nPrevCol = 0;
  2765.     while (!vStack.empty())
  2766.     {
  2767.         int nCol = vStack.back().first;
  2768.         CBlockIndex* pindex = vStack.back().second;
  2769.         vStack.pop_back();
  2770.         if (nCol > nPrevCol)
  2771.         {
  2772.             for (int i = 0; i < nCol-1; i++)
  2773.                 printf("| ");
  2774.             printf("|\\\n");
  2775.         }
  2776.         else if (nCol < nPrevCol)
  2777.         {
  2778.             for (int i = 0; i < nCol; i++)
  2779.                 printf("| ");
  2780.             printf("|\n");
  2781.         }
  2782.         nPrevCol = nCol;
  2783.         for (int i = 0; i < nCol; i++)
  2784.             printf("| ");
  2785.         CBlock block;
  2786.         block.ReadFromDisk(pindex, true);
  2787.         printf("%d (%u,%u) %s  %s  tx %d",
  2788.             pindex->nHeight,
  2789.             pindex->nFile,
  2790.             pindex->nBlockPos,
  2791.             block.GetHash().ToString().substr(0,14).c_str(),
  2792.             DateTimeStr(block.nTime).c_str(),
  2793.             block.vtx.size());
  2794.         CRITICAL_BLOCK(cs_mapWallet)
  2795.         {
  2796.             if (mapWallet.count(block.vtx[0].GetHash()))
  2797.             {
  2798.                 CWalletTx& wtx = mapWallet[block.vtx[0].GetHash()];
  2799.                 printf("    mine:  %d  %d  %d", wtx.GetDepthInMainChain(), wtx.GetBlocksToMaturity(), wtx.GetCredit());
  2800.             }
  2801.         }
  2802.         printf("\n");
  2803.         vector<CBlockIndex*>& vNext = mapNext[pindex];
  2804.         for (int i = 0; i < vNext.size(); i++)
  2805.         {
  2806.             if (vNext[i]->pnext)
  2807.             {
  2808.                 swap(vNext[0], vNext[i]);
  2809.                 break;
  2810.             }
  2811.         }
  2812.         for (int i = 0; i < vNext.size(); i++)
  2813.             vStack.push_back(make_pair(nCol+i, vNext[i]));
  2814.     }
  2815. }bool AlreadyHave(CTxDB& txdb, const CInv& inv)
  2816. {
  2817.     switch (inv.type)
  2818.     {
  2819.     case MSG_TX:        return mapTransactions.count(inv.hash) || txdb.ContainsTx(inv.hash);
  2820.     case MSG_BLOCK:     return mapBlockIndex.count(inv.hash) || mapOrphanBlocks.count(inv.hash);
  2821.     case MSG_REVIEW:    return true;
  2822.     case MSG_PRODUCT:   return mapProducts.count(inv.hash);
  2823.     }
  2824.     return true;
  2825. }
  2826. bool ProcessMessages(CNode* pfrom)
  2827. {
  2828.     CDataStream& vRecv = pfrom->vRecv;
  2829.     if (vRecv.empty())
  2830.         return true;
  2831.     printf("ProcessMessages(%d bytes)\n", vRecv.size());
  2832.     loop
  2833.     {
  2834.         CDataStream::iterator pstart = search(vRecv.begin(), vRecv.end(), BEGIN(pchMessageStart), END(pchMessageStart));
  2835.         if (vRecv.end() - pstart < sizeof(CMessageHeader))
  2836.         {
  2837.             if (vRecv.size() > sizeof(CMessageHeader))
  2838.             {
  2839.                 printf("\n\nPROCESSMESSAGE MESSAGESTART NOT FOUND\n\n");
  2840.                 vRecv.erase(vRecv.begin(), vRecv.end() - sizeof(CMessageHeader));
  2841.             }
  2842.             break;
  2843.         }
  2844.         if (pstart - vRecv.begin() > 0)
  2845.             printf("\n\nPROCESSMESSAGE SKIPPED %d BYTES\n\n", pstart - vRecv.begin());
  2846.         vRecv.erase(vRecv.begin(), pstart);
  2847.         CMessageHeader hdr;
  2848.         vRecv >> hdr;
  2849.         if (!hdr.IsValid())
  2850.         {
  2851.             printf("\n\nPROCESSMESSAGE: ERRORS IN HEADER %s\n\n\n", hdr.GetCommand().c_str());
  2852.             continue;
  2853.         }
  2854.         string strCommand = hdr.GetCommand();
  2855.         unsigned int nMessageSize = hdr.nMessageSize;
  2856.         if (nMessageSize > vRecv.size())
  2857.         {
  2858.             printf("MESSAGE-BREAK 2\n");
  2859.             vRecv.insert(vRecv.begin(), BEGIN(hdr), END(hdr));
  2860.             Sleep(100);
  2861.             break;
  2862.         }
  2863.         CDataStream vMsg(vRecv.begin(), vRecv.begin() + nMessageSize, vRecv.nType, vRecv.nVersion);
  2864.         vRecv.ignore(nMessageSize);
  2865.         bool fRet = false;
  2866.         try
  2867.         {
  2868.             CheckForShutdown(2);
  2869.             CRITICAL_BLOCK(cs_main)
  2870.                 fRet = ProcessMessage(pfrom, strCommand, vMsg);
  2871.             CheckForShutdown(2);
  2872.         }
  2873.         CATCH_PRINT_EXCEPTION("ProcessMessage()")
  2874.         if (!fRet)
  2875.             printf("ProcessMessage(%s, %d bytes) from %s to %s FAILED\n", strCommand.c_str(), nMessageSize, pfrom->addr.ToString().c_str(), addrLocalHost.ToString().c_str());
  2876.     }
  2877.     vRecv.Compact();
  2878.     return true;
  2879. }
  2880. bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
  2881. {
  2882.     static map<unsigned int, vector<unsigned char> > mapReuseKey;
  2883.     printf("received: %-12s (%d bytes)  ", strCommand.c_str(), vRecv.size());
  2884.     for (int i = 0; i < min(vRecv.size(), (unsigned int)25); i++)
  2885.         printf("%02x ", vRecv[i] & 0xff);
  2886.     printf("\n");
  2887.     if (nDropMessagesTest > 0 && GetRand(nDropMessagesTest) == 0)
  2888.     {
  2889.         printf("dropmessages DROPPING RECV MESSAGE\n");
  2890.         return true;
  2891.     }
  2892.     if (strCommand == "version")
  2893.     {
  2894.         if (pfrom->nVersion != 0)
  2895.             return false;
  2896.         int64 nTime;
  2897.         CAddress addrMe;
  2898.         vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe;
  2899.         if (pfrom->nVersion == 0)
  2900.             return false;
  2901.         pfrom->vSend.SetVersion(min(pfrom->nVersion, VERSION));
  2902.         pfrom->vRecv.SetVersion(min(pfrom->nVersion, VERSION));
  2903.         pfrom->fClient = !(pfrom->nServices & NODE_NETWORK);
  2904.         if (pfrom->fClient)
  2905.         {
  2906.             pfrom->vSend.nType |= SER_BLOCKHEADERONLY;
  2907.             pfrom->vRecv.nType |= SER_BLOCKHEADERONLY;
  2908.         }
  2909.         AddTimeData(pfrom->addr.ip, nTime);
  2910.         static bool fAskedForBlocks;
  2911.         if (!fAskedForBlocks && !pfrom->fClient)
  2912.         {
  2913.             fAskedForBlocks = true;
  2914.             pfrom->PushMessage("getblocks", CBlockLocator(pindexBest), uint256(0));
  2915.         }
  2916.         printf("version addrMe = %s\n", addrMe.ToString().c_str());
  2917.     }
  2918.     else if (pfrom->nVersion == 0)
  2919.     {
  2920.         return false;
  2921.     }
  2922.     else if (strCommand == "addr")
  2923.     {
  2924.         vector<CAddress> vAddr;
  2925.         vRecv >> vAddr;
  2926.         CAddrDB addrdb;
  2927.         foreach(const CAddress& addr, vAddr)
  2928.         {
  2929.             if (fShutdown)
  2930.                 return true;
  2931.             if (AddAddress(addrdb, addr))
  2932.             {
  2933.                 pfrom->setAddrKnown.insert(addr);
  2934.                 CRITICAL_BLOCK(cs_vNodes)
  2935.                     foreach(CNode* pnode, vNodes)
  2936.                         if (!pnode->setAddrKnown.count(addr))
  2937.                             pnode->vAddrToSend.push_back(addr);
  2938.             }
  2939.         }
  2940.     }
  2941.     else if (strCommand == "inv")
  2942.     {
  2943.         vector<CInv> vInv;
  2944.         vRecv >> vInv;
  2945.         CTxDB txdb("r");
  2946.         foreach(const CInv& inv, vInv)
  2947.         {
  2948.             if (fShutdown)
  2949.                 return true;
  2950.             pfrom->AddInventoryKnown(inv);
  2951.  
  2952.             bool fAlreadyHave = AlreadyHave(txdb, inv);
  2953.             printf("  got inventory: %s  %s\n", inv.ToString().c_str(), fAlreadyHave ? "have" : "new");
  2954.             if (!fAlreadyHave)
  2955.                 pfrom->AskFor(inv);
  2956.             else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash))
  2957.                 pfrom->PushMessage("getblocks", CBlockLocator(pindexBest), GetOrphanRoot(mapOrphanBlocks[inv.hash]));
  2958.         }
  2959.     }
  2960.     else if (strCommand == "getdata")
  2961.     {
  2962.         vector<CInv> vInv;
  2963.         vRecv >> vInv;
  2964.         foreach(const CInv& inv, vInv)
  2965.         {
  2966.             if (fShutdown)
  2967.                 return true;
  2968.             printf("received getdata for: %s\n", inv.ToString().c_str());
  2969.             if (inv.type == MSG_BLOCK)
  2970.             {
  2971.                 map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(inv.hash);
  2972.                 if (mi != mapBlockIndex.end())
  2973.                 {
  2974.                     CBlock block;
  2975.                     block.ReadFromDisk((*mi).second, !pfrom->fClient);
  2976.                     pfrom->PushMessage("block", block);
  2977.                 }
  2978.             }
  2979.             else if (inv.IsKnownType())
  2980.             {
  2981.                 CRITICAL_BLOCK(cs_mapRelay)
  2982.                 {
  2983.                     map<CInv, CDataStream>::iterator mi = mapRelay.find(inv);
  2984.                     if (mi != mapRelay.end())
  2985.                         pfrom->PushMessage(inv.GetCommand(), (*mi).second);
  2986.                 }
  2987.             }
  2988.         }
  2989.     }
  2990.     else if (strCommand == "getblocks")
  2991.     {
  2992.         CBlockLocator locator;
  2993.         uint256 hashStop;
  2994.         vRecv >> locator >> hashStop;
  2995.         CBlockIndex* pindex = locator.GetBlockIndex();
  2996.         if (pindex)
  2997.             pindex = pindex->pnext;
  2998.         printf("getblocks %d to %s\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,14).c_str());
  2999.         for (; pindex; pindex = pindex->pnext)
  3000.         {
  3001.             if (pindex->GetBlockHash() == hashStop)
  3002.             {
  3003.                 printf("  getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,14).c_str());
  3004.                 break;
  3005.             }
  3006.             CRITICAL_BLOCK(pfrom->cs_inventory)
  3007.             {
  3008.                 CInv inv(MSG_BLOCK, pindex->GetBlockHash());
  3009.                 if (pfrom->setInventoryKnown2.insert(inv).second)
  3010.                 {
  3011.                     pfrom->setInventoryKnown.erase(inv);
  3012.                     pfrom->vInventoryToSend.push_back(inv);
  3013.                 }
  3014.             }
  3015.         }
  3016.     }
  3017.     else if (strCommand == "tx")
  3018.     {
  3019.         vector<uint256> vWorkQueue;
  3020.         CDataStream vMsg(vRecv);
  3021.         CTransaction tx;
  3022.         vRecv >> tx;
  3023.         CInv inv(MSG_TX, tx.GetHash());
  3024.         pfrom->AddInventoryKnown(inv);
  3025.         bool fMissingInputs = false;
  3026.         if (tx.AcceptTransaction(true, &fMissingInputs))
  3027.         {
  3028.             AddToWalletIfMine(tx, NULL);
  3029.             RelayMessage(inv, vMsg);
  3030.             mapAlreadyAskedFor.erase(inv);
  3031.             vWorkQueue.push_back(inv.hash);
  3032.             for (int i = 0; i < vWorkQueue.size(); i++)
  3033.             {
  3034.                 uint256 hashPrev = vWorkQueue[i];
  3035.                 for (multimap<uint256, CDataStream*>::iterator mi = mapOrphanTransactionsByPrev.lower_bound(hashPrev);
  3036.                      mi != mapOrphanTransactionsByPrev.upper_bound(hashPrev);
  3037.                      ++mi)
  3038.                 {
  3039.                     const CDataStream& vMsg = *((*mi).second);
  3040.                     CTransaction tx;
  3041.                     CDataStream(vMsg) >> tx;
  3042.                     CInv inv(MSG_TX, tx.GetHash());
  3043.                     if (tx.AcceptTransaction(true))
  3044.                     {
  3045.                         printf("   accepted orphan tx %s\n", inv.hash.ToString().substr(0,6).c_str());
  3046.                         AddToWalletIfMine(tx, NULL);
  3047.                         RelayMessage(inv, vMsg);
  3048.                         mapAlreadyAskedFor.erase(inv);
  3049.                         vWorkQueue.push_back(inv.hash);
  3050.                     }
  3051.                 }
  3052.             }
  3053.             foreach(uint256 hash, vWorkQueue)
  3054.                 EraseOrphanTx(hash);
  3055.         }
  3056.         else if (fMissingInputs)
  3057.         {
  3058.             printf("storing orphan tx %s\n", inv.hash.ToString().substr(0,6).c_str());
  3059.             AddOrphanTx(vMsg);
  3060.         }
  3061.     }
  3062.     else if (strCommand == "review")
  3063.     {
  3064.         CDataStream vMsg(vRecv);
  3065.         CReview review;
  3066.         vRecv >> review;
  3067.         CInv inv(MSG_REVIEW, review.GetHash());
  3068.         pfrom->AddInventoryKnown(inv);
  3069.         if (review.AcceptReview())
  3070.         {
  3071.             RelayMessage(inv, vMsg);
  3072.             mapAlreadyAskedFor.erase(inv);
  3073.         }
  3074.     }
  3075.     else if (strCommand == "block")
  3076.     {
  3077.         auto_ptr<CBlock> pblock(new CBlock);
  3078.         vRecv >> *pblock;
  3079.         printf("received block:\n"); pblock->print();
  3080.         CInv inv(MSG_BLOCK, pblock->GetHash());
  3081.         pfrom->AddInventoryKnown(inv);
  3082.         if (ProcessBlock(pfrom, pblock.release()))
  3083.             mapAlreadyAskedFor.erase(inv);
  3084.     }
  3085.     else if (strCommand == "getaddr")
  3086.     {
  3087.         pfrom->vAddrToSend.clear();
  3088.         int64 nSince = GetAdjustedTime() - 60 * 60;
  3089.         CRITICAL_BLOCK(cs_mapAddresses)
  3090.         {
  3091.             foreach(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
  3092.             {
  3093.                 if (fShutdown)
  3094.                     return true;
  3095.                 const CAddress& addr = item.second;
  3096.                 if (addr.nTime > nSince)
  3097.                     pfrom->vAddrToSend.push_back(addr);
  3098.             }
  3099.         }
  3100.     }
  3101.     else if (strCommand == "checkorder")
  3102.     {
  3103.         uint256 hashReply;
  3104.         CWalletTx order;
  3105.         vRecv >> hashReply >> order;
  3106.         if (!mapReuseKey.count(pfrom->addr.ip))
  3107.             mapReuseKey[pfrom->addr.ip] = GenerateNewKey();
  3108.         CScript scriptPubKey;
  3109.         scriptPubKey << mapReuseKey[pfrom->addr.ip] << OP_CHECKSIG;
  3110.         pfrom->PushMessage("reply", hashReply, (int)0, scriptPubKey);
  3111.     }
  3112.     else if (strCommand == "submitorder")
  3113.     {
  3114.         uint256 hashReply;
  3115.         CWalletTx wtxNew;
  3116.         vRecv >> hashReply >> wtxNew;
  3117.         if (!wtxNew.AcceptWalletTransaction())
  3118.         {
  3119.             pfrom->PushMessage("reply", hashReply, (int)1);
  3120.             return error("submitorder AcceptWalletTransaction() failed, returning error 1");
  3121.         }
  3122.         wtxNew.fTimeReceivedIsTxTime = true;
  3123.         AddToWallet(wtxNew);
  3124.         wtxNew.RelayWalletTransaction();
  3125.         mapReuseKey.erase(pfrom->addr.ip);
  3126.         pfrom->PushMessage("reply", hashReply, (int)0);
  3127.     }
  3128.     else if (strCommand == "reply")
  3129.     {
  3130.         uint256 hashReply;
  3131.         vRecv >> hashReply;
  3132.         CRequestTracker tracker;
  3133.         CRITICAL_BLOCK(pfrom->cs_mapRequests)
  3134.         {
  3135.             map<uint256, CRequestTracker>::iterator mi = pfrom->mapRequests.find(hashReply);
  3136.             if (mi != pfrom->mapRequests.end())
  3137.             {
  3138.                 tracker = (*mi).second;
  3139.                 pfrom->mapRequests.erase(mi);
  3140.             }
  3141.         }
  3142.         if (!tracker.IsNull())
  3143.             tracker.fn(tracker.param1, vRecv);
  3144.     }
  3145.     else
  3146.     {
  3147.         printf("ProcessMessage(%s) : Ignored unknown message\n", strCommand.c_str());
  3148.     }
  3149.     if (!vRecv.empty())
  3150.         printf("ProcessMessage(%s) : %d extra bytes\n", strCommand.c_str(), vRecv.size());
  3151.     return true;
  3152. }
  3153. bool SendMessages(CNode* pto)
  3154. {
  3155.     CheckForShutdown(2);
  3156.     CRITICAL_BLOCK(cs_main)
  3157.     {
  3158.         if (pto->nVersion == 0)
  3159.             return true;
  3160.         vector<CAddress> vAddrToSend;
  3161.         vAddrToSend.reserve(pto->vAddrToSend.size());
  3162.         foreach(const CAddress& addr, pto->vAddrToSend)
  3163.             if (!pto->setAddrKnown.count(addr))
  3164.                 vAddrToSend.push_back(addr);
  3165.         pto->vAddrToSend.clear();
  3166.         if (!vAddrToSend.empty())
  3167.             pto->PushMessage("addr", vAddrToSend);
  3168.         vector<CInv> vInventoryToSend;
  3169.         CRITICAL_BLOCK(pto->cs_inventory)
  3170.         {
  3171.             vInventoryToSend.reserve(pto->vInventoryToSend.size());
  3172.             foreach(const CInv& inv, pto->vInventoryToSend)
  3173.             {
  3174.                 if (pto->setInventoryKnown.insert(inv).second)
  3175.                     vInventoryToSend.push_back(inv);
  3176.             }
  3177.             pto->vInventoryToSend.clear();
  3178.             pto->setInventoryKnown2.clear();
  3179.         }
  3180.         if (!vInventoryToSend.empty())
  3181.             pto->PushMessage("inv", vInventoryToSend);
  3182.         vector<CInv> vAskFor;
  3183.         int64 nNow = GetTime() * 1000000;
  3184.         CTxDB txdb("r");
  3185.         while (!pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow)
  3186.         {
  3187.             const CInv& inv = (*pto->mapAskFor.begin()).second;
  3188.             printf("sending getdata: %s\n", inv.ToString().c_str());
  3189.             if (!AlreadyHave(txdb, inv))
  3190.                 vAskFor.push_back(inv);
  3191.             pto->mapAskFor.erase(pto->mapAskFor.begin());
  3192.         }
  3193.         if (!vAskFor.empty())
  3194.             pto->PushMessage("getdata", vAskFor);
  3195.     }
  3196.     return true;
  3197. }
  3198. int FormatHashBlocks(void* pbuffer, unsigned int len)
  3199. {
  3200.     unsigned char* pdata = (unsigned char*)pbuffer;
  3201.     unsigned int blocks = 1 + ((len + 8) / 64);
  3202.     unsigned char* pend = pdata + 64 * blocks;
  3203.     memset(pdata + len, 0, 64 * blocks - len);
  3204.     pdata[len] = 0x80;
  3205.     unsigned int bits = len * 8;
  3206.     pend[-1] = (bits >> 0) & 0xff;
  3207.     pend[-2] = (bits >> 8) & 0xff;
  3208.     pend[-3] = (bits >> 16) & 0xff;
  3209.     pend[-4] = (bits >> 24) & 0xff;
  3210.     return blocks;
  3211. }
  3212. using CryptoPP::ByteReverse;
  3213. static int detectlittleendian = 1;
  3214. void BlockSHA256(const void* pin, unsigned int nBlocks, void* pout)
  3215. {
  3216.     unsigned int* pinput = (unsigned int*)pin;
  3217.     unsigned int* pstate = (unsigned int*)pout;
  3218.     CryptoPP::SHA256::InitState(pstate);
  3219.     if (*(char*)&detectlittleendian != 0)
  3220.     {
  3221.         for (int n = 0; n < nBlocks; n++)
  3222.         {
  3223.             unsigned int pbuf[16];
  3224.             for (int i = 0; i < 16; i++)
  3225.                 pbuf[i] = ByteReverse(pinput[n * 16 + i]);
  3226.             CryptoPP::SHA256::Transform(pstate, pbuf);
  3227.         }
  3228.         for (int i = 0; i < 8; i++)
  3229.             pstate[i] = ByteReverse(pstate[i]);
  3230.     }
  3231.     else
  3232.     {
  3233.         for (int n = 0; n < nBlocks; n++)
  3234.             CryptoPP::SHA256::Transform(pstate, pinput + n * 16);
  3235.     }
  3236. }
  3237. bool BitcoinMiner()
  3238. {    printf("BitcoinMiner started\n");
  3239.     SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST);
  3240.     CKey key;
  3241.     key.MakeNewKey();
  3242.     CBigNum bnExtraNonce = 0;
  3243.     while (fGenerateBitcoins)
  3244.     {
  3245.         Sleep(50);
  3246.         CheckForShutdown(3);
  3247.         while (vNodes.empty())
  3248.         {
  3249.             Sleep(1000);
  3250.             CheckForShutdown(3);
  3251.         }
  3252.         unsigned int nTransactionsUpdatedLast = nTransactionsUpdated;
  3253.         CBlockIndex* pindexPrev = pindexBest;
  3254.         unsigned int nBits = GetNextWorkRequired(pindexPrev);
  3255.         CTransaction txNew;
  3256.         txNew.vin.resize(1);
  3257.         txNew.vin[0].prevout.SetNull();
  3258.         txNew.vin[0].scriptSig << nBits << ++bnExtraNonce;
  3259.         txNew.vout.resize(1);
  3260.         txNew.vout[0].scriptPubKey << key.GetPubKey() << OP_CHECKSIG;
  3261.         auto_ptr<CBlock> pblock(new CBlock());
  3262.         if (!pblock.get())
  3263.             return false;
  3264.         pblock->vtx.push_back(txNew);
  3265.         int64 nFees = 0;
  3266.         CRITICAL_BLOCK(cs_main)
  3267.         CRITICAL_BLOCK(cs_mapTransactions)
  3268.         {
  3269.             CTxDB txdb("r");
  3270.             map<uint256, CTxIndex> mapTestPool;
  3271.             vector<char> vfAlreadyAdded(mapTransactions.size());
  3272.             bool fFoundSomething = true;
  3273.             unsigned int nBlockSize = 0;
  3274.             while (fFoundSomething && nBlockSize < MAX_SIZE/2)
  3275.             {
  3276.                 fFoundSomething = false;
  3277.                 unsigned int n = 0;
  3278.                 for (map<uint256, CTransaction>::iterator mi = mapTransactions.begin(); mi != mapTransactions.end(); ++mi, ++n)
  3279.                 {
  3280.                     if (vfAlreadyAdded[n])
  3281.                         continue;
  3282.                     CTransaction& tx = (*mi).second;
  3283.                     if (tx.IsCoinBase() || !tx.IsFinal())
  3284.                         continue;
  3285.                     int64 nMinFee = tx.GetMinFee(pblock->vtx.size() < 100);
  3286.  
  3287.                     map<uint256, CTxIndex> mapTestPoolTmp(mapTestPool);
  3288.                     if (!tx.ConnectInputs(txdb, mapTestPoolTmp, CDiskTxPos(1,1,1), 0, nFees, false, true, nMinFee))
  3289.                         continue;
  3290.                     swap(mapTestPool, mapTestPoolTmp);
  3291.  
  3292.                     pblock->vtx.push_back(tx);
  3293.                     nBlockSize += ::GetSerializeSize(tx, SER_NETWORK);
  3294.                     vfAlreadyAdded[n] = true;
  3295.                     fFoundSomething = true;
  3296.                 }
  3297.             }
  3298.         }
  3299.         pblock->nBits = nBits;
  3300.         pblock->vtx[0].vout[0].nValue = pblock->GetBlockValue(nFees);
  3301.         printf("\n\nRunning BitcoinMiner with %d transactions in block\n", pblock->vtx.size());
  3302.         struct unnamed1
  3303.         {
  3304.             struct unnamed2
  3305.             {
  3306.                 int nVersion;
  3307.                 uint256 hashPrevBlock;
  3308.                 uint256 hashMerkleRoot;
  3309.                 unsigned int nTime;
  3310.                 unsigned int nBits;
  3311.                 unsigned int nNonce;
  3312.             }
  3313.             block;
  3314.             unsigned char pchPadding0[64];
  3315.             uint256 hash1;
  3316.             unsigned char pchPadding1[64];
  3317.         }
  3318.         tmp;
  3319.         tmp.block.nVersion       = pblock->nVersion;
  3320.         tmp.block.hashPrevBlock  = pblock->hashPrevBlock  = (pindexPrev ? pindexPrev->GetBlockHash() : 0);
  3321.         tmp.block.hashMerkleRoot = pblock->hashMerkleRoot = pblock->BuildMerkleTree();
  3322.         tmp.block.nTime          = pblock->nTime          = max((pindexPrev ? pindexPrev->GetMedianTimePast()+1 : 0), GetAdjustedTime());
  3323.         tmp.block.nBits          = pblock->nBits          = nBits;
  3324.         tmp.block.nNonce         = pblock->nNonce         = 1;
  3325.         unsigned int nBlocks0 = FormatHashBlocks(&tmp.block, sizeof(tmp.block));
  3326.         unsigned int nBlocks1 = FormatHashBlocks(&tmp.hash1, sizeof(tmp.hash1));
  3327.         unsigned int nStart = GetTime();
  3328.         uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
  3329.         uint256 hash;
  3330.         loop
  3331.         {
  3332.             BlockSHA256(&tmp.block, nBlocks0, &tmp.hash1);
  3333.             BlockSHA256(&tmp.hash1, nBlocks1, &hash);
  3334.             if (hash <= hashTarget)
  3335.             {
  3336.                 pblock->nNonce = tmp.block.nNonce;
  3337.                 assert(hash == pblock->GetHash());
  3338.                     printf("BitcoinMiner:\n");
  3339.                     printf("proof-of-work found  \n  hash: %s  \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str());
  3340.                     pblock->print();
  3341.  
  3342.                 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
  3343.                 CRITICAL_BLOCK(cs_main)
  3344.                 {
  3345.                     if (!AddKey(key))
  3346.                         return false;
  3347.                     key.MakeNewKey();
  3348.                     if (!ProcessBlock(NULL, pblock.release()))
  3349.                         printf("ERROR in BitcoinMiner, ProcessBlock, block not accepted\n");
  3350.                 }
  3351.                 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST);
  3352.                 Sleep(500);
  3353.                 break;
  3354.             }
  3355.             if ((++tmp.block.nNonce & 0x3ffff) == 0)
  3356.             {
  3357.                 CheckForShutdown(3);
  3358.                 if (tmp.block.nNonce == 0)
  3359.                     break;
  3360.                 if (pindexPrev != pindexBest)
  3361.                     break;
  3362.                 if (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60)
  3363.                     break;
  3364.                 if (!fGenerateBitcoins)
  3365.                     break;
  3366.                 tmp.block.nTime = pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
  3367.             }
  3368.         }
  3369.     }
  3370.     return true;
  3371. }
  3372. int64 GetBalance()
  3373. {
  3374.     int64 nStart, nEnd;
  3375.     QueryPerformanceCounter((LARGE_INTEGER*)&nStart);
  3376.     int64 nTotal = 0;
  3377.     CRITICAL_BLOCK(cs_mapWallet)
  3378.     {
  3379.         for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
  3380.         {
  3381.             CWalletTx* pcoin = &(*it).second;
  3382.             if (!pcoin->IsFinal() || pcoin->fSpent)
  3383.                 continue;
  3384.             nTotal += pcoin->GetCredit();
  3385.         }
  3386.     }
  3387.     QueryPerformanceCounter((LARGE_INTEGER*)&nEnd);
  3388.     return nTotal;
  3389. }
  3390. bool SelectCoins(int64 nTargetValue, set<CWalletTx*>& setCoinsRet)
  3391. {
  3392.     setCoinsRet.clear();
  3393.     int64 nLowestLarger = _I64_MAX;
  3394.     CWalletTx* pcoinLowestLarger = NULL;
  3395.     vector<pair<int64, CWalletTx*> > vValue;
  3396.     int64 nTotalLower = 0;
  3397.     CRITICAL_BLOCK(cs_mapWallet)
  3398.     {
  3399.         for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
  3400.         {
  3401.             CWalletTx* pcoin = &(*it).second;
  3402.             if (!pcoin->IsFinal() || pcoin->fSpent)
  3403.                 continue;
  3404.             int64 n = pcoin->GetCredit();
  3405.             if (n <= 0)
  3406.                 continue;
  3407.             if (n < nTargetValue)
  3408.             {
  3409.                 vValue.push_back(make_pair(n, pcoin));
  3410.                 nTotalLower += n;
  3411.             }
  3412.             else if (n == nTargetValue)
  3413.             {
  3414.                 setCoinsRet.insert(pcoin);
  3415.                 return true;
  3416.             }
  3417.             else if (n < nLowestLarger)
  3418.             {
  3419.                 nLowestLarger = n;
  3420.                 pcoinLowestLarger = pcoin;
  3421.             }
  3422.         }
  3423.     }
  3424.     if (nTotalLower < nTargetValue)
  3425.     {
  3426.         if (pcoinLowestLarger == NULL)
  3427.             return false;
  3428.         setCoinsRet.insert(pcoinLowestLarger);
  3429.         return true;
  3430.     }
  3431.     sort(vValue.rbegin(), vValue.rend());
  3432.     vector<char> vfIncluded;
  3433.     vector<char> vfBest(vValue.size(), true);
  3434.     int64 nBest = nTotalLower;
  3435.     for (int nRep = 0; nRep < 1000 && nBest != nTargetValue; nRep++)
  3436.     {
  3437.         vfIncluded.assign(vValue.size(), false);
  3438.         int64 nTotal = 0;
  3439.         bool fReachedTarget = false;
  3440.         for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++)
  3441.         {
  3442.             for (int i = 0; i < vValue.size(); i++)
  3443.             {
  3444.                 if (nPass == 0 ? rand() % 2 : !vfIncluded[i])
  3445.                 {
  3446.                     nTotal += vValue[i].first;
  3447.                     vfIncluded[i] = true;
  3448.                     if (nTotal >= nTargetValue)
  3449.                     {
  3450.                         fReachedTarget = true;
  3451.                         if (nTotal < nBest)
  3452.                         {
  3453.                             nBest = nTotal;
  3454.                             vfBest = vfIncluded;
  3455.                         }
  3456.                         nTotal -= vValue[i].first;
  3457.                         vfIncluded[i] = false;
  3458.                     }
  3459.                 }
  3460.             }
  3461.         }
  3462.     }
  3463.     if (pcoinLowestLarger && nLowestLarger - nTargetValue <= nBest - nTargetValue)
  3464.         setCoinsRet.insert(pcoinLowestLarger);
  3465.     else
  3466.     {
  3467.         for (int i = 0; i < vValue.size(); i++)
  3468.             if (vfBest[i])
  3469.                 setCoinsRet.insert(vValue[i].second);
  3470.  
  3471.         printf("SelectCoins() best subset: ");
  3472.         for (int i = 0; i < vValue.size(); i++)
  3473.             if (vfBest[i])
  3474.                 printf("%s ", FormatMoney(vValue[i].first).c_str());
  3475.         printf("total %s\n", FormatMoney(nBest).c_str());
  3476.     }
  3477.     return true;
  3478. }
  3479. bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, int64& nFeeRequiredRet)
  3480. {
  3481.     nFeeRequiredRet = 0;
  3482.     CRITICAL_BLOCK(cs_main)
  3483.     {
  3484.         CTxDB txdb("r");
  3485.         CRITICAL_BLOCK(cs_mapWallet)
  3486.         {
  3487.             int64 nFee = nTransactionFee;
  3488.             loop
  3489.             {
  3490.                 wtxNew.vin.clear();
  3491.                 wtxNew.vout.clear();
  3492.                 if (nValue < 0)
  3493.                     return false;
  3494.                 int64 nValueOut = nValue;
  3495.                 nValue += nFee;
  3496.  
  3497.                 set<CWalletTx*> setCoins;
  3498.                 if (!SelectCoins(nValue, setCoins))
  3499.                     return false;
  3500.                 int64 nValueIn = 0;
  3501.                 foreach(CWalletTx* pcoin, setCoins)
  3502.                     nValueIn += pcoin->GetCredit();
  3503.                 wtxNew.vout.push_back(CTxOut(nValueOut, scriptPubKey));
  3504.                 if (nValueIn > nValue)
  3505.                 {
  3506.                     vector<unsigned char> vchPubKey;
  3507.                     CTransaction& txFirst = *(*setCoins.begin());
  3508.                     foreach(const CTxOut& txout, txFirst.vout)
  3509.                         if (txout.IsMine())
  3510.                             if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey))
  3511.                                 break;
  3512.                     if (vchPubKey.empty())
  3513.                         return false;
  3514.                     CScript scriptPubKey;
  3515.                     scriptPubKey << vchPubKey << OP_CHECKSIG;
  3516.                     wtxNew.vout.push_back(CTxOut(nValueIn - nValue, scriptPubKey));
  3517.                 }
  3518.                 foreach(CWalletTx* pcoin, setCoins)
  3519.                     for (int nOut = 0; nOut < pcoin->vout.size(); nOut++)
  3520.                         if (pcoin->vout[nOut].IsMine())
  3521.                             wtxNew.vin.push_back(CTxIn(pcoin->GetHash(), nOut));
  3522.                 int nIn = 0;
  3523.                 foreach(CWalletTx* pcoin, setCoins)
  3524.                     for (int nOut = 0; nOut < pcoin->vout.size(); nOut++)
  3525.                         if (pcoin->vout[nOut].IsMine())
  3526.                             SignSignature(*pcoin, wtxNew, nIn++);
  3527.                 if (nFee < wtxNew.GetMinFee(true))
  3528.                 {
  3529.                     nFee = nFeeRequiredRet = wtxNew.GetMinFee(true);
  3530.                     continue;
  3531.                 }
  3532.                 wtxNew.AddSupportingTransactions(txdb);
  3533.                 wtxNew.fTimeReceivedIsTxTime = true;
  3534.                 break;
  3535.             }
  3536.         }
  3537.     }
  3538.     return true;
  3539. }
  3540. bool CommitTransactionSpent(const CWalletTx& wtxNew)
  3541. {
  3542.     CRITICAL_BLOCK(cs_main)
  3543.     CRITICAL_BLOCK(cs_mapWallet)
  3544.     {
  3545.        AddToWallet(wtxNew);
  3546.         set<CWalletTx*> setCoins;
  3547.         foreach(const CTxIn& txin, wtxNew.vin)
  3548.             setCoins.insert(&mapWallet[txin.prevout.hash]);
  3549.         foreach(CWalletTx* pcoin, setCoins)
  3550.         {
  3551.             pcoin->fSpent = true;
  3552.             pcoin->WriteToDisk();
  3553.             vWalletUpdated.push_back(make_pair(pcoin->GetHash(), false));
  3554.         }
  3555.     }
  3556.     MainFrameRepaint();
  3557.     return true;
  3558. }
  3559. bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew)
  3560. {
  3561.     CRITICAL_BLOCK(cs_main)
  3562.     {
  3563.         int64 nFeeRequired;
  3564.         if (!CreateTransaction(scriptPubKey, nValue, wtxNew, nFeeRequired))
  3565.         {
  3566.             string strError;
  3567.             if (nValue + nFeeRequired > GetBalance())
  3568.                 strError = strprintf("Error: This is an oversized transaction that requires a transaction fee of %s ", FormatMoney(nFeeRequired).c_str());
  3569.             else
  3570.                 strError = "Error: Transaction creation failed ";
  3571.             wxMessageBox(strError, "Sending...");
  3572.             return error("SendMoney() : %s\n", strError.c_str());
  3573.         }
  3574.         if (!CommitTransactionSpent(wtxNew))
  3575.         {
  3576.             wxMessageBox("Error finalizing transaction", "Sending...");
  3577.             return error("SendMoney() : Error finalizing transaction");
  3578.         }
  3579.         printf("SendMoney: %s\n", wtxNew.GetHash().ToString().substr(0,6).c_str());
  3580.         if (!wtxNew.AcceptTransaction())
  3581.         {
  3582.             throw runtime_error("SendMoney() : wtxNew.AcceptTransaction() failed\n");
  3583.             wxMessageBox("Error: Transaction not valid", "Sending...");
  3584.             return error("SendMoney() : Error: Transaction not valid");
  3585.         }
  3586.         wtxNew.RelayWalletTransaction();
  3587.     }
  3588.     MainFrameRepaint();
  3589.     return true;
  3590. }
  3591. class COutPoint;
  3592. class CInPoint;
  3593. class CDiskTxPos;
  3594. class CCoinBase;
  3595. class CTxIn;
  3596. class CTxOut;
  3597. class CTransaction;
  3598. class CBlock;
  3599. class CBlockIndex;
  3600. class CWalletTx;
  3601. class CKeyItem;
  3602. static const unsigned int MAX_SIZE = 0x02000000;
  3603. static const int64 COIN = 100000000;
  3604. static const int64 CENT = 1000000;
  3605. static const int COINBASE_MATURITY = 100;
  3606. static const CBigNum bnProofOfWorkLimit(~uint256(0) >> 32);
  3607. extern CCriticalSection cs_main;
  3608. extern map<uint256, CBlockIndex*> mapBlockIndex;
  3609. extern const uint256 hashGenesisBlock;
  3610. extern CBlockIndex* pindexGenesisBlock;
  3611. extern int nBestHeight;
  3612. extern uint256 hashBestChain;
  3613. extern CBlockIndex* pindexBest;
  3614. extern unsigned int nTransactionsUpdated;
  3615. extern string strSetDataDir;
  3616. extern int nDropMessagesTest;
  3617. extern int fGenerateBitcoins;
  3618. extern int64 nTransactionFee;
  3619. extern CAddress addrIncoming;
  3620. string GetAppDir();
  3621. FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb");
  3622. FILE* AppendBlockFile(unsigned int& nFileRet);
  3623. bool AddKey(const CKey& key);
  3624. vector<unsigned char> GenerateNewKey();
  3625. bool AddToWallet(const CWalletTx& wtxIn);
  3626. void ReacceptWalletTransactions();
  3627. void RelayWalletTransactions();
  3628. bool LoadBlockIndex(bool fAllowNew=true);
  3629. void PrintBlockTree();
  3630. bool BitcoinMiner();
  3631. bool ProcessMessages(CNode* pfrom);
  3632. bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv);
  3633. bool SendMessages(CNode* pto);
  3634. int64 GetBalance();
  3635. bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& txNew, int64& nFeeRequiredRet);
  3636. bool CommitTransactionSpent(const CWalletTx& wtxNew);
  3637. bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew);
  3638. class CDiskTxPos
  3639. {
  3640. public:
  3641.     unsigned int nFile;
  3642.     unsigned int nBlockPos;
  3643.     unsigned int nTxPos;
  3644.     CDiskTxPos()
  3645.     {
  3646.         SetNull();
  3647.     }
  3648.     CDiskTxPos(unsigned int nFileIn, unsigned int nBlockPosIn, unsigned int nTxPosIn)
  3649.     {
  3650.         nFile = nFileIn;
  3651.         nBlockPos = nBlockPosIn;
  3652.         nTxPos = nTxPosIn;
  3653.     }
  3654.     IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); )
  3655.     void SetNull() { nFile = -1; nBlockPos = 0; nTxPos = 0; }
  3656.     bool IsNull() const { return (nFile == -1); }
  3657.     friend bool operator==(const CDiskTxPos& a, const CDiskTxPos& b)
  3658.     {
  3659.         return (a.nFile     == b.nFile &&
  3660.                 a.nBlockPos == b.nBlockPos &&
  3661.                 a.nTxPos    == b.nTxPos);
  3662.     }
  3663.     friend bool operator!=(const CDiskTxPos& a, const CDiskTxPos& b)
  3664.     {
  3665.         return !(a == b);
  3666.     }
  3667.     string ToString() const
  3668.     {
  3669.         if (IsNull())
  3670.             return strprintf("null");
  3671.         else
  3672.             return strprintf("(nFile=%d, nBlockPos=%d, nTxPos=%d)", nFile, nBlockPos, nTxPos);
  3673.     }
  3674.     void print() const
  3675.     {
  3676.         printf("%s", ToString().c_str());
  3677.     }
  3678. };
  3679. class CInPoint
  3680. {
  3681. public:
  3682.     CTransaction* ptx;
  3683.     unsigned int n;
  3684.     CInPoint() { SetNull(); }
  3685.     CInPoint(CTransaction* ptxIn, unsigned int nIn) { ptx = ptxIn; n = nIn; }
  3686.     void SetNull() { ptx = NULL; n = -1; }
  3687.     bool IsNull() const { return (ptx == NULL && n == -1); }
  3688. };
  3689. class COutPoint
  3690. {
  3691. public:
  3692.     uint256 hash;
  3693.     unsigned int n;
  3694.     COutPoint() { SetNull(); }
  3695.     COutPoint(uint256 hashIn, unsigned int nIn) { hash = hashIn; n = nIn; }
  3696.     IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); )
  3697.     void SetNull() { hash = 0; n = -1; }
  3698.     bool IsNull() const { return (hash == 0 && n == -1); }
  3699.     friend bool operator<(const COutPoint& a, const COutPoint& b)
  3700.     {
  3701.         return (a.hash < b.hash || (a.hash == b.hash && a.n < b.n));
  3702.     }
  3703.     friend bool operator==(const COutPoint& a, const COutPoint& b)
  3704.     {
  3705.         return (a.hash == b.hash && a.n == b.n);
  3706.     }
  3707.     friend bool operator!=(const COutPoint& a, const COutPoint& b)
  3708.     {
  3709.         return !(a == b);
  3710.     }
  3711.     string ToString() const
  3712.     {
  3713.         return strprintf("COutPoint(%s, %d)", hash.ToString().substr(0,6).c_str(), n);
  3714.     }
  3715.     void print() const
  3716.     {
  3717.         printf("%s\n", ToString().c_str());
  3718.     }
  3719. };
  3720. class CTxIn
  3721. {
  3722. public:
  3723.     COutPoint prevout;
  3724.     CScript scriptSig;
  3725.     unsigned int nSequence;
  3726.     CTxIn()
  3727.     {
  3728.         nSequence = UINT_MAX;
  3729.     }
  3730.     explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX)
  3731.     {
  3732.         prevout = prevoutIn;
  3733.         scriptSig = scriptSigIn;
  3734.         nSequence = nSequenceIn;
  3735.     }
  3736.     CTxIn(uint256 hashPrevTx, unsigned int nOut, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX)
  3737.     {
  3738.         prevout = COutPoint(hashPrevTx, nOut);
  3739.         scriptSig = scriptSigIn;
  3740.         nSequence = nSequenceIn;
  3741.     }
  3742.     IMPLEMENT_SERIALIZE
  3743.     (
  3744.         READWRITE(prevout);
  3745.         READWRITE(scriptSig);
  3746.         READWRITE(nSequence);
  3747.     )
  3748.     bool IsFinal() const
  3749.     {
  3750.         return (nSequence == UINT_MAX);
  3751.     }
  3752.     friend bool operator==(const CTxIn& a, const CTxIn& b)
  3753.     {
  3754.         return (a.prevout   == b.prevout &&
  3755.                 a.scriptSig == b.scriptSig &&
  3756.                 a.nSequence == b.nSequence);
  3757.     }
  3758.     friend bool operator!=(const CTxIn& a, const CTxIn& b)
  3759.     {
  3760.         return !(a == b);
  3761.     }
  3762.     string ToString() const
  3763.     {
  3764.         string str;
  3765.         str += strprintf("CTxIn(");
  3766.         str += prevout.ToString();
  3767.         if (prevout.IsNull())
  3768.             str += strprintf(", coinbase %s", HexStr(scriptSig.begin(), scriptSig.end(), false).c_str());
  3769.         else
  3770.             str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24).c_str());
  3771.         if (nSequence != UINT_MAX)
  3772.             str += strprintf(", nSequence=%u", nSequence);
  3773.         str += ")";
  3774.         return str;
  3775.     }
  3776.     void print() const
  3777.     {
  3778.         printf("%s\n", ToString().c_str());
  3779.     }
  3780.     bool IsMine() const;
  3781.     int64 GetDebit() const;
  3782. };
  3783. class CTxOut
  3784. {
  3785. public:
  3786.     int64 nValue;
  3787.     CScript scriptPubKey;
  3788. public:
  3789.     CTxOut()
  3790.     {
  3791.         SetNull();
  3792.     }
  3793.     CTxOut(int64 nValueIn, CScript scriptPubKeyIn)
  3794.     {
  3795.         nValue = nValueIn;
  3796.         scriptPubKey = scriptPubKeyIn;
  3797.     }
  3798.     IMPLEMENT_SERIALIZE
  3799.     (
  3800.         READWRITE(nValue);
  3801.         READWRITE(scriptPubKey);
  3802.     )
  3803.     void SetNull()
  3804.     {
  3805.         nValue = -1;
  3806.         scriptPubKey.clear();
  3807.     }
  3808.     bool IsNull()
  3809.     {
  3810.         return (nValue == -1);
  3811.     }
  3812.     uint256 GetHash() const
  3813.     {
  3814.         return SerializeHash(*this);
  3815.     }
  3816.     bool IsMine() const
  3817.     {
  3818.         return ::IsMine(scriptPubKey);
  3819.     }
  3820.     int64 GetCredit() const
  3821.     {
  3822.         if (IsMine())
  3823.             return nValue;
  3824.         return 0;
  3825.     }
  3826.     friend bool operator==(const CTxOut& a, const CTxOut& b)
  3827.     {
  3828.         return (a.nValue       == b.nValue &&
  3829.                 a.scriptPubKey == b.scriptPubKey);
  3830.     }
  3831.     friend bool operator!=(const CTxOut& a, const CTxOut& b)
  3832.     {
  3833.         return !(a == b);
  3834.     }
  3835.     string ToString() const
  3836.     {
  3837.         if (scriptPubKey.size() < 6)
  3838.             return "CTxOut(error)";
  3839.         return strprintf("CTxOut(nValue=%I64d.%08I64d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,24).c_str());
  3840.     }
  3841.     void print() const
  3842.     {
  3843.         printf("%s\n", ToString().c_str());
  3844.     }
  3845. };
  3846. class CTransaction
  3847. {
  3848. public:
  3849.     int nVersion;
  3850.     vector<CTxIn> vin;
  3851.     vector<CTxOut> vout;
  3852.     int nLockTime;
  3853.     CTransaction()
  3854.     {
  3855.         SetNull();
  3856.     }
  3857.     IMPLEMENT_SERIALIZE
  3858.     (
  3859.         READWRITE(this->nVersion);
  3860.         nVersion = this->nVersion;
  3861.         READWRITE(vin);
  3862.         READWRITE(vout);
  3863.         READWRITE(nLockTime);
  3864.     )
  3865.     void SetNull()
  3866.     {
  3867.         nVersion = 1;
  3868.         vin.clear();
  3869.         vout.clear();
  3870.         nLockTime = 0;
  3871.     }
  3872.     bool IsNull() const
  3873.     {
  3874.         return (vin.empty() && vout.empty());
  3875.     }
  3876.     uint256 GetHash() const
  3877.     {
  3878.         return SerializeHash(*this);
  3879.     }
  3880.     bool IsFinal() const
  3881.     {
  3882.         if (nLockTime == 0 || nLockTime < nBestHeight)
  3883.             return true;
  3884.         foreach(const CTxIn& txin, vin)
  3885.             if (!txin.IsFinal())
  3886.                 return false;
  3887.         return true;
  3888.     }
  3889.     bool IsNewerThan(const CTransaction& old) const
  3890.     {
  3891.         if (vin.size() != old.vin.size())
  3892.             return false;
  3893.         for (int i = 0; i < vin.size(); i++)
  3894.             if (vin[i].prevout != old.vin[i].prevout)
  3895.                 return false;
  3896.         bool fNewer = false;
  3897.         unsigned int nLowest = UINT_MAX;
  3898.         for (int i = 0; i < vin.size(); i++)
  3899.         {
  3900.             if (vin[i].nSequence != old.vin[i].nSequence)
  3901.             {
  3902.                 if (vin[i].nSequence <= nLowest)
  3903.                 {
  3904.                     fNewer = false;
  3905.                     nLowest = vin[i].nSequence;
  3906.                 }
  3907.                 if (old.vin[i].nSequence < nLowest)
  3908.                 {
  3909.                     fNewer = true;
  3910.                     nLowest = old.vin[i].nSequence;
  3911.                 }
  3912.             }
  3913.         }
  3914.         return fNewer;
  3915.     }
  3916.     bool IsCoinBase() const
  3917.     {
  3918.         return (vin.size() == 1 && vin[0].prevout.IsNull());
  3919.     }
  3920.     bool CheckTransaction() const
  3921.     {
  3922.         if (vin.empty() || vout.empty())
  3923.             return error("CTransaction::CheckTransaction() : vin or vout empty");
  3924.         foreach(const CTxOut& txout, vout)
  3925.             if (txout.nValue < 0)
  3926.                 return error("CTransaction::CheckTransaction() : txout.nValue negative");
  3927.         if (IsCoinBase())
  3928.         {
  3929.             if (vin[0].scriptSig.size() < 2 || vin[0].scriptSig.size() > 100)
  3930.                 return error("CTransaction::CheckTransaction() : coinbase script size");
  3931.         }
  3932.         else
  3933.         {
  3934.             foreach(const CTxIn& txin, vin)
  3935.                 if (txin.prevout.IsNull())
  3936.                     return error("CTransaction::CheckTransaction() : prevout is null");
  3937.         }
  3938.         return true;
  3939.     }
  3940.     bool IsMine() const
  3941.     {
  3942.         foreach(const CTxOut& txout, vout)
  3943.             if (txout.IsMine())
  3944.                 return true;
  3945.         return false;
  3946.     }
  3947.     int64 GetDebit() const
  3948.     {
  3949.         int64 nDebit = 0;
  3950.         foreach(const CTxIn& txin, vin)
  3951.             nDebit += txin.GetDebit();
  3952.         return nDebit;
  3953.     }
  3954.     int64 GetCredit() const
  3955.     {
  3956.         int64 nCredit = 0;
  3957.         foreach(const CTxOut& txout, vout)
  3958.             nCredit += txout.GetCredit();
  3959.         return nCredit;
  3960.     }
  3961.     int64 GetValueOut() const
  3962.     {
  3963.         int64 nValueOut = 0;
  3964.         foreach(const CTxOut& txout, vout)
  3965.         {
  3966.             if (txout.nValue < 0)
  3967.                 throw runtime_error("CTransaction::GetValueOut() : negative value");
  3968.             nValueOut += txout.nValue;
  3969.         }
  3970.         return nValueOut;
  3971.     }
  3972.     int64 GetMinFee(bool fDiscount=false) const
  3973.     {
  3974.         unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK);
  3975.         if (fDiscount && nBytes < 10000)
  3976.             return 0;
  3977.         return (1 + (int64)nBytes / 1000) * CENT;
  3978.     }
  3979.     bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL)
  3980.     {
  3981.         CAutoFile filein = OpenBlockFile(pos.nFile, 0, pfileRet ? "rb+" : "rb");
  3982.         if (!filein)
  3983.             return error("CTransaction::ReadFromDisk() : OpenBlockFile failed");
  3984.         if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)
  3985.             return error("CTransaction::ReadFromDisk() : fseek failed");
  3986.         filein >> *this;
  3987.         if (pfileRet)
  3988.         {
  3989.             if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)
  3990.                 return error("CTransaction::ReadFromDisk() : second fseek failed");
  3991.             *pfileRet = filein.release();
  3992.         }
  3993.         return true;
  3994.     }
  3995.     friend bool operator==(const CTransaction& a, const CTransaction& b)
  3996.     {
  3997.         return (a.nVersion  == b.nVersion &&
  3998.                 a.vin       == b.vin &&
  3999.                 a.vout      == b.vout &&
  4000.                 a.nLockTime == b.nLockTime);
  4001.     }
  4002.     friend bool operator!=(const CTransaction& a, const CTransaction& b)
  4003.     {
  4004.         return !(a == b);
  4005.     }
  4006.     string ToString() const
  4007.     {
  4008.         string str;
  4009.         str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%d, vout.size=%d, nLockTime=%d)\n",
  4010.             GetHash().ToString().substr(0,6).c_str(),
  4011.             nVersion,
  4012.             vin.size(),
  4013.             vout.size(),
  4014.             nLockTime);
  4015.         for (int i = 0; i < vin.size(); i++)
  4016.             str += "    " + vin[i].ToString() + "\n";
  4017.         for (int i = 0; i < vout.size(); i++)
  4018.             str += "    " + vout[i].ToString() + "\n";
  4019.         return str;
  4020.     }
  4021.     void print() const
  4022.     {
  4023.         printf("%s", ToString().c_str());
  4024.     }
  4025.     bool DisconnectInputs(CTxDB& txdb);
  4026.     bool ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPool, CDiskTxPos posThisTx, int nHeight, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee=0);
  4027.     bool ClientConnectInputs();
  4028.     bool AcceptTransaction(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL);
  4029.     bool AcceptTransaction(bool fCheckInputs=true, bool* pfMissingInputs=NULL)
  4030.     {
  4031.         CTxDB txdb("r");
  4032.         return AcceptTransaction(txdb, fCheckInputs, pfMissingInputs);
  4033.     }
  4034. protected:
  4035.     bool AddToMemoryPool();
  4036. public:
  4037.     bool RemoveFromMemoryPool();
  4038. };
  4039. class CMerkleTx : public CTransaction
  4040. {
  4041. public:
  4042.     uint256 hashBlock;
  4043.     vector<uint256> vMerkleBranch;
  4044.     int nIndex;
  4045.     mutable bool fMerkleVerified;
  4046.     CMerkleTx()
  4047.     {
  4048.         Init();
  4049.     }
  4050.     CMerkleTx(const CTransaction& txIn) : CTransaction(txIn)
  4051.     {
  4052.         Init();
  4053.     }
  4054.     void Init()
  4055.     {
  4056.         hashBlock = 0;
  4057.         nIndex = -1;
  4058.         fMerkleVerified = false;
  4059.     }
  4060.     int64 GetCredit() const
  4061.     {
  4062.         if (IsCoinBase() && GetBlocksToMaturity() > 0)
  4063.             return 0;
  4064.         return CTransaction::GetCredit();
  4065.     }
  4066.     IMPLEMENT_SERIALIZE
  4067.     (
  4068.         nSerSize += SerReadWrite(s, *(CTransaction*)this, nType, nVersion, ser_action);
  4069.         nVersion = this->nVersion;
  4070.         READWRITE(hashBlock);
  4071.         READWRITE(vMerkleBranch);
  4072.         READWRITE(nIndex);
  4073.     )
  4074.     int SetMerkleBranch(const CBlock* pblock=NULL);
  4075.     int GetDepthInMainChain() const;
  4076.     bool IsInMainChain() const { return GetDepthInMainChain() > 0; }
  4077.     int GetBlocksToMaturity() const;
  4078.     bool AcceptTransaction(CTxDB& txdb, bool fCheckInputs=true);
  4079.     bool AcceptTransaction() { CTxDB txdb("r"); return AcceptTransaction(txdb); }
  4080. };
  4081. class CWalletTx : public CMerkleTx
  4082. {
  4083. public:
  4084.     vector<CMerkleTx> vtxPrev;
  4085.     map<string, string> mapValue;
  4086.     vector<pair<string, string> > vOrderForm;
  4087.     unsigned int fTimeReceivedIsTxTime;
  4088.     unsigned int nTimeReceived;
  4089.     char fFromMe;
  4090.     char fSpent;
  4091.     mutable unsigned int nTimeDisplayed;
  4092.     CWalletTx()
  4093.     {
  4094.         Init();
  4095.     }
  4096.     CWalletTx(const CMerkleTx& txIn) : CMerkleTx(txIn)
  4097.     {
  4098.         Init();
  4099.     }
  4100.     CWalletTx(const CTransaction& txIn) : CMerkleTx(txIn)
  4101.     {
  4102.         Init();
  4103.     }
  4104.     void Init()
  4105.     {
  4106.         fTimeReceivedIsTxTime = false;
  4107.         nTimeReceived = 0;
  4108.         fFromMe = false;
  4109.         fSpent = false;
  4110.         nTimeDisplayed = 0;
  4111.     }
  4112.     IMPLEMENT_SERIALIZE
  4113.     (
  4114.         nSerSize += SerReadWrite(s, *(CMerkleTx*)this, nType, nVersion, ser_action);
  4115.         nVersion = this->nVersion;
  4116.         READWRITE(vtxPrev);
  4117.         READWRITE(mapValue);
  4118.         READWRITE(vOrderForm);
  4119.         READWRITE(fTimeReceivedIsTxTime);
  4120.         READWRITE(nTimeReceived);
  4121.         READWRITE(fFromMe);
  4122.         READWRITE(fSpent);
  4123.     )
  4124.     bool WriteToDisk()
  4125.     {
  4126.         return CWalletDB().WriteTx(GetHash(), *this);
  4127.     }
  4128.     int64 GetTxTime() const;
  4129.     void AddSupportingTransactions(CTxDB& txdb);
  4130.     bool AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs=true);
  4131.     bool AcceptWalletTransaction() { CTxDB txdb("r"); return AcceptWalletTransaction(txdb); }
  4132.     void RelayWalletTransaction(CTxDB& txdb);
  4133.     void RelayWalletTransaction() { CTxDB txdb("r"); RelayWalletTransaction(txdb); }
  4134. };
  4135. class CTxIndex
  4136. {
  4137. public:
  4138.     CDiskTxPos pos;
  4139.     vector<CDiskTxPos> vSpent;
  4140.     CTxIndex()
  4141.     {
  4142.         SetNull();
  4143.     }
  4144.     CTxIndex(const CDiskTxPos& posIn, unsigned int nOutputs)
  4145.     {
  4146.         pos = posIn;
  4147.         vSpent.resize(nOutputs);
  4148.     }
  4149.     IMPLEMENT_SERIALIZE
  4150.     (
  4151.         if (!(nType & SER_GETHASH))
  4152.         READWRITE(nVersion);
  4153.         READWRITE(pos);
  4154.         READWRITE(vSpent);
  4155.     )
  4156.     void SetNull()
  4157.     {
  4158.         pos.SetNull();
  4159.         vSpent.clear();
  4160.     }
  4161.     bool IsNull()
  4162.     {
  4163.         return pos.IsNull();
  4164.     }
  4165.     friend bool operator==(const CTxIndex& a, const CTxIndex& b)
  4166.     {
  4167.         if (a.pos != b.pos || a.vSpent.size() != b.vSpent.size())
  4168.             return false;
  4169.         for (int i = 0; i < a.vSpent.size(); i++)
  4170.             if (a.vSpent[i] != b.vSpent[i])
  4171.                 return false;
  4172.         return true;
  4173.     }
  4174.     friend bool operator!=(const CTxIndex& a, const CTxIndex& b)
  4175.     {
  4176.         return !(a == b);
  4177.     }
  4178. };
  4179. class CBlock
  4180. {
  4181. public:
  4182.     int nVersion;
  4183.     uint256 hashPrevBlock;
  4184.     uint256 hashMerkleRoot;
  4185.     unsigned int nTime;
  4186.     unsigned int nBits;
  4187.     unsigned int nNonce;
  4188.     vector<CTransaction> vtx;
  4189.     mutable vector<uint256> vMerkleTree;
  4190.     CBlock()
  4191.     {
  4192.         SetNull();
  4193.     }
  4194.     IMPLEMENT_SERIALIZE
  4195.     (
  4196.         READWRITE(this->nVersion);
  4197.         nVersion = this->nVersion;
  4198.         READWRITE(hashPrevBlock);
  4199.         READWRITE(hashMerkleRoot);
  4200.         READWRITE(nTime);
  4201.         READWRITE(nBits);
  4202.         READWRITE(nNonce);
  4203.         if (!(nType & (SER_GETHASH|SER_BLOCKHEADERONLY)))
  4204.             READWRITE(vtx);
  4205.         else if (fRead)
  4206.             const_cast<CBlock*>(this)->vtx.clear();
  4207.     )
  4208.     void SetNull()
  4209.     {
  4210.         nVersion = 1;
  4211.         hashPrevBlock = 0;
  4212.         hashMerkleRoot = 0;
  4213.         nTime = 0;
  4214.         nBits = 0;
  4215.         nNonce = 0;
  4216.         vtx.clear();
  4217.         vMerkleTree.clear();
  4218.     }
  4219.     bool IsNull() const
  4220.     {
  4221.         return (nBits == 0);
  4222.     }
  4223.     uint256 GetHash() const
  4224.     {
  4225.         return Hash(BEGIN(nVersion), END(nNonce));
  4226.     }
  4227.     uint256 BuildMerkleTree() const
  4228.     {
  4229.         vMerkleTree.clear();
  4230.         foreach(const CTransaction& tx, vtx)
  4231.             vMerkleTree.push_back(tx.GetHash());
  4232.         int j = 0;
  4233.         for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
  4234.         {
  4235.             for (int i = 0; i < nSize; i += 2)
  4236.             {
  4237.                 int i2 = min(i+1, nSize-1);
  4238.                 vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]),  END(vMerkleTree[j+i]),
  4239.                                            BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2])));
  4240.             }
  4241.             j += nSize;
  4242.         }
  4243.         return (vMerkleTree.empty() ? 0 : vMerkleTree.back());
  4244.     }
  4245.     vector<uint256> GetMerkleBranch(int nIndex) const
  4246.     {
  4247.         if (vMerkleTree.empty())
  4248.             BuildMerkleTree();
  4249.         vector<uint256> vMerkleBranch;
  4250.         int j = 0;
  4251.         for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
  4252.         {
  4253.             int i = min(nIndex^1, nSize-1);
  4254.             vMerkleBranch.push_back(vMerkleTree[j+i]);
  4255.             nIndex >>= 1;
  4256.             j += nSize;
  4257.         }
  4258.         return vMerkleBranch;
  4259.     }
  4260.     static uint256 CheckMerkleBranch(uint256 hash, const vector<uint256>& vMerkleBranch, int nIndex)
  4261.     {
  4262.         if (nIndex == -1)
  4263.             return 0;
  4264.         foreach(const uint256& otherside, vMerkleBranch)
  4265.         {
  4266.             if (nIndex & 1)
  4267.                 hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash));
  4268.             else
  4269.                 hash = Hash(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside));
  4270.             nIndex >>= 1;
  4271.         }
  4272.         return hash;
  4273.     }
  4274.     bool WriteToDisk(bool fWriteTransactions, unsigned int& nFileRet, unsigned int& nBlockPosRet)
  4275.     {
  4276.         CAutoFile fileout = AppendBlockFile(nFileRet);
  4277.         if (!fileout)
  4278.             return error("CBlock::WriteToDisk() : AppendBlockFile failed");
  4279.         if (!fWriteTransactions)
  4280.             fileout.nType |= SER_BLOCKHEADERONLY;
  4281.         unsigned int nSize = fileout.GetSerializeSize(*this);
  4282.         fileout << FLATDATA(pchMessageStart) << nSize;
  4283.         nBlockPosRet = ftell(fileout);
  4284.         if (nBlockPosRet == -1)
  4285.             return error("CBlock::WriteToDisk() : ftell failed");
  4286.         fileout << *this;
  4287.         return true;
  4288.     }
  4289.     bool ReadFromDisk(unsigned int nFile, unsigned int nBlockPos, bool fReadTransactions)
  4290.     {
  4291.         SetNull();
  4292.         CAutoFile filein = OpenBlockFile(nFile, nBlockPos, "rb");
  4293.         if (!filein)
  4294.             return error("CBlock::ReadFromDisk() : OpenBlockFile failed");
  4295.         if (!fReadTransactions)
  4296.             filein.nType |= SER_BLOCKHEADERONLY;
  4297.         filein >> *this;
  4298.         if (CBigNum().SetCompact(nBits) > bnProofOfWorkLimit)
  4299.             return error("CBlock::ReadFromDisk() : nBits errors in block header");
  4300.         if (GetHash() > CBigNum().SetCompact(nBits).getuint256())
  4301.             return error("CBlock::ReadFromDisk() : GetHash() errors in block header");
  4302.         return true;
  4303.     }
  4304.     void print() const
  4305.     {
  4306.         printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%d)\n",
  4307.             GetHash().ToString().substr(0,14).c_str(),
  4308.             nVersion,
  4309.             hashPrevBlock.ToString().substr(0,14).c_str(),
  4310.             hashMerkleRoot.ToString().substr(0,6).c_str(),
  4311.             nTime, nBits, nNonce,
  4312.             vtx.size());
  4313.         for (int i = 0; i < vtx.size(); i++)
  4314.         {
  4315.             printf("  ");
  4316.             vtx[i].print();
  4317.         }
  4318.         printf("  vMerkleTree: ");
  4319.         for (int i = 0; i < vMerkleTree.size(); i++)
  4320.             printf("%s ", vMerkleTree[i].ToString().substr(0,6).c_str());
  4321.         printf("\n");
  4322.     }
  4323.     int64 GetBlockValue(int64 nFees) const;
  4324.     bool DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex);
  4325.     bool ConnectBlock(CTxDB& txdb, CBlockIndex* pindex);
  4326.     bool ReadFromDisk(const CBlockIndex* blockindex, bool fReadTransactions);
  4327.     bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos);
  4328.     bool CheckBlock() const;
  4329.     bool AcceptBlock();
  4330. };
  4331. class CBlockIndex
  4332. {
  4333. public:
  4334.     const uint256* phashBlock;
  4335.     CBlockIndex* pprev;
  4336.     CBlockIndex* pnext;
  4337.     unsigned int nFile;
  4338.     unsigned int nBlockPos;
  4339.     int nHeight;
  4340.     int nVersion;
  4341.     uint256 hashMerkleRoot;
  4342.     unsigned int nTime;
  4343.     unsigned int nBits;
  4344.     unsigned int nNonce;
  4345.     CBlockIndex()
  4346.     {
  4347.         phashBlock = NULL;
  4348.         pprev = NULL;
  4349.         pnext = NULL;
  4350.         nFile = 0;
  4351.         nBlockPos = 0;
  4352.         nHeight = 0;
  4353.         nVersion       = 0;
  4354.         hashMerkleRoot = 0;
  4355.         nTime          = 0;
  4356.         nBits          = 0;
  4357.         nNonce         = 0;
  4358.     }
  4359.     CBlockIndex(unsigned int nFileIn, unsigned int nBlockPosIn, CBlock& block)
  4360.     {
  4361.         phashBlock = NULL;
  4362.         pprev = NULL;
  4363.         pnext = NULL;
  4364.         nFile = nFileIn;
  4365.         nBlockPos = nBlockPosIn;
  4366.         nHeight = 0;
  4367.         nVersion       = block.nVersion;
  4368.         hashMerkleRoot = block.hashMerkleRoot;
  4369.         nTime          = block.nTime;
  4370.         nBits          = block.nBits;
  4371.         nNonce         = block.nNonce;
  4372.     }
  4373.     uint256 GetBlockHash() const
  4374.     {
  4375.         return *phashBlock;
  4376.     }
  4377.     bool IsInMainChain() const
  4378.     {
  4379.         return (pnext || this == pindexBest);
  4380.     }
  4381.     bool EraseBlockFromDisk()
  4382.     {
  4383.         CAutoFile fileout = OpenBlockFile(nFile, nBlockPos, "rb+");
  4384.         if (!fileout)
  4385.             return false;
  4386.         CBlock block;
  4387.         block.SetNull();
  4388.         fileout << block;
  4389.         return true;
  4390.     }
  4391.     enum { nMedianTimeSpan=11 };
  4392.     int64 GetMedianTimePast() const
  4393.     {
  4394.         unsigned int pmedian[nMedianTimeSpan];
  4395.         unsigned int* pbegin = &pmedian[nMedianTimeSpan];
  4396.         unsigned int* pend = &pmedian[nMedianTimeSpan];
  4397.         const CBlockIndex* pindex = this;
  4398.         for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev)
  4399.             *(--pbegin) = pindex->nTime;
  4400.         sort(pbegin, pend);
  4401.         return pbegin[(pend - pbegin)/2];
  4402.     }
  4403.     int64 GetMedianTime() const
  4404.     {
  4405.         const CBlockIndex* pindex = this;
  4406.         for (int i = 0; i < nMedianTimeSpan/2; i++)
  4407.         {
  4408.             if (!pindex->pnext)
  4409.                 return nTime;
  4410.             pindex = pindex->pnext;
  4411.         }
  4412.         return pindex->GetMedianTimePast();
  4413.     }
  4414.     string ToString() const
  4415.     {
  4416.         return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)",
  4417.             pprev, pnext, nFile, nBlockPos, nHeight,
  4418.             hashMerkleRoot.ToString().substr(0,6).c_str(),
  4419.             GetBlockHash().ToString().substr(0,14).c_str());
  4420.     }
  4421.     void print() const
  4422.     {
  4423.         printf("%s\n", ToString().c_str());
  4424.     }
  4425. };
  4426. class CDiskBlockIndex : public CBlockIndex
  4427. {
  4428. public:
  4429.     uint256 hashPrev;
  4430.     uint256 hashNext;
  4431.     CDiskBlockIndex()
  4432.     {
  4433.         hashPrev = 0;
  4434.         hashNext = 0;
  4435.     }
  4436.     explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex)
  4437.     {
  4438.         hashPrev = (pprev ? pprev->GetBlockHash() : 0);
  4439.         hashNext = (pnext ? pnext->GetBlockHash() : 0);
  4440.     }
  4441.     IMPLEMENT_SERIALIZE
  4442.     (
  4443.         if (!(nType & SER_GETHASH))
  4444.         READWRITE(nVersion);
  4445.         READWRITE(hashNext);
  4446.         READWRITE(nFile);
  4447.         READWRITE(nBlockPos);
  4448.         READWRITE(nHeight);
  4449.         READWRITE(this->nVersion);
  4450.         READWRITE(hashPrev);
  4451.         READWRITE(hashMerkleRoot);
  4452.         READWRITE(nTime);
  4453.         READWRITE(nBits);
  4454.         READWRITE(nNonce);
  4455.     )
  4456.     uint256 GetBlockHash() const
  4457.     {
  4458.         CBlock block;
  4459.         block.nVersion        = nVersion;
  4460.         block.hashPrevBlock   = hashPrev;
  4461.         block.hashMerkleRoot  = hashMerkleRoot;
  4462.         block.nTime           = nTime;
  4463.         block.nBits           = nBits;
  4464.         block.nNonce          = nNonce;
  4465.         return block.GetHash();
  4466.     }
  4467.     string ToString() const
  4468.     {
  4469.         string str = "CDiskBlockIndex(";
  4470.         str += CBlockIndex::ToString();
  4471.         str += strprintf("\n                hashBlock=%s, hashPrev=%s, hashNext=%s)",
  4472.             GetBlockHash().ToString().c_str(),
  4473.             hashPrev.ToString().substr(0,14).c_str(),
  4474.             hashNext.ToString().substr(0,14).c_str());
  4475.         return str;
  4476.     }
  4477.     void print() const
  4478.     {
  4479.         printf("%s\n", ToString().c_str());
  4480.     }
  4481. };
  4482. class CBlockLocator
  4483. {
  4484. protected:
  4485.     vector<uint256> vHave;
  4486. public:
  4487.     CBlockLocator()
  4488.     {
  4489.     }
  4490.     explicit CBlockLocator(const CBlockIndex* pindex)
  4491.     {
  4492.         Set(pindex);
  4493.     }
  4494.     explicit CBlockLocator(uint256 hashBlock)
  4495.     {
  4496.         map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
  4497.         if (mi != mapBlockIndex.end())
  4498.             Set((*mi).second);
  4499.     }
  4500.     IMPLEMENT_SERIALIZE
  4501.     (
  4502.         if (!(nType & SER_GETHASH))
  4503.             READWRITE(nVersion);
  4504.         READWRITE(vHave);
  4505.     )
  4506.     void Set(const CBlockIndex* pindex)
  4507.     {
  4508.         vHave.clear();
  4509.         int nStep = 1;
  4510.         while (pindex)
  4511.         {
  4512.             vHave.push_back(pindex->GetBlockHash());
  4513.  
  4514.             for (int i = 0; pindex && i < nStep; i++)
  4515.                 pindex = pindex->pprev;
  4516.             if (vHave.size() > 10)
  4517.                 nStep *= 2;
  4518.         }
  4519.         vHave.push_back(hashGenesisBlock);
  4520.     }
  4521.     CBlockIndex* GetBlockIndex()
  4522.     {
  4523.         foreach(const uint256& hash, vHave)
  4524.         {
  4525.             map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
  4526.             if (mi != mapBlockIndex.end())
  4527.             {
  4528.                 CBlockIndex* pindex = (*mi).second;
  4529.                 if (pindex->IsInMainChain())
  4530.                     return pindex;
  4531.             }
  4532.         }
  4533.         return pindexGenesisBlock;
  4534.     }
  4535.     uint256 GetBlockHash()
  4536.     {
  4537.      foreach(const uint256& hash, vHave)
  4538.         {
  4539.             map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
  4540.             if (mi != mapBlockIndex.end())
  4541.             {
  4542.                 CBlockIndex* pindex = (*mi).second;
  4543.                 if (pindex->IsInMainChain())
  4544.                     return hash;
  4545.             }
  4546.         }
  4547.         return hashGenesisBlock;
  4548.     }
  4549.     int GetHeight()
  4550.     {
  4551.         CBlockIndex* pindex = GetBlockIndex();
  4552.         if (!pindex)
  4553.             return 0;
  4554.         return pindex->nHeight;
  4555.     }
  4556. };
  4557. extern map<uint256, CTransaction> mapTransactions;
  4558. extern map<uint256, CWalletTx> mapWallet;
  4559. extern vector<pair<uint256, bool> > vWalletUpdated;
  4560. extern CCriticalSection cs_mapWallet;
  4561. extern map<vector<unsigned char>, CPrivKey> mapKeys;
  4562. extern map<uint160, vector<unsigned char> > mapPubKeys;
  4563. extern CCriticalSection cs_mapKeys;
  4564. extern CKey keyUser;
  4565. #include "headers.h"
  4566. map<uint256, CProduct> mapMyProducts;
  4567. map<uint256, CProduct> mapProducts;
  4568. CCriticalSection cs_mapProducts;
  4569. bool AdvertInsert(const CProduct& product)
  4570. {
  4571.     uint256 hash = product.GetHash();
  4572.     bool fNew = false;
  4573.     bool fUpdated = false;
  4574.     CRITICAL_BLOCK(cs_mapProducts)
  4575.     {
  4576.         pair<map<uint256, CProduct>::iterator, bool> item = mapProducts.insert(make_pair(hash, product));
  4577.         CProduct* pproduct = &(*(item.first)).second;
  4578.         fNew = item.second;
  4579.         if (product.nSequence > pproduct->nSequence)
  4580.         {
  4581.             *pproduct = product;
  4582.             fUpdated = true;
  4583.         }
  4584.     }
  4585.     return (fNew || fUpdated);
  4586. }
  4587. void AdvertErase(const CProduct& product)
  4588. {
  4589.     uint256 hash = product.GetHash();
  4590.     CRITICAL_BLOCK(cs_mapProducts)
  4591.         mapProducts.erase(hash);
  4592. }
  4593. template<typename T>
  4594. unsigned int Union(T& v1, T& v2)
  4595. {
  4596.     T vUnion;
  4597.     vUnion.reserve(v1.size() + v2.size());
  4598.     set_union(v1.begin(), v1.end(),
  4599.               v2.begin(), v2.end(),
  4600.               back_inserter(vUnion));
  4601.     unsigned int nAdded = vUnion.size() - v1.size();
  4602.     if (nAdded > 0)
  4603.         v1 = vUnion;
  4604.     return nAdded;
  4605. }
  4606. void CUser::AddAtom(unsigned short nAtom, bool fOrigin)
  4607. {
  4608.     if (binary_search(vAtomsIn.begin(), vAtomsIn.end(), nAtom) ||
  4609.         find(vAtomsNew.begin(), vAtomsNew.end(), nAtom) != vAtomsNew.end())
  4610.         return;
  4611.     if (nAtom == 0 || fOrigin)
  4612.     {
  4613.         vector<unsigned short> vTmp(1, nAtom);
  4614.         Union(vAtomsIn, vTmp);
  4615.         if (fOrigin)
  4616.             vAtomsOut.push_back(nAtom);
  4617.         return;
  4618.     }
  4619.     vAtomsNew.push_back(nAtom);
  4620.     if (vAtomsNew.size() >= nFlowthroughRate || vAtomsOut.empty())
  4621.     {
  4622.         vAtomsOut.push_back(vAtomsNew[GetRand(vAtomsNew.size())]);
  4623.         sort(vAtomsNew.begin(), vAtomsNew.end());
  4624.         Union(vAtomsIn, vAtomsNew);
  4625.         vAtomsNew.clear();
  4626.     }
  4627. }
  4628. bool AddAtomsAndPropagate(uint256 hashUserStart, const vector<unsigned short>& vAtoms, bool fOrigin)
  4629. {
  4630.     CReviewDB reviewdb;
  4631.     map<uint256, vector<unsigned short> > pmapPropagate[2];
  4632.     pmapPropagate[0][hashUserStart] = vAtoms;
  4633.     for (int side = 0; !pmapPropagate[side].empty(); side = 1 - side)
  4634.     {
  4635.         map<uint256, vector<unsigned short> >& mapFrom = pmapPropagate[side];
  4636.         map<uint256, vector<unsigned short> >& mapTo = pmapPropagate[1 - side];
  4637.         for (map<uint256, vector<unsigned short> >::iterator mi = mapFrom.begin(); mi != mapFrom.end(); ++mi)
  4638.         {
  4639.             const uint256& hashUser = (*mi).first;
  4640.             const vector<unsigned short>& vReceived = (*mi).second;
  4641.             CUser user;
  4642.             reviewdb.ReadUser(hashUser, user);
  4643.             unsigned int nIn = user.vAtomsIn.size();
  4644.             unsigned int nNew = user.vAtomsNew.size();
  4645.             unsigned int nOut = user.vAtomsOut.size();
  4646.             foreach(unsigned short nAtom, vReceived)
  4647.             user.AddAtom(nAtom, fOrigin);
  4648.             fOrigin = false;
  4649.             if (user.vAtomsIn.size() == nIn && user.vAtomsNew.size() == nNew)
  4650.                 continue;
  4651.             if (user.vAtomsOut.size() > nOut)
  4652.                 foreach(const uint256& hash, user.vLinksOut)
  4653.                     mapTo[hash].insert(mapTo[hash].end(), user.vAtomsOut.begin() + nOut, user.vAtomsOut.end());
  4654.             if (!reviewdb.WriteUser(hashUser, user))
  4655.                 return false;
  4656.         }
  4657.         mapFrom.clear();
  4658.     }
  4659.     return true;
  4660. }
  4661. bool CReview::AcceptReview()
  4662. {
  4663.     nTime = GetTime();
  4664.     if (!CKey::Verify(vchPubKeyFrom, GetSigHash(), vchSig))
  4665.         return false;
  4666.     CReviewDB reviewdb;
  4667.     vector<CReview> vReviews;
  4668.     reviewdb.ReadReviews(hashTo, vReviews);
  4669.     vReviews.push_back(*this);
  4670.     if (!reviewdb.WriteReviews(hashTo, vReviews))
  4671.         return false;
  4672.     CUser user;
  4673.     uint256 hashFrom = Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end());
  4674.     reviewdb.ReadUser(hashFrom, user);
  4675.     user.vLinksOut.push_back(hashTo);
  4676.     if (!reviewdb.WriteUser(hashFrom, user))
  4677.         return false;
  4678.     reviewdb.Close();
  4679.     vector<unsigned short> vZeroAtom(1, 0);
  4680.     if (!AddAtomsAndPropagate(hashTo, user.vAtomsOut.size() ? user.vAtomsOut : vZeroAtom, false))
  4681.         return false;
  4682.     return true;
  4683. }
  4684. bool CProduct::CheckSignature()
  4685. {
  4686.     return (CKey::Verify(vchPubKeyFrom, GetSigHash(), vchSig));
  4687. }
  4688. bool CProduct::CheckProduct()
  4689. {
  4690.     if (!CheckSignature())
  4691.         return false;
  4692.     if (!mapDetails.empty() || !vOrderForm.empty())
  4693.         return false;
  4694.     CReviewDB reviewdb("r");
  4695.     CUser user;
  4696.     reviewdb.ReadUser(GetUserHash(), user);
  4697.     nAtoms = user.GetAtomCount();
  4698.     reviewdb.Close();
  4699.     return true;
  4700. }
  4701. class CUser;
  4702. class CReview;
  4703. class CProduct;
  4704. static const unsigned int nFlowthroughRate = 2;
  4705. bool AdvertInsert(const CProduct& product);
  4706. void AdvertErase(const CProduct& product);
  4707. bool AddAtomsAndPropagate(uint256 hashUserStart, const vector<unsigned short>& vAtoms, bool fOrigin);
  4708. class CUser
  4709. {
  4710. public:
  4711.     vector<unsigned short> vAtomsIn;
  4712.     vector<unsigned short> vAtomsNew;
  4713.     vector<unsigned short> vAtomsOut;
  4714.     vector<uint256> vLinksOut;
  4715.     CUser()
  4716.     {
  4717.     }
  4718.     IMPLEMENT_SERIALIZE
  4719.     (
  4720.         if (!(nType & SER_GETHASH))
  4721.             READWRITE(nVersion);
  4722.         READWRITE(vAtomsIn);
  4723.         READWRITE(vAtomsNew);
  4724.         READWRITE(vAtomsOut);
  4725.         READWRITE(vLinksOut);
  4726.     )
  4727.     void SetNull()
  4728.     {
  4729.         vAtomsIn.clear();
  4730.         vAtomsNew.clear();
  4731.         vAtomsOut.clear();
  4732.         vLinksOut.clear();
  4733.     }
  4734.     uint256 GetHash() const { return SerializeHash(*this); }
  4735.     int GetAtomCount() const
  4736.     {
  4737.         return (vAtomsIn.size() + vAtomsNew.size());
  4738.     }
  4739.     void AddAtom(unsigned short nAtom, bool fOrigin);
  4740. };
  4741. class CReview
  4742. {
  4743. public:
  4744.     int nVersion;
  4745.     uint256 hashTo;
  4746.     map<string, string> mapValue;
  4747.     vector<unsigned char> vchPubKeyFrom;
  4748.     vector<unsigned char> vchSig;
  4749.     unsigned int nTime;
  4750.     int nAtoms;
  4751.     CReview()
  4752.     {
  4753.         nVersion = 1;
  4754.         hashTo = 0;
  4755.         nTime = 0;
  4756.         nAtoms = 0;
  4757.     }
  4758.     IMPLEMENT_SERIALIZE
  4759.     (
  4760.         READWRITE(this->nVersion);
  4761.         nVersion = this->nVersion;
  4762.         if (!(nType & SER_DISK))
  4763.             READWRITE(hashTo);
  4764.         READWRITE(mapValue);
  4765.         READWRITE(vchPubKeyFrom);
  4766.         if (!(nType & SER_GETHASH))
  4767.             READWRITE(vchSig);
  4768.     )
  4769.     uint256 GetHash() const { return SerializeHash(*this); }
  4770.     uint256 GetSigHash() const { return SerializeHash(*this, SER_GETHASH|SER_SKIPSIG); }
  4771.     uint256 GetUserHash() const { return Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end()); }
  4772.     bool AcceptReview();
  4773. };
  4774. class CProduct
  4775. {
  4776. public:
  4777.     int nVersion;
  4778.     CAddress addr;
  4779.     map<string, string> mapValue;
  4780.     map<string, string> mapDetails;
  4781.     vector<pair<string, string> > vOrderForm;
  4782.     unsigned int nSequence;
  4783.     vector<unsigned char> vchPubKeyFrom;
  4784.     vector<unsigned char> vchSig;
  4785.     int nAtoms;
  4786.     set<unsigned int> setSources;
  4787.     CProduct()
  4788.     {
  4789.         nVersion = 1;
  4790.         nAtoms = 0;
  4791.         nSequence = 0;
  4792.     }
  4793.     IMPLEMENT_SERIALIZE
  4794.     (
  4795.         READWRITE(this->nVersion);
  4796.         nVersion = this->nVersion;
  4797.         READWRITE(addr);
  4798.         READWRITE(mapValue);
  4799.         if (!(nType & SER_GETHASH))
  4800.         {
  4801.             READWRITE(mapDetails);
  4802.             READWRITE(vOrderForm);
  4803.             READWRITE(nSequence);
  4804.         }
  4805.         READWRITE(vchPubKeyFrom);
  4806.         if (!(nType & SER_GETHASH))
  4807.             READWRITE(vchSig);
  4808.         if (nType & SER_DISK)
  4809.             READWRITE(nAtoms);
  4810.     )
  4811.     uint256 GetHash() const { return SerializeHash(*this); }
  4812.     uint256 GetSigHash() const { return SerializeHash(*this, SER_GETHASH|SER_SKIPSIG); }
  4813.     uint256 GetUserHash() const { return Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end()); }
  4814.     bool CheckSignature();
  4815.     bool CheckProduct();
  4816. };
  4817. extern map<uint256, CProduct> mapProducts;
  4818. extern CCriticalSection cs_mapProducts;
  4819. extern map<uint256, CProduct> mapMyProducts;
  4820. #include "headers.h"
  4821. #include <winsock2.h>
  4822. void ThreadMessageHandler2(void* parg);
  4823. void ThreadSocketHandler2(void* parg);
  4824. void ThreadOpenConnections2(void* parg);
  4825. bool fClient = false;
  4826. uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
  4827. CAddress addrLocalHost(0, DEFAULT_PORT, nLocalServices);
  4828. CNode nodeLocalHost(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices));
  4829. CNode* pnodeLocalHost = &nodeLocalHost;
  4830. bool fShutdown = false;
  4831. array<bool, 10> vfThreadRunning;
  4832. vector<CNode*> vNodes;
  4833. CCriticalSection cs_vNodes;
  4834. map<vector<unsigned char>, CAddress> mapAddresses;
  4835. CCriticalSection cs_mapAddresses;
  4836. map<CInv, CDataStream> mapRelay;
  4837. deque<pair<int64, CInv> > vRelayExpiration;
  4838. CCriticalSection cs_mapRelay;
  4839. map<CInv, int64> mapAlreadyAskedFor;
  4840. CAddress addrProxy;
  4841. bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet)
  4842. {
  4843.     hSocketRet = INVALID_SOCKET;
  4844.     SOCKET hSocket = socket(AF_INET, SOCK_STREAM, 0);
  4845.     if (hSocket == INVALID_SOCKET)
  4846.         return false;
  4847.     bool fRoutable = !(addrConnect.GetByte(3) == 10 || (addrConnect.GetByte(3) == 192 && addrConnect.GetByte(2) == 168));
  4848.     bool fProxy = (addrProxy.ip && fRoutable);
  4849.     struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr());
  4850.     if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
  4851.     {
  4852.         closesocket(hSocket);
  4853.         return false;
  4854.     }
  4855.     if (fProxy)
  4856.     {
  4857.         printf("Proxy connecting to %s\n", addrConnect.ToString().c_str());
  4858.         char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
  4859.         memcpy(pszSocks4IP + 2, &addrConnect.port, 2);
  4860.         memcpy(pszSocks4IP + 4, &addrConnect.ip, 4);
  4861.         char* pszSocks4 = pszSocks4IP;
  4862.         int nSize = sizeof(pszSocks4IP);
  4863.         int ret = send(hSocket, pszSocks4, nSize, 0);
  4864.         if (ret != nSize)
  4865.         {
  4866.             closesocket(hSocket);
  4867.             return error("Error sending to proxy\n");
  4868.         }
  4869.         char pchRet[8];
  4870.         if (recv(hSocket, pchRet, 8, 0) != 8)
  4871.         {
  4872.             closesocket(hSocket);
  4873.             return error("Error reading proxy response\n");
  4874.         }
  4875.         if (pchRet[1] != 0x5a)
  4876.         {
  4877.             closesocket(hSocket);
  4878.             return error("Proxy returned error %d\n", pchRet[1]);
  4879.         }
  4880.         printf("Proxy connection established %s\n", addrConnect.ToString().c_str());
  4881.     }
  4882.     hSocketRet = hSocket;
  4883.     return true;
  4884. }
  4885. bool GetMyExternalIP(unsigned int& ipRet)
  4886. {
  4887.     CAddress addrConnect("72.233.89.199:80");
  4888.     SOCKET hSocket;
  4889.     if (!ConnectSocket(addrConnect, hSocket))
  4890.         return error("GetMyExternalIP() : connection to %s failed\n", addrConnect.ToString().c_str());
  4891.     char* pszGet =
  4892.         "GET /automation/n09230945.asp HTTP/1.1\r\n"
  4893.         "Host: www.whatismyip.com\r\n"
  4894.         "User-Agent: Bitcoin/0.1\r\n"
  4895.         "Connection: close\r\n"
  4896.         "\r\n";
  4897.     send(hSocket, pszGet, strlen(pszGet), 0);
  4898.     string strLine;
  4899.     while (RecvLine(hSocket, strLine))
  4900.     {
  4901.         if (strLine.empty())
  4902.         {
  4903.             if (!RecvLine(hSocket, strLine))
  4904.             {
  4905.                 closesocket(hSocket);
  4906.                 return false;
  4907.             }
  4908.             closesocket(hSocket);
  4909.             CAddress addr(strLine.c_str());
  4910.             printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
  4911.             if (addr.ip == 0)
  4912.                 return false;
  4913.             ipRet = addr.ip;
  4914.             return true;
  4915.         }
  4916.     }
  4917.     closesocket(hSocket);
  4918.     return error("GetMyExternalIP() : connection closed\n");
  4919. }
  4920. bool AddAddress(CAddrDB& addrdb, const CAddress& addr)
  4921. {
  4922.     if (!addr.IsRoutable())
  4923.         return false;
  4924.     if (addr.ip == addrLocalHost.ip)
  4925.         return false;
  4926.     CRITICAL_BLOCK(cs_mapAddresses)
  4927.     {
  4928.         map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
  4929.         if (it == mapAddresses.end())
  4930.         {
  4931.             mapAddresses.insert(make_pair(addr.GetKey(), addr));
  4932.             addrdb.WriteAddress(addr);
  4933.             return true;
  4934.         }
  4935.         else
  4936.         {
  4937.             CAddress& addrFound = (*it).second;
  4938.             if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
  4939.             {
  4940.                 addrFound.nServices |= addr.nServices;
  4941.                 addrdb.WriteAddress(addrFound);
  4942.                 return true;
  4943.             }
  4944.         }
  4945.     }
  4946.     return false;
  4947. }
  4948. void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
  4949. {
  4950.     CRITICAL_BLOCK(cs_vNodes)
  4951.     {
  4952.         foreach(CNode* pnode, vNodes)
  4953.         {
  4954.             CRITICAL_BLOCK(pnode->cs_mapRequests)
  4955.             {
  4956.                 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
  4957.                 {
  4958.                     CRequestTracker& tracker = (*mi).second;
  4959.                     if (tracker.fn == fn && tracker.param1 == param1)
  4960.                         pnode->mapRequests.erase(mi++);
  4961.                     else
  4962.                         mi++;
  4963.                 }
  4964.             }
  4965.         }
  4966.     }
  4967. }
  4968. bool AnySubscribed(unsigned int nChannel)
  4969. {
  4970.     if (pnodeLocalHost->IsSubscribed(nChannel))
  4971.         return true;
  4972.     CRITICAL_BLOCK(cs_vNodes)
  4973.         foreach(CNode* pnode, vNodes)
  4974.             if (pnode->IsSubscribed(nChannel))
  4975.                 return true;
  4976.     return false;
  4977. }
  4978. bool CNode::IsSubscribed(unsigned int nChannel)
  4979. {
  4980.     if (nChannel >= vfSubscribe.size())
  4981.         return false;
  4982.     return vfSubscribe[nChannel];
  4983. }
  4984. void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
  4985. {
  4986.     if (nChannel >= vfSubscribe.size())
  4987.         return;
  4988.     if (!AnySubscribed(nChannel))
  4989.     {
  4990.         CRITICAL_BLOCK(cs_vNodes)
  4991.             foreach(CNode* pnode, vNodes)
  4992.                 if (pnode != this)
  4993.                     pnode->PushMessage("subscribe", nChannel, nHops);
  4994.     }
  4995.     vfSubscribe[nChannel] = true;
  4996. }
  4997. void CNode::CancelSubscribe(unsigned int nChannel)
  4998. {
  4999.     if (nChannel >= vfSubscribe.size())
  5000.         return;
  5001.     if (!vfSubscribe[nChannel])
  5002.         return;
  5003.     vfSubscribe[nChannel] = false;
  5004.     if (!AnySubscribed(nChannel))
  5005.     {
  5006.         CRITICAL_BLOCK(cs_vNodes)
  5007.             foreach(CNode* pnode, vNodes)
  5008.                 if (pnode != this)
  5009.                     pnode->PushMessage("sub-cancel", nChannel);
  5010.  
  5011.         if (nChannel == MSG_PRODUCT)
  5012.             CRITICAL_BLOCK(cs_mapProducts)
  5013.                 mapProducts.clear();
  5014.     }
  5015. }
  5016. CNode* FindNode(unsigned int ip)
  5017. {
  5018.     CRITICAL_BLOCK(cs_vNodes)
  5019.     {
  5020.         foreach(CNode* pnode, vNodes)
  5021.             if (pnode->addr.ip == ip)
  5022.                 return (pnode);
  5023.     }
  5024.     return NULL;
  5025. }
  5026. CNode* FindNode(CAddress addr)
  5027. {
  5028.     CRITICAL_BLOCK(cs_vNodes)
  5029.     {
  5030.         foreach(CNode* pnode, vNodes)
  5031.             if (pnode->addr == addr)
  5032.                 return (pnode);
  5033.     }
  5034.     return NULL;
  5035. }
  5036. CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
  5037. {
  5038.     if (addrConnect.ip == addrLocalHost.ip)
  5039.         return NULL;
  5040.     CNode* pnode = FindNode(addrConnect.ip);
  5041.     if (pnode)
  5042.     {
  5043.         if (nTimeout != 0)
  5044.             pnode->AddRef(nTimeout);
  5045.         else
  5046.             pnode->AddRef();
  5047.         return pnode;
  5048.     }
  5049.     printf("trying %s\n", addrConnect.ToString().c_str());
  5050.     SOCKET hSocket;
  5051.     if (ConnectSocket(addrConnect, hSocket))
  5052.     {
  5053.         printf("connected %s\n", addrConnect.ToString().c_str());
  5054.         CNode* pnode = new CNode(hSocket, addrConnect, false);
  5055.         if (nTimeout != 0)
  5056.             pnode->AddRef(nTimeout);
  5057.         else
  5058.             pnode->AddRef();
  5059.         CRITICAL_BLOCK(cs_vNodes)
  5060.             vNodes.push_back(pnode);
  5061.         CRITICAL_BLOCK(cs_mapAddresses)
  5062.             mapAddresses[addrConnect.GetKey()].nLastFailed = 0;
  5063.         return pnode;
  5064.     }
  5065.     else
  5066.     {
  5067.         CRITICAL_BLOCK(cs_mapAddresses)
  5068.             mapAddresses[addrConnect.GetKey()].nLastFailed = GetTime();
  5069.         return NULL;
  5070.     }
  5071. }
  5072. void CNode::Disconnect()
  5073. {
  5074.     printf("disconnecting node %s\n", addr.ToString().c_str());
  5075.     closesocket(hSocket);
  5076.     CRITICAL_BLOCK(cs_mapProducts)
  5077.         for (map<uint256, CProduct>::iterator mi = mapProducts.begin(); mi != mapProducts.end();)
  5078.             AdvertRemoveSource(this, MSG_PRODUCT, 0, (*(mi++)).second);
  5079.     for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
  5080.         if (vfSubscribe[nChannel])
  5081.             CancelSubscribe(nChannel);
  5082. }
  5083. void ThreadSocketHandler(void* parg)
  5084. {
  5085.     IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
  5086.     loop
  5087.     {
  5088.         vfThreadRunning[0] = true;
  5089.         CheckForShutdown(0);
  5090.         try
  5091.         {
  5092.             ThreadSocketHandler2(parg);
  5093.         }
  5094.         CATCH_PRINT_EXCEPTION("ThreadSocketHandler()")
  5095.         vfThreadRunning[0] = false;
  5096.         Sleep(5000);
  5097.     }
  5098. }
  5099. void ThreadSocketHandler2(void* parg)
  5100. {
  5101.     printf("ThreadSocketHandler started\n");
  5102.     SOCKET hListenSocket = *(SOCKET*)parg;
  5103.     list<CNode*> vNodesDisconnected;
  5104.     int nPrevNodeCount = 0;
  5105.     loop
  5106.     {
  5107.         CRITICAL_BLOCK(cs_vNodes)
  5108.         {
  5109.             map<unsigned int, CNode*> mapFirst;
  5110.             foreach(CNode* pnode, vNodes)
  5111.             {
  5112.                 if (pnode->fDisconnect)
  5113.                     continue;
  5114.                 unsigned int ip = pnode->addr.ip;
  5115.                 if (mapFirst.count(ip) && addrLocalHost.ip < ip)
  5116.                 {
  5117.                     CNode* pnodeExtra = mapFirst[ip];
  5118.                     if (pnodeExtra->GetRefCount() > (pnodeExtra->fNetworkNode ? 1 : 0))
  5119.                         swap(pnodeExtra, pnode);
  5120.                     if (pnodeExtra->GetRefCount() <= (pnodeExtra->fNetworkNode ? 1 : 0))
  5121.                     {
  5122.                         printf("(%d nodes) disconnecting duplicate: %s\n", vNodes.size(), pnodeExtra->addr.ToString().c_str());
  5123.                         if (pnodeExtra->fNetworkNode && !pnode->fNetworkNode)
  5124.                         {
  5125.                             pnode->AddRef();
  5126.                             swap(pnodeExtra->fNetworkNode, pnode->fNetworkNode);
  5127.                             pnodeExtra->Release();
  5128.                         }
  5129.                         pnodeExtra->fDisconnect = true;
  5130.                     }
  5131.                 }
  5132.                 mapFirst[ip] = pnode;
  5133.             }
  5134.             vector<CNode*> vNodesCopy = vNodes;
  5135.             foreach(CNode* pnode, vNodesCopy)
  5136.             {
  5137.                 if (pnode->ReadyToDisconnect() && pnode->vRecv.empty() && pnode->vSend.empty())
  5138.                 {
  5139.                     vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
  5140.                     pnode->Disconnect();
  5141.                     pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 5 * 60);
  5142.                     if (pnode->fNetworkNode)
  5143.                         pnode->Release();
  5144.                     vNodesDisconnected.push_back(pnode);
  5145.                 }
  5146.             }
  5147.             list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
  5148.             foreach(CNode* pnode, vNodesDisconnectedCopy)
  5149.             {
  5150.                 if (pnode->GetRefCount() <= 0)
  5151.                 {
  5152.                     bool fDelete = false;
  5153.                     TRY_CRITICAL_BLOCK(pnode->cs_vSend)
  5154.                      TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
  5155.                       TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
  5156.                        TRY_CRITICAL_BLOCK(pnode->cs_inventory)
  5157.                         fDelete = true;
  5158.                     if (fDelete)
  5159.                     {
  5160.                         vNodesDisconnected.remove(pnode);
  5161.                         delete pnode;
  5162.                     }
  5163.                 }
  5164.             }
  5165.         }
  5166.         if (vNodes.size() != nPrevNodeCount)
  5167.         {
  5168.             nPrevNodeCount = vNodes.size();
  5169.             MainFrameRepaint();
  5170.         }
  5171.         struct timeval timeout;
  5172.         timeout.tv_sec  = 0;
  5173.         timeout.tv_usec = 50000;
  5174.         struct fd_set fdsetRecv;
  5175.         struct fd_set fdsetSend;
  5176.         FD_ZERO(&fdsetRecv);
  5177.         FD_ZERO(&fdsetSend);
  5178.         SOCKET hSocketMax = 0;
  5179.         FD_SET(hListenSocket, &fdsetRecv);
  5180.         hSocketMax = max(hSocketMax, hListenSocket);
  5181.         CRITICAL_BLOCK(cs_vNodes)
  5182.         {
  5183.             foreach(CNode* pnode, vNodes)
  5184.             {
  5185.                 FD_SET(pnode->hSocket, &fdsetRecv);
  5186.                 hSocketMax = max(hSocketMax, pnode->hSocket);
  5187.                 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
  5188.                     if (!pnode->vSend.empty())
  5189.                         FD_SET(pnode->hSocket, &fdsetSend);
  5190.             }
  5191.         }
  5192.         vfThreadRunning[0] = false;
  5193.         int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, NULL, &timeout);
  5194.         vfThreadRunning[0] = true;
  5195.         CheckForShutdown(0);
  5196.         if (nSelect == SOCKET_ERROR)
  5197.         {
  5198.             int nErr = WSAGetLastError();
  5199.             printf("select failed: %d\n", nErr);
  5200.             for (int i = 0; i <= hSocketMax; i++)
  5201.             {
  5202.                 FD_SET(i, &fdsetRecv);
  5203.                 FD_SET(i, &fdsetSend);
  5204.             }
  5205.             Sleep(timeout.tv_usec/1000);
  5206.         }
  5207.         RandAddSeed();
  5208.         if (FD_ISSET(hListenSocket, &fdsetRecv))
  5209.         {
  5210.             struct sockaddr_in sockaddr;
  5211.             int len = sizeof(sockaddr);
  5212.             SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
  5213.             CAddress addr(sockaddr);
  5214.             if (hSocket == INVALID_SOCKET)
  5215.             {
  5216.                 if (WSAGetLastError() != WSAEWOULDBLOCK)
  5217.                     printf("ERROR ThreadSocketHandler accept failed: %d\n", WSAGetLastError());
  5218.             }
  5219.             else
  5220.             {
  5221.                 printf("accepted connection from %s\n", addr.ToString().c_str());
  5222.                 CNode* pnode = new CNode(hSocket, addr, true);
  5223.                 pnode->AddRef();
  5224.                 CRITICAL_BLOCK(cs_vNodes)
  5225.                     vNodes.push_back(pnode);
  5226.             }
  5227.         }
  5228.         vector<CNode*> vNodesCopy;
  5229.         CRITICAL_BLOCK(cs_vNodes)
  5230.             vNodesCopy = vNodes;
  5231.         foreach(CNode* pnode, vNodesCopy)
  5232.         {
  5233.             CheckForShutdown(0);
  5234.             SOCKET hSocket = pnode->hSocket;
  5235.             if (FD_ISSET(hSocket, &fdsetRecv))
  5236.             {
  5237.                 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
  5238.                 {
  5239.                     CDataStream& vRecv = pnode->vRecv;
  5240.                     unsigned int nPos = vRecv.size();
  5241.                     const unsigned int nBufSize = 0x10000;
  5242.                     vRecv.resize(nPos + nBufSize);
  5243.                     int nBytes = recv(hSocket, &vRecv[nPos], nBufSize, 0);
  5244.                     vRecv.resize(nPos + max(nBytes, 0));
  5245.                     if (nBytes == 0)
  5246.                     {
  5247.                         if (!pnode->fDisconnect)
  5248.                             printf("recv: socket closed\n");
  5249.                         pnode->fDisconnect = true;
  5250.                     }
  5251.                     else if (nBytes < 0)
  5252.                     {
  5253.                         int nErr = WSAGetLastError();
  5254.                         if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
  5255.                         {
  5256.                             if (!pnode->fDisconnect)
  5257.                                 printf("recv failed: %d\n", nErr);
  5258.                             pnode->fDisconnect = true;
  5259.                         }
  5260.                     }
  5261.                 }
  5262.             }
  5263.             if (FD_ISSET(hSocket, &fdsetSend))
  5264.             {
  5265.                 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
  5266.                 {
  5267.                     CDataStream& vSend = pnode->vSend;
  5268.                     if (!vSend.empty())
  5269.                     {
  5270.                         int nBytes = send(hSocket, &vSend[0], vSend.size(), 0);
  5271.                         if (nBytes > 0)
  5272.                         {
  5273.                             vSend.erase(vSend.begin(), vSend.begin() + nBytes);
  5274.                         }
  5275.                         else if (nBytes == 0)
  5276.                         {
  5277.                             if (pnode->ReadyToDisconnect())
  5278.                                 pnode->vSend.clear();
  5279.                         }
  5280.                         else
  5281.                         {
  5282.                             printf("send error %d\n", nBytes);
  5283.                             if (pnode->ReadyToDisconnect())
  5284.                                 pnode->vSend.clear();
  5285.                         }
  5286.                     }
  5287.                 }
  5288.             }
  5289.         }
  5290.         Sleep(10);
  5291.     }
  5292. }
  5293. void ThreadOpenConnections(void* parg)
  5294. {
  5295.     IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
  5296.     loop
  5297.     {
  5298.         vfThreadRunning[1] = true;
  5299.         CheckForShutdown(1);
  5300.         try
  5301.         {
  5302.             ThreadOpenConnections2(parg);
  5303.         }
  5304.         CATCH_PRINT_EXCEPTION("ThreadOpenConnections()")
  5305.         vfThreadRunning[1] = false;
  5306.         Sleep(5000);
  5307.     }
  5308. }
  5309. void ThreadOpenConnections2(void* parg)
  5310. {
  5311.     printf("ThreadOpenConnections started\n");
  5312.     const int nMaxConnections = 15;
  5313.     loop
  5314.     {
  5315.         vfThreadRunning[1] = false;
  5316.         Sleep(500);
  5317.         while (vNodes.size() >= nMaxConnections || vNodes.size() >= mapAddresses.size())
  5318.         {
  5319.             CheckForShutdown(1);
  5320.             Sleep(2000);
  5321.         }
  5322.         vfThreadRunning[1] = true;
  5323.         CheckForShutdown(1);
  5324.         unsigned char pchIPCMask[4] = { 0xff, 0xff, 0xff, 0x00 };
  5325.         unsigned int nIPCMask = *(unsigned int*)pchIPCMask;
  5326.         vector<unsigned int> vIPC;
  5327.         CRITICAL_BLOCK(cs_mapAddresses)
  5328.         {
  5329.             vIPC.reserve(mapAddresses.size());
  5330.             unsigned int nPrev = 0;
  5331.             foreach(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
  5332.             {
  5333.                 const CAddress& addr = item.second;
  5334.                 if (!addr.IsIPv4())
  5335.                     continue;
  5336.                 unsigned int ipC = addr.ip & nIPCMask;
  5337.                 if (ipC != nPrev)
  5338.                     vIPC.push_back(nPrev = ipC);
  5339.             }
  5340.         }
  5341.         bool fSuccess = false;
  5342.         int nLimit = vIPC.size();
  5343.         while (!fSuccess && nLimit-- > 0)
  5344.         {
  5345.             unsigned int ipC = vIPC[GetRand(vIPC.size())];
  5346.             map<unsigned int, vector<CAddress> > mapIP;
  5347.             CRITICAL_BLOCK(cs_mapAddresses)
  5348.             {
  5349.                 unsigned int nDelay = ((30 * 60) << vNodes.size());
  5350.                 if (nDelay > 8 * 60 * 60)
  5351.                     nDelay = 8 * 60 * 60;
  5352.                 for (map<vector<unsigned char>, CAddress>::iterator mi = mapAddresses.lower_bound(CAddress(ipC, 0).GetKey());
  5353.                      mi != mapAddresses.upper_bound(CAddress(ipC | ~nIPCMask, 0xffff).GetKey());
  5354.                      ++mi)
  5355.                 {
  5356.                     const CAddress& addr = (*mi).second;
  5357.                     unsigned int nRandomizer = (addr.nLastFailed * addr.ip * 7777U) % 20000;
  5358.                     if (GetTime() - addr.nLastFailed > nDelay * nRandomizer / 10000)
  5359.                         mapIP[addr.ip].push_back(addr);
  5360.                 }
  5361.             }
  5362.             if (mapIP.empty())
  5363.                 break;
  5364.             map<unsigned int, vector<CAddress> >::iterator mi = mapIP.begin();
  5365.             advance(mi, GetRand(mapIP.size()));
  5366.             foreach(const CAddress& addrConnect, (*mi).second)
  5367.             {
  5368.                 if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))
  5369.                     continue;
  5370.                 CNode* pnode = ConnectNode(addrConnect);
  5371.                 if (!pnode)
  5372.                     continue;
  5373.                 pnode->fNetworkNode = true;
  5374.                 if (addrLocalHost.IsRoutable())
  5375.                 {
  5376.                     vector<CAddress> vAddrToSend;
  5377.                     vAddrToSend.push_back(addrLocalHost);
  5378.                     pnode->PushMessage("addr", vAddrToSend);
  5379.                 }
  5380.                 pnode->PushMessage("getaddr");
  5381.                 const unsigned int nHops = 0;
  5382.                 for (unsigned int nChannel = 0; nChannel < pnodeLocalHost->vfSubscribe.size(); nChannel++)
  5383.                     if (pnodeLocalHost->vfSubscribe[nChannel])
  5384.                         pnode->PushMessage("subscribe", nChannel, nHops);
  5385.                 fSuccess = true;
  5386.                 break;
  5387.             }
  5388.         }
  5389.     }
  5390. }
  5391. void ThreadMessageHandler(void* parg)
  5392. {
  5393.     IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
  5394.     loop
  5395.     {
  5396.         vfThreadRunning[2] = true;
  5397.         CheckForShutdown(2);
  5398.         try
  5399.         {
  5400.             ThreadMessageHandler2(parg);
  5401.         }
  5402.         CATCH_PRINT_EXCEPTION("ThreadMessageHandler()")
  5403.         vfThreadRunning[2] = false;
  5404.         Sleep(5000);
  5405.     }
  5406. }
  5407. void ThreadMessageHandler2(void* parg)
  5408. {
  5409.     printf("ThreadMessageHandler started\n");
  5410.     SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL);
  5411.     loop
  5412.     {
  5413.         vector<CNode*> vNodesCopy;
  5414.         CRITICAL_BLOCK(cs_vNodes)
  5415.             vNodesCopy = vNodes;
  5416.         foreach(CNode* pnode, vNodesCopy)
  5417.         {
  5418.             pnode->AddRef();
  5419.             TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
  5420.                 ProcessMessages(pnode);
  5421.             TRY_CRITICAL_BLOCK(pnode->cs_vSend)
  5422.                 SendMessages(pnode);
  5423.             pnode->Release();
  5424.         }
  5425.         vfThreadRunning[2] = false;
  5426.         Sleep(100);
  5427.         vfThreadRunning[2] = true;
  5428.         CheckForShutdown(2);
  5429.     }
  5430. }
  5431. void ThreadBitcoinMiner(void* parg)
  5432. {
  5433.     vfThreadRunning[3] = true;
  5434.     CheckForShutdown(3);
  5435.     try
  5436.     {
  5437.         bool fRet = BitcoinMiner();
  5438.         printf("BitcoinMiner returned %s\n\n\n", fRet ? "true" : "false");
  5439.     }
  5440.     CATCH_PRINT_EXCEPTION("BitcoinMiner()")
  5441.     vfThreadRunning[3] = false;
  5442. }
  5443. bool StartNode(string& strError)
  5444. {
  5445.     strError = "";
  5446.     WSADATA wsadata;
  5447.     int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
  5448.     if (ret != NO_ERROR)
  5449.     {
  5450.         strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
  5451.         printf("%s\n", strError.c_str());
  5452.         return false;
  5453.     }
  5454.     char pszHostName[255];
  5455.     if (gethostname(pszHostName, 255) == SOCKET_ERROR)
  5456.     {
  5457.         strError = strprintf("Error: Unable to get IP address of this computer (gethostname returned error %d)", WSAGetLastError());
  5458.         printf("%s\n", strError.c_str());
  5459.         return false;
  5460.     }
  5461.     struct hostent* pHostEnt = gethostbyname(pszHostName);
  5462.     if (!pHostEnt)
  5463.     {
  5464.         strError = strprintf("Error: Unable to get IP address of this computer (gethostbyname returned error %d)", WSAGetLastError());
  5465.         printf("%s\n", strError.c_str());
  5466.         return false;
  5467.     }
  5468.     addrLocalHost = CAddress(*(long*)(pHostEnt->h_addr_list[0]),
  5469.     DEFAULT_PORT,
  5470.     nLocalServices);
  5471.     printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
  5472.     SOCKET hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  5473.     if (hListenSocket == INVALID_SOCKET)
  5474.     {
  5475.         strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
  5476.         printf("%s\n", strError.c_str());
  5477.         return false;
  5478.     }
  5479.     u_long nOne = 1;
  5480.     if (ioctlsocket(hListenSocket, FIONBIO, &nOne) == SOCKET_ERROR)
  5481.     {
  5482.         strError = strprintf("Error: Couldn't set properties on socket for incoming connections (ioctlsocket returned error %d)", WSAGetLastError());
  5483.         printf("%s\n", strError.c_str());
  5484.         return false;
  5485.     }
  5486.     int nRetryLimit = 15;
  5487.     struct sockaddr_in sockaddr = addrLocalHost.GetSockAddr();
  5488.     if (bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
  5489.     {
  5490.         int nErr = WSAGetLastError();
  5491.         if (nErr == WSAEADDRINUSE)
  5492.             strError = strprintf("Error: Unable to bind to port %s on this computer. The program is probably already running.", addrLocalHost.ToString().c_str());
  5493.         else
  5494.             strError = strprintf("Error: Unable to bind to port %s on this computer (bind returned error %d)", addrLocalHost.ToString().c_str(), nErr);
  5495.         printf("%s\n", strError.c_str());
  5496.         return false;
  5497.     }
  5498.     printf("bound to addrLocalHost = %s\n\n", addrLocalHost.ToString().c_str());
  5499.     if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
  5500.     {
  5501.         strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
  5502.         printf("%s\n", strError.c_str());
  5503.         return false;
  5504.     }
  5505.     if (addrIncoming.ip)
  5506.         addrLocalHost.ip = addrIncoming.ip;
  5507.     if (GetMyExternalIP(addrLocalHost.ip))
  5508.     {
  5509.         addrIncoming = addrLocalHost;
  5510.         CWalletDB().WriteSetting("addrIncoming", addrIncoming);
  5511.     }
  5512.     if (_beginthread(ThreadIRCSeed, 0, NULL) == -1)
  5513.         printf("Error: _beginthread(ThreadIRCSeed) failed\n");
  5514.     if (_beginthread(ThreadSocketHandler, 0, new SOCKET(hListenSocket)) == -1)
  5515.     {
  5516.         strError = "Error: _beginthread(ThreadSocketHandler) failed";
  5517.         printf("%s\n", strError.c_str());
  5518.         return false;
  5519.     }
  5520.     if (_beginthread(ThreadOpenConnections, 0, NULL) == -1)
  5521.     {
  5522.         strError = "Error: _beginthread(ThreadOpenConnections) failed";
  5523.         printf("%s\n", strError.c_str());
  5524.         return false;
  5525.     }
  5526.     if (_beginthread(ThreadMessageHandler, 0, NULL) == -1)
  5527.     {
  5528.         strError = "Error: _beginthread(ThreadMessageHandler) failed";
  5529.         printf("%s\n", strError.c_str());
  5530.         return false;
  5531.     }
  5532.     return true;
  5533. }
  5534. bool StopNode()
  5535. {
  5536.     printf("StopNode()\n");
  5537.     fShutdown = true;
  5538.     nTransactionsUpdated++;
  5539.     while (count(vfThreadRunning.begin(), vfThreadRunning.end(), true))
  5540.         Sleep(10);
  5541.     Sleep(50);
  5542.     WSACleanup();
  5543.     return true;
  5544. }
  5545. void CheckForShutdown(int n)
  5546. {
  5547.     if (fShutdown)
  5548.     {
  5549.         if (n != -1)
  5550.             vfThreadRunning[n] = false;
  5551.         _endthread();
  5552.     }
  5553. }
  5554. class CMessageHeader;
  5555. class CAddress;
  5556. class CInv;
  5557. class CRequestTracker;
  5558. class CNode;
  5559. static const unsigned short DEFAULT_PORT = htons(8333);
  5560. static const unsigned int PUBLISH_HOPS = 5;
  5561. enum
  5562. {
  5563.     NODE_NETWORK = (1 << 0),
  5564. };
  5565. bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet);
  5566. bool GetMyExternalIP(unsigned int& ipRet);
  5567. bool AddAddress(CAddrDB& addrdb, const CAddress& addr);
  5568. CNode* FindNode(unsigned int ip);
  5569. CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0);
  5570. void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1);
  5571. bool AnySubscribed(unsigned int nChannel);
  5572. void ThreadBitcoinMiner(void* parg);
  5573. bool StartNode(string& strError=REF(string()));
  5574. bool StopNode();
  5575. void CheckForShutdown(int n);
  5576. static const char pchMessageStart[4] = { 0xf9, 0xbe, 0xb4, 0xd9 };
  5577. class CMessageHeader
  5578. {
  5579. public:
  5580.     enum { COMMAND_SIZE=12 };
  5581.     char pchMessageStart[sizeof(::pchMessageStart)];
  5582.     char pchCommand[COMMAND_SIZE];
  5583.     unsigned int nMessageSize;
  5584.     CMessageHeader()
  5585.     {
  5586.         memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart));
  5587.         memset(pchCommand, 0, sizeof(pchCommand));
  5588.         pchCommand[1] = 1;
  5589.         nMessageSize = -1;
  5590.     }
  5591.     CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn)
  5592.     {
  5593.         memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart));
  5594.         strncpy(pchCommand, pszCommand, COMMAND_SIZE);
  5595.         nMessageSize = nMessageSizeIn;
  5596.     }
  5597.     IMPLEMENT_SERIALIZE
  5598.     (
  5599.         READWRITE(FLATDATA(pchMessageStart));
  5600.         READWRITE(FLATDATA(pchCommand));
  5601.         READWRITE(nMessageSize);
  5602.     )
  5603.     string GetCommand()
  5604.     {
  5605.         if (pchCommand[COMMAND_SIZE-1] == 0)
  5606.             return string(pchCommand, pchCommand + strlen(pchCommand));
  5607.         else
  5608.             return string(pchCommand, pchCommand + COMMAND_SIZE);
  5609.     }
  5610.     bool IsValid()
  5611.     {
  5612.         if (memcmp(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)) != 0)
  5613.             return false;
  5614.         for (char* p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; p1++)
  5615.         {
  5616.             if (*p1 == 0)
  5617.             {
  5618.                 for (; p1 < pchCommand + COMMAND_SIZE; p1++)
  5619.                     if (*p1 != 0)
  5620.                         return false;
  5621.             }
  5622.             else if (*p1 < ' ' || *p1 > 0x7E)
  5623.                 return false;
  5624.         }
  5625.         if (nMessageSize > 0x10000000)
  5626.         {
  5627.             printf("CMessageHeader::IsValid() : nMessageSize too large %u\n", nMessageSize);
  5628.             return false;
  5629.         }
  5630.         return true;
  5631.     }
  5632. };
  5633. static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
  5634. class CAddress
  5635. {
  5636. public:
  5637.     uint64 nServices;
  5638.     unsigned char pchReserved[12];
  5639.     unsigned int ip;
  5640.     unsigned short port;
  5641.     unsigned int nTime;
  5642.     unsigned int nLastFailed;
  5643.     CAddress()
  5644.     {
  5645.         nServices = 0;
  5646.         memcpy(pchReserved, pchIPv4, sizeof(pchReserved));
  5647.         ip = 0;
  5648.         port = DEFAULT_PORT;
  5649.         nTime = GetAdjustedTime();
  5650.         nLastFailed = 0;
  5651.     }
  5652.     CAddress(unsigned int ipIn, unsigned short portIn, uint64 nServicesIn=0)
  5653.     {
  5654.         nServices = nServicesIn;
  5655.         memcpy(pchReserved, pchIPv4, sizeof(pchReserved));
  5656.         ip = ipIn;
  5657.         port = portIn;
  5658.         nTime = GetAdjustedTime();
  5659.         nLastFailed = 0;
  5660.     }
  5661.     explicit CAddress(const struct sockaddr_in& sockaddr, uint64 nServicesIn=0)
  5662.     {
  5663.         nServices = nServicesIn;
  5664.         memcpy(pchReserved, pchIPv4, sizeof(pchReserved));
  5665.         ip = sockaddr.sin_addr.s_addr;
  5666.         port = sockaddr.sin_port;
  5667.         nTime = GetAdjustedTime();
  5668.         nLastFailed = 0;
  5669.     }
  5670.     explicit CAddress(const char* pszIn, uint64 nServicesIn=0)
  5671.     {
  5672.         nServices = nServicesIn;
  5673.         memcpy(pchReserved, pchIPv4, sizeof(pchReserved));
  5674.         ip = 0;
  5675.         port = DEFAULT_PORT;
  5676.         nTime = GetAdjustedTime();
  5677.         nLastFailed = 0;
  5678.         char psz[100];
  5679.         if (strlen(pszIn) > ARRAYLEN(psz)-1)
  5680.             return;
  5681.         strcpy(psz, pszIn);
  5682.         unsigned int a, b, c, d, e;
  5683.         if (sscanf(psz, "%u.%u.%u.%u:%u", &a, &b, &c, &d, &e) < 4)
  5684.             return;
  5685.         char* pszPort = strchr(psz, ':');
  5686.         if (pszPort)
  5687.         {
  5688.             *pszPort++ = '\0';
  5689.             port = htons(atoi(pszPort));
  5690.         }
  5691.         ip = inet_addr(psz);
  5692.     }
  5693.     IMPLEMENT_SERIALIZE
  5694.     (
  5695.         if (nType & SER_DISK)
  5696.         {
  5697.             READWRITE(nVersion);
  5698.             READWRITE(nTime);
  5699.         }
  5700.         READWRITE(nServices);
  5701.         READWRITE(FLATDATA(pchReserved));
  5702.         READWRITE(ip);
  5703.         READWRITE(port);
  5704.     )
  5705.     friend inline bool operator==(const CAddress& a, const CAddress& b)
  5706.     {
  5707.         return (memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved)) == 0 &&
  5708.                 a.ip   == b.ip &&
  5709.                 a.port == b.port);
  5710.     }
  5711.     friend inline bool operator<(const CAddress& a, const CAddress& b)
  5712.     {
  5713.         int ret = memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved));
  5714.         if (ret < 0)
  5715.             return true;
  5716.         else if (ret == 0)
  5717.         {
  5718.             if (ntohl(a.ip) < ntohl(b.ip))
  5719.                 return true;
  5720.             else if (a.ip == b.ip)
  5721.                 return ntohs(a.port) < ntohs(b.port);
  5722.         }
  5723.         return false;
  5724.     }
  5725.     vector<unsigned char> GetKey() const
  5726.     {
  5727.         CDataStream ss;
  5728.         ss.reserve(18);
  5729.         ss << FLATDATA(pchReserved) << ip << port;
  5730.  
  5731.         #if defined(_MSC_VER) && _MSC_VER < 1300
  5732.         return vector<unsigned char>((unsigned char*)&ss.begin()[0], (unsigned char*)&ss.end()[0]);
  5733.         #else
  5734.         return vector<unsigned char>(ss.begin(), ss.end());
  5735.         #endif
  5736.     }
  5737.     struct sockaddr_in GetSockAddr() const
  5738.     {
  5739.         struct sockaddr_in sockaddr;
  5740.         sockaddr.sin_family = AF_INET;
  5741.         sockaddr.sin_addr.s_addr = ip;
  5742.         sockaddr.sin_port = port;
  5743.         return sockaddr;
  5744.     }
  5745.     bool IsIPv4() const
  5746.     {
  5747.         return (memcmp(pchReserved, pchIPv4, sizeof(pchIPv4)) == 0);
  5748.     }
  5749.     bool IsRoutable() const
  5750.     {
  5751.         return !(GetByte(3) == 10 || (GetByte(3) == 192 && GetByte(2) == 168));
  5752.     }
  5753.     unsigned char GetByte(int n) const
  5754.     {
  5755.         return ((unsigned char*)&ip)[3-n];
  5756.     }
  5757.     string ToStringIPPort() const
  5758.     {
  5759.         return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port));
  5760.     }
  5761.     string ToStringIP() const
  5762.     {
  5763.         return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0));
  5764.     }
  5765.     string ToString() const
  5766.     {
  5767.         return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port));
  5768.     }
  5769.     void print() const
  5770.     {
  5771.         printf("CAddress(%s)\n", ToString().c_str());
  5772.     }
  5773. };
  5774. enum
  5775. {
  5776.     MSG_TX = 1,
  5777.     MSG_BLOCK,
  5778.     MSG_REVIEW,
  5779.     MSG_PRODUCT,
  5780.     MSG_TABLE,
  5781. };
  5782. static const char* ppszTypeName[] =
  5783. {
  5784.     "ERROR",
  5785.     "tx",
  5786.     "block",
  5787.     "review",
  5788.     "product",
  5789.     "table",
  5790. };
  5791. class CInv
  5792. {
  5793. public:
  5794.     int type;
  5795.     uint256 hash;
  5796.     CInv()
  5797.     {
  5798.         type = 0;
  5799.         hash = 0;
  5800.     }
  5801.     CInv(int typeIn, const uint256& hashIn)
  5802.     {
  5803.         type = typeIn;
  5804.         hash = hashIn;
  5805.     }
  5806.     CInv(const string& strType, const uint256& hashIn)
  5807.     {
  5808.         int i;
  5809.         for (i = 1; i < ARRAYLEN(ppszTypeName); i++)
  5810.         {
  5811.             if (strType == ppszTypeName[i])
  5812.             {
  5813.                 type = i;
  5814.                 break;
  5815.             }
  5816.         }
  5817.         if (i == ARRAYLEN(ppszTypeName))
  5818.             throw std::out_of_range(strprintf("CInv::CInv(string, uint256) : unknown type '%s'", strType.c_str()));
  5819.         hash = hashIn;
  5820.     }
  5821.     IMPLEMENT_SERIALIZE
  5822.     (
  5823.         READWRITE(type);
  5824.         READWRITE(hash);
  5825.     )
  5826.     friend inline bool operator<(const CInv& a, const CInv& b)
  5827.     {
  5828.         return (a.type < b.type || (a.type == b.type && a.hash < b.hash));
  5829.     }
  5830.     bool IsKnownType() const
  5831.     {
  5832.         return (type >= 1 && type < ARRAYLEN(ppszTypeName));
  5833.     }
  5834.     const char* GetCommand() const
  5835.     {
  5836.         if (!IsKnownType())
  5837.             throw std::out_of_range(strprintf("CInv::GetCommand() : type=% unknown type", type));
  5838.         return ppszTypeName[type];
  5839.     }
  5840.     string ToString() const
  5841.     {
  5842.         return strprintf("%s %s", GetCommand(), hash.ToString().substr(0,14).c_str());
  5843.     }
  5844.     void print() const
  5845.     {
  5846.         printf("CInv(%s)\n", ToString().c_str());
  5847.     }
  5848. };
  5849. class CRequestTracker
  5850. {
  5851. public:
  5852.     void (*fn)(void*, CDataStream&);
  5853.     void* param1;
  5854.     explicit CRequestTracker(void (*fnIn)(void*, CDataStream&)=NULL, void* param1In=NULL)
  5855.     {
  5856.         fn = fnIn;
  5857.         param1 = param1In;
  5858.     }
  5859.     bool IsNull()
  5860.     {
  5861.         return fn == NULL;
  5862.     }
  5863. };
  5864. extern bool fClient;
  5865. extern uint64 nLocalServices;
  5866. extern CAddress addrLocalHost;
  5867. extern CNode* pnodeLocalHost;
  5868. extern bool fShutdown;
  5869. extern array<bool, 10> vfThreadRunning;
  5870. extern vector<CNode*> vNodes;
  5871. extern CCriticalSection cs_vNodes;
  5872. extern map<vector<unsigned char>, CAddress> mapAddresses;
  5873. extern CCriticalSection cs_mapAddresses;
  5874. extern map<CInv, CDataStream> mapRelay;
  5875. extern deque<pair<int64, CInv> > vRelayExpiration;
  5876. extern CCriticalSection cs_mapRelay;
  5877. extern map<CInv, int64> mapAlreadyAskedFor;
  5878. extern CAddress addrProxy;
  5879. class CNode
  5880. {
  5881. public:
  5882.     uint64 nServices;
  5883.     SOCKET hSocket;
  5884.     CDataStream vSend;
  5885.     CDataStream vRecv;
  5886.     CCriticalSection cs_vSend;
  5887.     CCriticalSection cs_vRecv;
  5888.     unsigned int nPushPos;
  5889.     CAddress addr;
  5890.     int nVersion;
  5891.     bool fClient;
  5892.     bool fInbound;
  5893.     bool fNetworkNode;
  5894.     bool fDisconnect;
  5895. protected:
  5896.     int nRefCount;
  5897. public:
  5898.     int64 nReleaseTime;
  5899.     map<uint256, CRequestTracker> mapRequests;
  5900.     CCriticalSection cs_mapRequests;
  5901.     vector<CAddress> vAddrToSend;
  5902.     set<CAddress> setAddrKnown;
  5903.     set<CInv> setInventoryKnown;
  5904.     set<CInv> setInventoryKnown2;
  5905.     vector<CInv> vInventoryToSend;
  5906.     CCriticalSection cs_inventory;
  5907.     multimap<int64, CInv> mapAskFor;
  5908.     vector<char> vfSubscribe;
  5909.     CNode(SOCKET hSocketIn, CAddress addrIn, bool fInboundIn=false)
  5910.     {
  5911.         nServices = 0;
  5912.         hSocket = hSocketIn;
  5913.         vSend.SetType(SER_NETWORK);
  5914.         vRecv.SetType(SER_NETWORK);
  5915.         nPushPos = -1;
  5916.         addr = addrIn;
  5917.         nVersion = 0;
  5918.         fClient = false;
  5919.         fInbound = fInboundIn;
  5920.         fNetworkNode = false;
  5921.         fDisconnect = false;
  5922.         nRefCount = 0;
  5923.         nReleaseTime = 0;
  5924.         vfSubscribe.assign(256, false);
  5925.         int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
  5926.         PushMessage("version", VERSION, nLocalServices, nTime, addr);
  5927.     }
  5928.     ~CNode()
  5929.     {
  5930.         if (hSocket != INVALID_SOCKET)
  5931.             closesocket(hSocket);
  5932.     }
  5933. private:
  5934.     CNode(const CNode&);
  5935.     void operator=(const CNode&);
  5936. public:
  5937.     bool ReadyToDisconnect()
  5938.     {
  5939.         return fDisconnect || GetRefCount() <= 0;
  5940.     }
  5941.     int GetRefCount()
  5942.     {
  5943.         return max(nRefCount, 0) + (GetTime() < nReleaseTime ? 1 : 0);
  5944.     }
  5945.     void AddRef(int64 nTimeout=0)
  5946.     {
  5947.         if (nTimeout != 0)
  5948.             nReleaseTime = max(nReleaseTime, GetTime() + nTimeout);
  5949.         else
  5950.             nRefCount++;
  5951.     }
  5952.     void Release()
  5953.     {
  5954.         nRefCount--;
  5955.     }
  5956.     void AddInventoryKnown(const CInv& inv)
  5957.     {
  5958.         CRITICAL_BLOCK(cs_inventory)
  5959.             setInventoryKnown.insert(inv);
  5960.     }
  5961.     void PushInventory(const CInv& inv)
  5962.     {
  5963.         CRITICAL_BLOCK(cs_inventory)
  5964.             if (!setInventoryKnown.count(inv))
  5965.                 vInventoryToSend.push_back(inv);
  5966.     }
  5967.     void AskFor(const CInv& inv)
  5968.     {
  5969.         int64& nRequestTime = mapAlreadyAskedFor[inv];
  5970.         printf("askfor %s  %I64d\n", inv.ToString().c_str(), nRequestTime);
  5971.         int64 nNow = (GetTime() - 1) * 1000000;
  5972.         static int64 nLastTime;
  5973.         nLastTime = nNow = max(nNow, ++nLastTime);
  5974.         nRequestTime = max(nRequestTime + 2 * 60 * 1000000, nNow);
  5975.         mapAskFor.insert(make_pair(nRequestTime, inv));
  5976.     }
  5977.     void BeginMessage(const char* pszCommand)
  5978.     {
  5979.         EnterCriticalSection(&cs_vSend);
  5980.         if (nPushPos != -1)
  5981.             AbortMessage();
  5982.         nPushPos = vSend.size();
  5983.         vSend << CMessageHeader(pszCommand, 0);
  5984.         printf("sending: %-12s ", pszCommand);
  5985.     }
  5986.     void AbortMessage()
  5987.     {
  5988.         if (nPushPos == -1)
  5989.             return;
  5990.         vSend.resize(nPushPos);
  5991.         nPushPos = -1;
  5992.         LeaveCriticalSection(&cs_vSend);
  5993.         printf("(aborted)\n");
  5994.     }
  5995.     void EndMessage()
  5996.     {
  5997.         extern int nDropMessagesTest;
  5998.         if (nDropMessagesTest > 0 && GetRand(nDropMessagesTest) == 0)
  5999.         {
  6000.             printf("dropmessages DROPPING SEND MESSAGE\n");
  6001.             AbortMessage();
  6002.             return;
  6003.         }
  6004.         if (nPushPos == -1)
  6005.             return;
  6006.         unsigned int nSize = vSend.size() - nPushPos - sizeof(CMessageHeader);
  6007.         memcpy((char*)&vSend[nPushPos] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize));
  6008.         printf("(%d bytes)  ", nSize);
  6009.         printf("\n");
  6010.         nPushPos = -1;
  6011.         LeaveCriticalSection(&cs_vSend);
  6012.     }
  6013.     void EndMessageAbortIfEmpty()
  6014.     {
  6015.         if (nPushPos == -1)
  6016.             return;
  6017.         int nSize = vSend.size() - nPushPos - sizeof(CMessageHeader);
  6018.         if (nSize > 0)
  6019.             EndMessage();
  6020.         else
  6021.             AbortMessage();
  6022.     }
  6023.     const char* GetMessageCommand() const
  6024.     {
  6025.         if (nPushPos == -1)
  6026.             return "";
  6027.         return &vSend[nPushPos] + offsetof(CMessageHeader, pchCommand);
  6028.     }
  6029.     void PushMessage(const char* pszCommand)
  6030.     {
  6031.         try
  6032.         {
  6033.             BeginMessage(pszCommand);
  6034.             EndMessage();
  6035.         }
  6036.         catch (...)
  6037.         {
  6038.             AbortMessage();
  6039.             throw;
  6040.         }
  6041.     }
  6042.     template<typename T1>
  6043.     void PushMessage(const char* pszCommand, const T1& a1)
  6044.     {
  6045.         try
  6046.         {
  6047.             BeginMessage(pszCommand);
  6048.             vSend << a1;
  6049.             EndMessage();
  6050.         }
  6051.         catch (...)
  6052.         {
  6053.             AbortMessage();
  6054.             throw;
  6055.         }
  6056.     }
  6057.     template<typename T1, typename T2>
  6058.     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2)
  6059.     {
  6060.         try
  6061.         {
  6062.             BeginMessage(pszCommand);
  6063.             vSend << a1 << a2;
  6064.             EndMessage();
  6065.         }
  6066.         catch (...)
  6067.         {
  6068.             AbortMessage();
  6069.             throw;
  6070.         }
  6071.     }
  6072.     template<typename T1, typename T2, typename T3>
  6073.     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3)
  6074.     {
  6075.         try
  6076.         {
  6077.             BeginMessage(pszCommand);
  6078.             vSend << a1 << a2 << a3;
  6079.             EndMessage();
  6080.         }
  6081.         catch (...)
  6082.         {
  6083.             AbortMessage();
  6084.             throw;
  6085.         }
  6086.     }
  6087.     template<typename T1, typename T2, typename T3, typename T4>
  6088.     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4)
  6089.     {
  6090.         try
  6091.         {
  6092.             BeginMessage(pszCommand);
  6093.             vSend << a1 << a2 << a3 << a4;
  6094.             EndMessage();
  6095.         }
  6096.         catch (...)
  6097.         {
  6098.             AbortMessage();
  6099.             throw;
  6100.         }
  6101.     }
  6102.     void PushRequest(const char* pszCommand,
  6103.                      void (*fn)(void*, CDataStream&), void* param1)
  6104.     {
  6105.         uint256 hashReply;
  6106.         RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
  6107.         CRITICAL_BLOCK(cs_mapRequests)
  6108.             mapRequests[hashReply] = CRequestTracker(fn, param1);
  6109.         PushMessage(pszCommand, hashReply);
  6110.     }
  6111.     template<typename T1>
  6112.     void PushRequest(const char* pszCommand, const T1& a1,
  6113.                      void (*fn)(void*, CDataStream&), void* param1)
  6114.     {
  6115.         uint256 hashReply;
  6116.         RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
  6117.         CRITICAL_BLOCK(cs_mapRequests)
  6118.             mapRequests[hashReply] = CRequestTracker(fn, param1);
  6119.         PushMessage(pszCommand, hashReply, a1);
  6120.     }
  6121.     template<typename T1, typename T2>
  6122.     void PushRequest(const char* pszCommand, const T1& a1, const T2& a2,
  6123.                      void (*fn)(void*, CDataStream&), void* param1)
  6124.     {
  6125.         uint256 hashReply;
  6126.         RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
  6127.         CRITICAL_BLOCK(cs_mapRequests)
  6128.             mapRequests[hashReply] = CRequestTracker(fn, param1);
  6129.         PushMessage(pszCommand, hashReply, a1, a2);
  6130.     }
  6131.     bool IsSubscribed(unsigned int nChannel);
  6132.     void Subscribe(unsigned int nChannel, unsigned int nHops=0);
  6133.     void CancelSubscribe(unsigned int nChannel);
  6134.     void Disconnect();
  6135. };
  6136. inline void RelayInventory(const CInv& inv)
  6137. {
  6138.     CRITICAL_BLOCK(cs_vNodes)
  6139.         foreach(CNode* pnode, vNodes)
  6140.             pnode->PushInventory(inv);
  6141. }
  6142. template<typename T>
  6143. void RelayMessage(const CInv& inv, const T& a)
  6144. {
  6145.     CDataStream ss(SER_NETWORK);
  6146.     ss.reserve(10000);
  6147.     ss << a;
  6148.     RelayMessage(inv, ss);
  6149. }
  6150. template<>
  6151. inline void RelayMessage<>(const CInv& inv, const CDataStream& ss)
  6152. {
  6153.     CRITICAL_BLOCK(cs_mapRelay)
  6154.     {
  6155.         while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
  6156.         {
  6157.             mapRelay.erase(vRelayExpiration.front().second);
  6158.             vRelayExpiration.pop_front();
  6159.         }
  6160.         mapRelay[inv] = ss;
  6161.         vRelayExpiration.push_back(make_pair(GetTime() + 15 * 60, inv));
  6162.     }
  6163.     RelayInventory(inv);
  6164. }
  6165. template<typename T>
  6166. void AdvertStartPublish(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj)
  6167. {
  6168.     obj.setSources.insert(pfrom->addr.ip);
  6169.     if (!AdvertInsert(obj))
  6170.         return;
  6171.     CRITICAL_BLOCK(cs_vNodes)
  6172.         foreach(CNode* pnode, vNodes)
  6173.             if (pnode != pfrom && (nHops < PUBLISH_HOPS || pnode->IsSubscribed(nChannel)))
  6174.                 pnode->PushMessage("publish", nChannel, nHops, obj);
  6175. }
  6176. template<typename T>
  6177. void AdvertStopPublish(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj)
  6178. {
  6179.     uint256 hash = obj.GetHash();
  6180.     CRITICAL_BLOCK(cs_vNodes)
  6181.         foreach(CNode* pnode, vNodes)
  6182.             if (pnode != pfrom && (nHops < PUBLISH_HOPS || pnode->IsSubscribed(nChannel)))
  6183.                 pnode->PushMessage("pub-cancel", nChannel, nHops, hash);
  6184.     AdvertErase(obj);
  6185. }
  6186. template<typename T>
  6187. void AdvertRemoveSource(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj)
  6188. {
  6189.     obj.setSources.erase(pfrom->addr.ip);
  6190.     if (obj.setSources.empty())
  6191.         AdvertStopPublish(pfrom, nChannel, nHops, obj);
  6192. }
  6193. #include "headers.h"
  6194. bool CheckSig(vector<unsigned char> vchSig, vector<unsigned char> vchPubKey, CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType);
  6195. typedef vector<unsigned char> valtype;
  6196. static const valtype vchFalse(0);
  6197. static const valtype vchZero(0);
  6198. static const valtype vchTrue(1, 1);
  6199. static const CBigNum bnZero(0);
  6200. static const CBigNum bnOne(1);
  6201. static const CBigNum bnFalse(0);
  6202. static const CBigNum bnTrue(1);
  6203. bool CastToBool(const valtype& vch)
  6204. {
  6205.     return (CBigNum(vch) != bnZero);
  6206. }
  6207. void MakeSameSize(valtype& vch1, valtype& vch2)
  6208. {
  6209.     if (vch1.size() < vch2.size())
  6210.         vch1.resize(vch2.size(), 0);
  6211.     if (vch2.size() < vch1.size())
  6212.         vch2.resize(vch1.size(), 0);
  6213. }
  6214. #define stacktop(i)  (stack.at(stack.size()+(i)))
  6215. #define altstacktop(i)  (altstack.at(altstack.size()+(i)))
  6216. bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType,
  6217.                 vector<vector<unsigned char> >* pvStackRet)
  6218. {
  6219.     CAutoBN_CTX pctx;
  6220.     CScript::const_iterator pc = script.begin();
  6221.     CScript::const_iterator pend = script.end();
  6222.     CScript::const_iterator pbegincodehash = script.begin();
  6223.     vector<bool> vfExec;
  6224.     vector<valtype> stack;
  6225.     vector<valtype> altstack;
  6226.     if (pvStackRet)
  6227.         pvStackRet->clear();
  6228.     while (pc < pend)
  6229.     {
  6230.         bool fExec = !count(vfExec.begin(), vfExec.end(), false);
  6231.         opcodetype opcode;
  6232.         valtype vchPushValue;
  6233.         if (!script.GetOp(pc, opcode, vchPushValue))
  6234.             return false;
  6235.         if (fExec && opcode <= OP_PUSHDATA4)
  6236.             stack.push_back(vchPushValue);
  6237.         else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF))
  6238.         switch (opcode)
  6239.         {
  6240.             case OP_1NEGATE:
  6241.             case OP_1:
  6242.             case OP_2:
  6243.             case OP_3:
  6244.             case OP_4:
  6245.             case OP_5:
  6246.             case OP_6:
  6247.             case OP_7:
  6248.             case OP_8:
  6249.             case OP_9:
  6250.             case OP_10:
  6251.             case OP_11:
  6252.             case OP_12:
  6253.             case OP_13:
  6254.             case OP_14:
  6255.             case OP_15:
  6256.             case OP_16:
  6257.             {
  6258.                 CBigNum bn((int)opcode - (int)(OP_1 - 1));
  6259.                 stack.push_back(bn.getvch());
  6260.             }
  6261.             break;
  6262.             case OP_NOP:
  6263.             break;
  6264.             case OP_VER:
  6265.             {
  6266.                 CBigNum bn(VERSION);
  6267.                 stack.push_back(bn.getvch());
  6268.             }
  6269.             break;
  6270.             case OP_IF:
  6271.             case OP_NOTIF:
  6272.             case OP_VERIF:
  6273.             case OP_VERNOTIF:
  6274.             {
  6275.                 bool fValue = false;
  6276.                 if (fExec)
  6277.                 {
  6278.                     if (stack.size() < 1)
  6279.                         return false;
  6280.                     valtype& vch = stacktop(-1);
  6281.                     if (opcode == OP_VERIF || opcode == OP_VERNOTIF)
  6282.                         fValue = (CBigNum(VERSION) >= CBigNum(vch));
  6283.                     else
  6284.                         fValue = CastToBool(vch);
  6285.                     if (opcode == OP_NOTIF || opcode == OP_VERNOTIF)
  6286.                         fValue = !fValue;
  6287.                     stack.pop_back();
  6288.                 }
  6289.                 vfExec.push_back(fValue);
  6290.             }
  6291.             break;
  6292.             case OP_ELSE:
  6293.             {
  6294.                 if (vfExec.empty())
  6295.                     return false;
  6296.                 vfExec.back() = !vfExec.back();
  6297.             }
  6298.             break;
  6299.             case OP_ENDIF:
  6300.             {
  6301.                 if (vfExec.empty())
  6302.                     return false;
  6303.                 vfExec.pop_back();
  6304.             }
  6305.             break;
  6306.             case OP_VERIFY:
  6307.             {
  6308.                 if (stack.size() < 1)
  6309.                     return false;
  6310.                 bool fValue = CastToBool(stacktop(-1));
  6311.                 if (fValue)
  6312.                     stack.pop_back();
  6313.                 else
  6314.                     pc = pend;
  6315.             }
  6316.             break;
  6317.             case OP_RETURN:
  6318.             {
  6319.                 pc = pend;
  6320.             }
  6321.             break;
  6322.             case OP_TOALTSTACK:
  6323.             {
  6324.                 if (stack.size() < 1)
  6325.                     return false;
  6326.                 altstack.push_back(stacktop(-1));
  6327.                 stack.pop_back();
  6328.             }
  6329.             break;
  6330.             case OP_FROMALTSTACK:
  6331.             {
  6332.                 if (altstack.size() < 1)
  6333.                     return false;
  6334.                 stack.push_back(altstacktop(-1));
  6335.                 altstack.pop_back();
  6336.             }
  6337.             break;
  6338.             case OP_2DROP:
  6339.             {
  6340.                 stack.pop_back();
  6341.                 stack.pop_back();
  6342.             }
  6343.             break;
  6344.             case OP_2DUP:
  6345.             {
  6346.                 if (stack.size() < 2)
  6347.                     return false;
  6348.                 valtype vch1 = stacktop(-2);
  6349.                 valtype vch2 = stacktop(-1);
  6350.                 stack.push_back(vch1);
  6351.                 stack.push_back(vch2);
  6352.             }
  6353.             break;
  6354.             case OP_3DUP:
  6355.             {
  6356.                 if (stack.size() < 3)
  6357.                     return false;
  6358.                 valtype vch1 = stacktop(-3);
  6359.                 valtype vch2 = stacktop(-2);
  6360.                 valtype vch3 = stacktop(-1);
  6361.                 stack.push_back(vch1);
  6362.                 stack.push_back(vch2);
  6363.                 stack.push_back(vch3);
  6364.             }
  6365.             break;
  6366.             case OP_2OVER:
  6367.             {
  6368.                 if (stack.size() < 4)
  6369.                     return false;
  6370.                 valtype vch1 = stacktop(-4);
  6371.                 valtype vch2 = stacktop(-3);
  6372.                 stack.push_back(vch1);
  6373.                 stack.push_back(vch2);
  6374.             }
  6375.             break;
  6376.             case OP_2ROT:
  6377.             {
  6378.                 if (stack.size() < 6)
  6379.                     return false;
  6380.                 valtype vch1 = stacktop(-6);
  6381.                 valtype vch2 = stacktop(-5);
  6382.                 stack.erase(stack.end()-6, stack.end()-4);
  6383.                 stack.push_back(vch1);
  6384.                 stack.push_back(vch2);
  6385.             }
  6386.             break;
  6387.             case OP_2SWAP:
  6388.             {
  6389.                 if (stack.size() < 4)
  6390.                     return false;
  6391.                 swap(stacktop(-4), stacktop(-2));
  6392.                 swap(stacktop(-3), stacktop(-1));
  6393.             }
  6394.             break;
  6395.             case OP_IFDUP:
  6396.             {
  6397.                 if (stack.size() < 1)
  6398.                     return false;
  6399.                 valtype vch = stacktop(-1);
  6400.                 if (CastToBool(vch))
  6401.                     stack.push_back(vch);
  6402.             }
  6403.             break;
  6404.             case OP_DEPTH:
  6405.             {
  6406.                 CBigNum bn(stack.size());
  6407.                 stack.push_back(bn.getvch());
  6408.             }
  6409.             break;
  6410.             case OP_DROP:
  6411.             {
  6412.                 if (stack.size() < 1)
  6413.                     return false;
  6414.                 stack.pop_back();
  6415.             }
  6416.             break;
  6417.             case OP_DUP:
  6418.             {
  6419.                 if (stack.size() < 1)
  6420.                     return false;
  6421.                 valtype vch = stacktop(-1);
  6422.                 stack.push_back(vch);
  6423.             }
  6424.             break;
  6425.             case OP_NIP:
  6426.             {
  6427.                 if (stack.size() < 2)
  6428.                     return false;
  6429.                 stack.erase(stack.end() - 2);
  6430.             }
  6431.             break;
  6432.             case OP_OVER:
  6433.             {
  6434.                 if (stack.size() < 2)
  6435.                     return false;
  6436.                 valtype vch = stacktop(-2);
  6437.                 stack.push_back(vch);
  6438.             }
  6439.             break;
  6440.             case OP_PICK:
  6441.             case OP_ROLL:
  6442.             {
  6443.                 if (stack.size() < 2)
  6444.                     return false;
  6445.                 int n = CBigNum(stacktop(-1)).getint();
  6446.                 stack.pop_back();
  6447.                 if (n < 0 || n >= stack.size())
  6448.                     return false;
  6449.                 valtype vch = stacktop(-n-1);
  6450.                 if (opcode == OP_ROLL)
  6451.                     stack.erase(stack.end()-n-1);
  6452.                 stack.push_back(vch);
  6453.             }
  6454.             break;
  6455.             case OP_ROT:
  6456.             {
  6457.                 if (stack.size() < 3)
  6458.                     return false;
  6459.                 swap(stacktop(-3), stacktop(-2));
  6460.                 swap(stacktop(-2), stacktop(-1));
  6461.             }
  6462.             break;
  6463.             case OP_SWAP:
  6464.             {
  6465.                 if (stack.size() < 2)
  6466.                     return false;
  6467.                 swap(stacktop(-2), stacktop(-1));
  6468.             }
  6469.             break;
  6470.             case OP_TUCK:
  6471.             {
  6472.                 if (stack.size() < 2)
  6473.                     return false;
  6474.                 valtype vch = stacktop(-1);
  6475.                 stack.insert(stack.end()-2, vch);
  6476.             }
  6477.             break;
  6478.             case OP_CAT:
  6479.             {
  6480.                 if (stack.size() < 2)
  6481.                     return false;
  6482.                 valtype& vch1 = stacktop(-2);
  6483.                 valtype& vch2 = stacktop(-1);
  6484.                 vch1.insert(vch1.end(), vch2.begin(), vch2.end());
  6485.                 stack.pop_back();
  6486.             }
  6487.             break;
  6488.             case OP_SUBSTR:
  6489.             {
  6490.                 if (stack.size() < 3)
  6491.                     return false;
  6492.                 valtype& vch = stacktop(-3);
  6493.                 int nBegin = CBigNum(stacktop(-2)).getint();
  6494.                 int nEnd = nBegin + CBigNum(stacktop(-1)).getint();
  6495.                 if (nBegin < 0 || nEnd < nBegin)
  6496.                     return false;
  6497.                 if (nBegin > vch.size())
  6498.                     nBegin = vch.size();
  6499.                 if (nEnd > vch.size())
  6500.                     nEnd = vch.size();
  6501.                 vch.erase(vch.begin() + nEnd, vch.end());
  6502.                 vch.erase(vch.begin(), vch.begin() + nBegin);
  6503.                 stack.pop_back();
  6504.                 stack.pop_back();
  6505.             }
  6506.             break;
  6507.             case OP_LEFT:
  6508.             case OP_RIGHT:
  6509.             {
  6510.                 if (stack.size() < 2)
  6511.                     return false;
  6512.                 valtype& vch = stacktop(-2);
  6513.                 int nSize = CBigNum(stacktop(-1)).getint();
  6514.                 if (nSize < 0)
  6515.                     return false;
  6516.                 if (nSize > vch.size())
  6517.                     nSize = vch.size();
  6518.                 if (opcode == OP_LEFT)
  6519.                     vch.erase(vch.begin() + nSize, vch.end());
  6520.                 else
  6521.                     vch.erase(vch.begin(), vch.end() - nSize);
  6522.                 stack.pop_back();
  6523.             }
  6524.             break;
  6525.             case OP_SIZE:
  6526.             {
  6527.                 if (stack.size() < 1)
  6528.                     return false;
  6529.                 CBigNum bn(stacktop(-1).size());
  6530.                 stack.push_back(bn.getvch());
  6531.             }
  6532.             break;
  6533.             case OP_INVERT:
  6534.             {
  6535.                 if (stack.size() < 1)
  6536.                     return false;
  6537.                 valtype& vch = stacktop(-1);
  6538.                 for (int i = 0; i < vch.size(); i++)
  6539.                     vch[i] = ~vch[i];
  6540.             }
  6541.             break;
  6542.             case OP_AND:
  6543.             case OP_OR:
  6544.             case OP_XOR:
  6545.             {
  6546.                 if (stack.size() < 2)
  6547.                     return false;
  6548.                 valtype& vch1 = stacktop(-2);
  6549.                 valtype& vch2 = stacktop(-1);
  6550.                 MakeSameSize(vch1, vch2);
  6551.                 if (opcode == OP_AND)
  6552.                 {
  6553.                     for (int i = 0; i < vch1.size(); i++)
  6554.                         vch1[i] &= vch2[i];
  6555.                 }
  6556.                 else if (opcode == OP_OR)
  6557.                 {
  6558.                     for (int i = 0; i < vch1.size(); i++)
  6559.                         vch1[i] |= vch2[i];
  6560.                 }
  6561.                 else if (opcode == OP_XOR)
  6562.                 {
  6563.                     for (int i = 0; i < vch1.size(); i++)
  6564.                         vch1[i] ^= vch2[i];
  6565.                 }
  6566.                 stack.pop_back();
  6567.             }
  6568.             break;
  6569.             case OP_EQUAL:
  6570.             case OP_EQUALVERIFY:
  6571.             {
  6572.                 if (stack.size() < 2)
  6573.                     return false;
  6574.                 valtype& vch1 = stacktop(-2);
  6575.                 valtype& vch2 = stacktop(-1);
  6576.                 bool fEqual = (vch1 == vch2);
  6577.                 stack.pop_back();
  6578.                 stack.pop_back();
  6579.                 stack.push_back(fEqual ? vchTrue : vchFalse);
  6580.                 if (opcode == OP_EQUALVERIFY)
  6581.                 {
  6582.                     if (fEqual)
  6583.                         stack.pop_back();
  6584.                     else
  6585.                         pc = pend;
  6586.                 }
  6587.             }
  6588.             break;
  6589.             case OP_1ADD:
  6590.             case OP_1SUB:
  6591.             case OP_2MUL:
  6592.             case OP_2DIV:
  6593.             case OP_NEGATE:
  6594.             case OP_ABS:
  6595.             case OP_NOT:
  6596.             case OP_0NOTEQUAL:
  6597.             {
  6598.                 if (stack.size() < 1)
  6599.                     return false;
  6600.                 CBigNum bn(stacktop(-1));
  6601.                 switch (opcode)
  6602.                 {
  6603.                 case OP_1ADD:       bn += bnOne; break;
  6604.                 case OP_1SUB:       bn -= bnOne; break;
  6605.                 case OP_2MUL:       bn <<= 1; break;
  6606.                 case OP_2DIV:       bn >>= 1; break;
  6607.                 case OP_NEGATE:     bn = -bn; break;
  6608.                 case OP_ABS:        if (bn < bnZero) bn = -bn; break;
  6609.                 case OP_NOT:        bn = (bn == bnZero); break;
  6610.                 case OP_0NOTEQUAL:  bn = (bn != bnZero); break;
  6611.                 }
  6612.                 stack.pop_back();
  6613.                 stack.push_back(bn.getvch());
  6614.             }
  6615.             break;
  6616.             case OP_ADD:
  6617.             case OP_SUB:
  6618.             case OP_MUL:
  6619.             case OP_DIV:
  6620.             case OP_MOD:
  6621.             case OP_LSHIFT:
  6622.             case OP_RSHIFT:
  6623.             case OP_BOOLAND:
  6624.             case OP_BOOLOR:
  6625.             case OP_NUMEQUAL:
  6626.             case OP_NUMEQUALVERIFY:
  6627.             case OP_NUMNOTEQUAL:
  6628.             case OP_LESSTHAN:
  6629.             case OP_GREATERTHAN:
  6630.             case OP_LESSTHANOREQUAL:
  6631.             case OP_GREATERTHANOREQUAL:
  6632.             case OP_MIN:
  6633.             case OP_MAX:
  6634.             {
  6635.                 if (stack.size() < 2)
  6636.                     return false;
  6637.                 CBigNum bn1(stacktop(-2));
  6638.                 CBigNum bn2(stacktop(-1));
  6639.                 CBigNum bn;
  6640.                 switch (opcode)
  6641.                 {
  6642.                 case OP_ADD:
  6643.                     bn = bn1 + bn2;
  6644.                     break;
  6645.                 case OP_SUB:
  6646.                     bn = bn1 - bn2;
  6647.                     break;
  6648.                 case OP_MUL:
  6649.                     if (!BN_mul(&bn, &bn1, &bn2, pctx))
  6650.                         return false;
  6651.                     break;
  6652.                 case OP_DIV:
  6653.                     if (!BN_div(&bn, NULL, &bn1, &bn2, pctx))
  6654.                         return false;
  6655.                     break;
  6656.                 case OP_MOD:
  6657.                     if (!BN_mod(&bn, &bn1, &bn2, pctx))
  6658.                         return false;
  6659.                     break;
  6660.                 case OP_LSHIFT:
  6661.                     if (bn2 < bnZero)
  6662.                         return false;
  6663.                     bn = bn1 << bn2.getulong();
  6664.                     break;
  6665.                 case OP_RSHIFT:
  6666.                     if (bn2 < bnZero)
  6667.                         return false;
  6668.                     bn = bn1 >> bn2.getulong();
  6669.                     break;
  6670.                 case OP_BOOLAND:             bn = (bn1 != bnZero && bn2 != bnZero); break;
  6671.                 case OP_BOOLOR:              bn = (bn1 != bnZero || bn2 != bnZero); break;
  6672.                 case OP_NUMEQUAL:            bn = (bn1 == bn2); break;
  6673.                 case OP_NUMEQUALVERIFY:      bn = (bn1 == bn2); break;
  6674.                 case OP_NUMNOTEQUAL:         bn = (bn1 != bn2); break;
  6675.                 case OP_LESSTHAN:            bn = (bn1 < bn2); break;
  6676.                 case OP_GREATERTHAN:         bn = (bn1 > bn2); break;
  6677.                 case OP_LESSTHANOREQUAL:     bn = (bn1 <= bn2); break;
  6678.                 case OP_GREATERTHANOREQUAL:  bn = (bn1 >= bn2); break;
  6679.                 case OP_MIN:                 bn = (bn1 < bn2 ? bn1 : bn2); break;
  6680.                 case OP_MAX:                 bn = (bn1 > bn2 ? bn1 : bn2); break;
  6681.                 }
  6682.                 stack.pop_back();
  6683.                 stack.pop_back();
  6684.                 stack.push_back(bn.getvch());
  6685.                 if (opcode == OP_NUMEQUALVERIFY)
  6686.                 {
  6687.                     if (CastToBool(stacktop(-1)))
  6688.                         stack.pop_back();
  6689.                     else
  6690.                         pc = pend;
  6691.                 }
  6692.             }
  6693.             break;
  6694.             case OP_WITHIN:
  6695.             {
  6696.                 if (stack.size() < 3)
  6697.                     return false;
  6698.                 CBigNum bn1(stacktop(-3));
  6699.                 CBigNum bn2(stacktop(-2));
  6700.                 CBigNum bn3(stacktop(-1));
  6701.                 bool fValue = (bn2 <= bn1 && bn1 < bn3);
  6702.                 stack.pop_back();
  6703.                 stack.pop_back();
  6704.                 stack.pop_back();
  6705.                 stack.push_back(fValue ? vchTrue : vchFalse);
  6706.             }
  6707.             break;
  6708.             case OP_RIPEMD160:
  6709.             case OP_SHA1:
  6710.             case OP_SHA256:
  6711.             case OP_HASH160:
  6712.             case OP_HASH256:
  6713.             {
  6714.                 if (stack.size() < 1)
  6715.                     return false;
  6716.                 valtype& vch = stacktop(-1);
  6717.                 valtype vchHash(opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160 ? 20 : 32);
  6718.                 if (opcode == OP_RIPEMD160)
  6719.                     RIPEMD160(&vch[0], vch.size(), &vchHash[0]);
  6720.                 else if (opcode == OP_SHA1)
  6721.                     SHA1(&vch[0], vch.size(), &vchHash[0]);
  6722.                 else if (opcode == OP_SHA256)
  6723.                     SHA256(&vch[0], vch.size(), &vchHash[0]);
  6724.                 else if (opcode == OP_HASH160)
  6725.                 {
  6726.                     uint160 hash160 = Hash160(vch);
  6727.                     memcpy(&vchHash[0], &hash160, sizeof(hash160));
  6728.                 }
  6729.                 else if (opcode == OP_HASH256)
  6730.                 {
  6731.                     uint256 hash = Hash(vch.begin(), vch.end());
  6732.                     memcpy(&vchHash[0], &hash, sizeof(hash));
  6733.                 }
  6734.                 stack.pop_back();
  6735.                 stack.push_back(vchHash);
  6736.             }
  6737.             break;
  6738.             case OP_CODESEPARATOR:
  6739.             {
  6740.                 pbegincodehash = pc;
  6741.             }
  6742.             break;
  6743.             case OP_CHECKSIG:
  6744.             case OP_CHECKSIGVERIFY:
  6745.             {
  6746.                 if (stack.size() < 2)
  6747.                     return false;
  6748.  
  6749.                 valtype& vchSig    = stacktop(-2);
  6750.                 valtype& vchPubKey = stacktop(-1);
  6751.                 CScript scriptCode(pbegincodehash, pend);
  6752.                 scriptCode.FindAndDelete(CScript(vchSig));
  6753.                 bool fSuccess = CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType);
  6754.                 stack.pop_back();
  6755.                 stack.pop_back();
  6756.                 stack.push_back(fSuccess ? vchTrue : vchFalse);
  6757.                 if (opcode == OP_CHECKSIGVERIFY)
  6758.                 {
  6759.                     if (fSuccess)
  6760.                         stack.pop_back();
  6761.                     else
  6762.                         pc = pend;
  6763.                 }
  6764.             }
  6765.             break;
  6766.             case OP_CHECKMULTISIG:
  6767.             case OP_CHECKMULTISIGVERIFY:
  6768.             {
  6769.                 int i = 1;
  6770.                 if (stack.size() < i)
  6771.                     return false;
  6772.                 int nKeysCount = CBigNum(stacktop(-i)).getint();
  6773.                 if (nKeysCount < 0)
  6774.                     return false;
  6775.                 int ikey = ++i;
  6776.                 i += nKeysCount;
  6777.                 if (stack.size() < i)
  6778.                     return false;
  6779.                 int nSigsCount = CBigNum(stacktop(-i)).getint();
  6780.                 if (nSigsCount < 0 || nSigsCount > nKeysCount)
  6781.                     return false;
  6782.                 int isig = ++i;
  6783.                 i += nSigsCount;
  6784.                 if (stack.size() < i)
  6785.                     return false;
  6786.                 CScript scriptCode(pbegincodehash, pend);
  6787.                 for (int i = 0; i < nSigsCount; i++)
  6788.                 {
  6789.                     valtype& vchSig = stacktop(-isig-i);
  6790.                     scriptCode.FindAndDelete(CScript(vchSig));
  6791.                 }
  6792.                 bool fSuccess = true;
  6793.                 while (fSuccess && nSigsCount > 0)
  6794.                 {
  6795.                     valtype& vchSig    = stacktop(-isig);
  6796.                     valtype& vchPubKey = stacktop(-ikey);
  6797.                     if (CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType))
  6798.                     {
  6799.                         isig++;
  6800.                         nSigsCount--;
  6801.                     }
  6802.                     ikey++;
  6803.                     nKeysCount--;
  6804.                     if (nSigsCount > nKeysCount)
  6805.                         fSuccess = false;
  6806.                 }
  6807.                 while (i-- > 0)
  6808.                     stack.pop_back();
  6809.                 stack.push_back(fSuccess ? vchTrue : vchFalse);
  6810.                 if (opcode == OP_CHECKMULTISIGVERIFY)
  6811.                 {
  6812.                     if (fSuccess)
  6813.                         stack.pop_back();
  6814.                     else
  6815.                         pc = pend;
  6816.                 }
  6817.             }
  6818.             break;
  6819.             default:
  6820.                 return false;
  6821.         }
  6822.     }
  6823.     if (pvStackRet)
  6824.         *pvStackRet = stack;
  6825.     return (stack.empty() ? false : CastToBool(stack.back()));
  6826. }
  6827. #undef top
  6828. uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType)
  6829. {
  6830.     if (nIn >= txTo.vin.size())
  6831.     {
  6832.         printf("ERROR: SignatureHash() : nIn=%d out of range\n", nIn);
  6833.         return 1;
  6834.     }
  6835.     CTransaction txTmp(txTo);
  6836.     scriptCode.FindAndDelete(CScript(OP_CODESEPARATOR));
  6837.     for (int i = 0; i < txTmp.vin.size(); i++)
  6838.         txTmp.vin[i].scriptSig = CScript();
  6839.     txTmp.vin[nIn].scriptSig = scriptCode;
  6840.     if ((nHashType & 0x1f) == SIGHASH_NONE)
  6841.     {
  6842.         txTmp.vout.clear();
  6843.         for (int i = 0; i < txTmp.vin.size(); i++)
  6844.             if (i != nIn)
  6845.                 txTmp.vin[i].nSequence = 0;
  6846.     }
  6847.     else if ((nHashType & 0x1f) == SIGHASH_SINGLE)
  6848.     {
  6849.         unsigned int nOut = nIn;
  6850.         if (nOut >= txTmp.vout.size())
  6851.         {
  6852.             printf("ERROR: SignatureHash() : nOut=%d out of range\n", nOut);
  6853.             return 1;
  6854.         }
  6855.         txTmp.vout.resize(nOut+1);
  6856.         for (int i = 0; i < nOut; i++)
  6857.             txTmp.vout[i].SetNull();
  6858.         for (int i = 0; i < txTmp.vin.size(); i++)
  6859.             if (i != nIn)
  6860.                 txTmp.vin[i].nSequence = 0;
  6861.     }
  6862.     if (nHashType & SIGHASH_ANYONECANPAY)
  6863.     {
  6864.         txTmp.vin[0] = txTmp.vin[nIn];
  6865.         txTmp.vin.resize(1);
  6866.     }
  6867.     CDataStream ss(SER_GETHASH);
  6868.     ss.reserve(10000);
  6869.     ss << txTmp << nHashType;
  6870.     return Hash(ss.begin(), ss.end());
  6871. }
  6872. bool CheckSig(vector<unsigned char> vchSig, vector<unsigned char> vchPubKey, CScript scriptCode,
  6873.               const CTransaction& txTo, unsigned int nIn, int nHashType)
  6874. {
  6875.     CKey key;
  6876.     if (!key.SetPubKey(vchPubKey))
  6877.         return false;
  6878.     if (vchSig.empty())
  6879.         return false;
  6880.     if (nHashType == 0)
  6881.         nHashType = vchSig.back();
  6882.     else if (nHashType != vchSig.back())
  6883.         return false;
  6884.     vchSig.pop_back();
  6885.     if (key.Verify(SignatureHash(scriptCode, txTo, nIn, nHashType), vchSig))
  6886.         return true;
  6887.     return false;
  6888. }
  6889. bool Solver(const CScript& scriptPubKey, vector<pair<opcodetype, valtype> >& vSolutionRet)
  6890. {
  6891.     static vector<CScript> vTemplates;
  6892.     if (vTemplates.empty())
  6893.     {
  6894.         vTemplates.push_back(CScript() << OP_PUBKEY << OP_CHECKSIG);
  6895.         vTemplates.push_back(CScript() << OP_DUP << OP_HASH160 << OP_PUBKEYHASH << OP_EQUALVERIFY << OP_CHECKSIG);
  6896.     }
  6897.     const CScript& script1 = scriptPubKey;
  6898.     foreach(const CScript& script2, vTemplates)
  6899.     {
  6900.         vSolutionRet.clear();
  6901.         opcodetype opcode1, opcode2;
  6902.         vector<unsigned char> vch1, vch2;
  6903.         CScript::const_iterator pc1 = script1.begin();
  6904.         CScript::const_iterator pc2 = script2.begin();
  6905.         loop
  6906.         {
  6907.             bool f1 = script1.GetOp(pc1, opcode1, vch1);
  6908.             bool f2 = script2.GetOp(pc2, opcode2, vch2);
  6909.             if (!f1 && !f2)
  6910.             {
  6911.                 reverse(vSolutionRet.begin(), vSolutionRet.end());
  6912.                 return true;
  6913.             }
  6914.             else if (f1 != f2)
  6915.             {
  6916.                 break;
  6917.             }
  6918.             else if (opcode2 == OP_PUBKEY)
  6919.             {
  6920.                 if (vch1.size() <= sizeof(uint256))
  6921.                     break;
  6922.                 vSolutionRet.push_back(make_pair(opcode2, vch1));
  6923.             }
  6924.             else if (opcode2 == OP_PUBKEYHASH)
  6925.             {
  6926.                 if (vch1.size() != sizeof(uint160))
  6927.                     break;
  6928.                 vSolutionRet.push_back(make_pair(opcode2, vch1));
  6929.             }
  6930.             else if (opcode1 != opcode2)
  6931.             {
  6932.                 break;
  6933.             }
  6934.         }
  6935.     }
  6936.     vSolutionRet.clear();
  6937.     return false;
  6938. }
  6939. bool Solver(const CScript& scriptPubKey, uint256 hash, int nHashType, CScript& scriptSigRet)
  6940. {
  6941.     scriptSigRet.clear();
  6942.     vector<pair<opcodetype, valtype> > vSolution;
  6943.     if (!Solver(scriptPubKey, vSolution))
  6944.         return false;
  6945.     CRITICAL_BLOCK(cs_mapKeys)
  6946.     {
  6947.         foreach(PAIRTYPE(opcodetype, valtype)& item, vSolution)
  6948.         {
  6949.             if (item.first == OP_PUBKEY)
  6950.             {
  6951.                 const valtype& vchPubKey = item.second;
  6952.                 if (!mapKeys.count(vchPubKey))
  6953.                     return false;
  6954.                 if (hash != 0)
  6955.                 {
  6956.                     vector<unsigned char> vchSig;
  6957.                     if (!CKey::Sign(mapKeys[vchPubKey], hash, vchSig))
  6958.                         return false;
  6959.                     vchSig.push_back((unsigned char)nHashType);
  6960.                     scriptSigRet << vchSig;
  6961.                 }
  6962.             }
  6963.             else if (item.first == OP_PUBKEYHASH)
  6964.             {
  6965.                 map<uint160, valtype>::iterator mi = mapPubKeys.find(uint160(item.second));
  6966.                 if (mi == mapPubKeys.end())
  6967.                     return false;
  6968.                 const vector<unsigned char>& vchPubKey = (*mi).second;
  6969.                 if (!mapKeys.count(vchPubKey))
  6970.                     return false;
  6971.                 if (hash != 0)
  6972.                 {
  6973.                     vector<unsigned char> vchSig;
  6974.                     if (!CKey::Sign(mapKeys[vchPubKey], hash, vchSig))
  6975.                         return false;
  6976.                     vchSig.push_back((unsigned char)nHashType);
  6977.                     scriptSigRet << vchSig << vchPubKey;
  6978.                 }
  6979.             }
  6980.         }
  6981.     }
  6982.     return true;
  6983. }
  6984. bool IsMine(const CScript& scriptPubKey)
  6985. {
  6986.     CScript scriptSig;
  6987.     return Solver(scriptPubKey, 0, 0, scriptSig);
  6988. }
  6989. bool ExtractPubKey(const CScript& scriptPubKey, bool fMineOnly, vector<unsigned char>& vchPubKeyRet)
  6990. {
  6991.     vchPubKeyRet.clear();
  6992.     vector<pair<opcodetype, valtype> > vSolution;
  6993.     if (!Solver(scriptPubKey, vSolution))
  6994.         return false;
  6995.     CRITICAL_BLOCK(cs_mapKeys)
  6996.     {
  6997.         foreach(PAIRTYPE(opcodetype, valtype)& item, vSolution)
  6998.         {
  6999.             valtype vchPubKey;
  7000.             if (item.first == OP_PUBKEY)
  7001.             {
  7002.                 vchPubKey = item.second;
  7003.             }
  7004.             else if (item.first == OP_PUBKEYHASH)
  7005.             {
  7006.                 map<uint160, valtype>::iterator mi = mapPubKeys.find(uint160(item.second));
  7007.                 if (mi == mapPubKeys.end())
  7008.                     continue;
  7009.                 vchPubKey = (*mi).second;
  7010.             }
  7011.             if (!fMineOnly || mapKeys.count(vchPubKey))
  7012.             {
  7013.                 vchPubKeyRet = vchPubKey;
  7014.                 return true;
  7015.             }
  7016.         }
  7017.     }
  7018.     return false;
  7019. }
  7020. bool ExtractHash160(const CScript& scriptPubKey, uint160& hash160Ret)
  7021. {
  7022.     hash160Ret = 0;
  7023.     vector<pair<opcodetype, valtype> > vSolution;
  7024.     if (!Solver(scriptPubKey, vSolution))
  7025.         return false;
  7026.     foreach(PAIRTYPE(opcodetype, valtype)& item, vSolution)
  7027.     {
  7028.         if (item.first == OP_PUBKEYHASH)
  7029.         {
  7030.             hash160Ret = uint160(item.second);
  7031.             return true;
  7032.         }
  7033.     }
  7034.     return false;
  7035. }
  7036. bool SignSignature(const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType, CScript scriptPrereq)
  7037. {
  7038.     assert(nIn < txTo.vin.size());
  7039.     CTxIn& txin = txTo.vin[nIn];
  7040.     assert(txin.prevout.n < txFrom.vout.size());
  7041.     const CTxOut& txout = txFrom.vout[txin.prevout.n];
  7042.     uint256 hash = SignatureHash(scriptPrereq + txout.scriptPubKey, txTo, nIn, nHashType);
  7043.     if (!Solver(txout.scriptPubKey, hash, nHashType, txin.scriptSig))
  7044.         return false;
  7045.     txin.scriptSig = scriptPrereq + txin.scriptSig;
  7046.     if (scriptPrereq.empty())
  7047.         if (!EvalScript(txin.scriptSig + CScript(OP_CODESEPARATOR) + txout.scriptPubKey, txTo, nIn))
  7048.             return false;
  7049.     return true;
  7050. }
  7051. bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, int nHashType)
  7052. {
  7053.     assert(nIn < txTo.vin.size());
  7054.     const CTxIn& txin = txTo.vin[nIn];
  7055.     if (txin.prevout.n >= txFrom.vout.size())
  7056.         return false;
  7057.     const CTxOut& txout = txFrom.vout[txin.prevout.n];
  7058.     if (txin.prevout.hash != txFrom.GetHash())
  7059.         return false;
  7060.     return EvalScript(txin.scriptSig + CScript(OP_CODESEPARATOR) + txout.scriptPubKey, txTo, nIn, nHashType);
  7061. }
  7062. class CTransaction;
  7063. enum
  7064. {
  7065.     SIGHASH_ALL = 1,
  7066.     SIGHASH_NONE = 2,
  7067.     SIGHASH_SINGLE = 3,
  7068.     SIGHASH_ANYONECANPAY = 0x80,
  7069. };
  7070. enum opcodetype
  7071. {
  7072.     OP_0=0,
  7073.     OP_FALSE=OP_0,
  7074.     OP_PUSHDATA1=76,
  7075.     OP_PUSHDATA2,
  7076.     OP_PUSHDATA4,
  7077.     OP_1NEGATE,
  7078.     OP_RESERVED,
  7079.     OP_1,
  7080.     OP_TRUE=OP_1,
  7081.     OP_2,
  7082.     OP_3,
  7083.     OP_4,
  7084.     OP_5,
  7085.     OP_6,
  7086.     OP_7,
  7087.     OP_8,
  7088.     OP_9,
  7089.     OP_10,
  7090.     OP_11,
  7091.     OP_12,
  7092.     OP_13,
  7093.     OP_14,
  7094.     OP_15,
  7095.     OP_16,
  7096.     OP_NOP,
  7097.     OP_VER,
  7098.     OP_IF,
  7099.     OP_NOTIF,
  7100.     OP_VERIF,
  7101.     OP_VERNOTIF,
  7102.     OP_ELSE,
  7103.     OP_ENDIF,
  7104.     OP_VERIFY,
  7105.     OP_RETURN,
  7106.     OP_TOALTSTACK,
  7107.     OP_FROMALTSTACK,
  7108.     OP_2DROP,
  7109.     OP_2DUP,
  7110.     OP_3DUP,
  7111.     OP_2OVER,
  7112.     OP_2ROT,
  7113.     OP_2SWAP,
  7114.     OP_IFDUP,
  7115.     OP_DEPTH,
  7116.     OP_DROP,
  7117.     OP_DUP,
  7118.     OP_NIP,
  7119.     OP_OVER,
  7120.     OP_PICK,
  7121.     OP_ROLL,
  7122.     OP_ROT,
  7123.     OP_SWAP,
  7124.     OP_TUCK,
  7125.     OP_CAT,
  7126.     OP_SUBSTR,
  7127.     OP_LEFT,
  7128.     OP_RIGHT,
  7129.     OP_SIZE,
  7130.     OP_INVERT,
  7131.     OP_AND,
  7132.     OP_OR,
  7133.     OP_XOR,
  7134.     OP_EQUAL,
  7135.     OP_EQUALVERIFY,
  7136.     OP_RESERVED1,
  7137.     OP_RESERVED2,
  7138.     OP_1ADD,
  7139.     OP_1SUB,
  7140.     OP_2MUL,
  7141.     OP_2DIV,
  7142.     OP_NEGATE,
  7143.     OP_ABS,
  7144.     OP_NOT,
  7145.     OP_0NOTEQUAL,
  7146.     OP_ADD,
  7147.     OP_SUB,
  7148.     OP_MUL,
  7149.     OP_DIV,
  7150.     OP_MOD,
  7151.     OP_LSHIFT,
  7152.     OP_RSHIFT,
  7153.     OP_BOOLAND,
  7154.     OP_BOOLOR,
  7155.     OP_NUMEQUAL,
  7156.     OP_NUMEQUALVERIFY,
  7157.     OP_NUMNOTEQUAL,
  7158.     OP_LESSTHAN,
  7159.     OP_GREATERTHAN,
  7160.     OP_LESSTHANOREQUAL,
  7161.     OP_GREATERTHANOREQUAL,
  7162.     OP_MIN,
  7163.     OP_MAX,
  7164.     OP_WITHIN,
  7165.     OP_RIPEMD160,
  7166.     OP_SHA1,
  7167.     OP_SHA256,
  7168.     OP_HASH160,
  7169.     OP_HASH256,
  7170.     OP_CODESEPARATOR,
  7171.     OP_CHECKSIG,
  7172.     OP_CHECKSIGVERIFY,
  7173.     OP_CHECKMULTISIG,
  7174.     OP_CHECKMULTISIGVERIFY,
  7175.     OP_SINGLEBYTE_END = 0xF0,
  7176.     OP_DOUBLEBYTE_BEGIN = 0xF000,
  7177.     OP_PUBKEY,
  7178.     OP_PUBKEYHASH,
  7179.     OP_INVALIDOPCODE = 0xFFFF,
  7180. };
  7181. inline const char* GetOpName(opcodetype opcode)
  7182. {
  7183.     switch (opcode)
  7184.     {
  7185.     case OP_0                      : return "0";
  7186.     case OP_PUSHDATA1              : return "OP_PUSHDATA1";
  7187.     case OP_PUSHDATA2              : return "OP_PUSHDATA2";
  7188.     case OP_PUSHDATA4              : return "OP_PUSHDATA4";
  7189.     case OP_1NEGATE                : return "-1";
  7190.     case OP_RESERVED               : return "OP_RESERVED";
  7191.     case OP_1                      : return "1";
  7192.     case OP_2                      : return "2";
  7193.     case OP_3                      : return "3";
  7194.     case OP_4                      : return "4";
  7195.     case OP_5                      : return "5";
  7196.     case OP_6                      : return "6";
  7197.     case OP_7                      : return "7";
  7198.     case OP_8                      : return "8";
  7199.     case OP_9                      : return "9";
  7200.     case OP_10                     : return "10";
  7201.     case OP_11                     : return "11";
  7202.     case OP_12                     : return "12";
  7203.     case OP_13                     : return "13";
  7204.     case OP_14                     : return "14";
  7205.     case OP_15                     : return "15";
  7206.     case OP_16                     : return "16";
  7207.     case OP_NOP                    : return "OP_NOP";
  7208.     case OP_VER                    : return "OP_VER";
  7209.     case OP_IF                     : return "OP_IF";
  7210.     case OP_NOTIF                  : return "OP_NOTIF";
  7211.     case OP_VERIF                  : return "OP_VERIF";
  7212.     case OP_VERNOTIF               : return "OP_VERNOTIF";
  7213.     case OP_ELSE                   : return "OP_ELSE";
  7214.     case OP_ENDIF                  : return "OP_ENDIF";
  7215.     case OP_VERIFY                 : return "OP_VERIFY";
  7216.     case OP_RETURN                 : return "OP_RETURN";
  7217.     case OP_TOALTSTACK             : return "OP_TOALTSTACK";
  7218.     case OP_FROMALTSTACK           : return "OP_FROMALTSTACK";
  7219.     case OP_2DROP                  : return "OP_2DROP";
  7220.     case OP_2DUP                   : return "OP_2DUP";
  7221.     case OP_3DUP                   : return "OP_3DUP";
  7222.     case OP_2OVER                  : return "OP_2OVER";
  7223.     case OP_2ROT                   : return "OP_2ROT";
  7224.     case OP_2SWAP                  : return "OP_2SWAP";
  7225.     case OP_IFDUP                  : return "OP_IFDUP";
  7226.     case OP_DEPTH                  : return "OP_DEPTH";
  7227.     case OP_DROP                   : return "OP_DROP";
  7228.     case OP_DUP                    : return "OP_DUP";
  7229.     case OP_NIP                    : return "OP_NIP";
  7230.     case OP_OVER                   : return "OP_OVER";
  7231.     case OP_PICK                   : return "OP_PICK";
  7232.     case OP_ROLL                   : return "OP_ROLL";
  7233.     case OP_ROT                    : return "OP_ROT";
  7234.     case OP_SWAP                   : return "OP_SWAP";
  7235.     case OP_TUCK                   : return "OP_TUCK";
  7236.     case OP_CAT                    : return "OP_CAT";
  7237.     case OP_SUBSTR                 : return "OP_SUBSTR";
  7238.     case OP_LEFT                   : return "OP_LEFT";
  7239.     case OP_RIGHT                  : return "OP_RIGHT";
  7240.     case OP_SIZE                   : return "OP_SIZE";
  7241.     case OP_INVERT                 : return "OP_INVERT";
  7242.     case OP_AND                    : return "OP_AND";
  7243.     case OP_OR                     : return "OP_OR";
  7244.     case OP_XOR                    : return "OP_XOR";
  7245.     case OP_EQUAL                  : return "OP_EQUAL";
  7246.     case OP_EQUALVERIFY            : return "OP_EQUALVERIFY";
  7247.     case OP_RESERVED1              : return "OP_RESERVED1";
  7248.     case OP_RESERVED2              : return "OP_RESERVED2";
  7249.     case OP_1ADD                   : return "OP_1ADD";
  7250.     case OP_1SUB                   : return "OP_1SUB";
  7251.     case OP_2MUL                   : return "OP_2MUL";
  7252.     case OP_2DIV                   : return "OP_2DIV";
  7253.     case OP_NEGATE                 : return "OP_NEGATE";
  7254.     case OP_ABS                    : return "OP_ABS";
  7255.     case OP_NOT                    : return "OP_NOT";
  7256.     case OP_0NOTEQUAL              : return "OP_0NOTEQUAL";
  7257.     case OP_ADD                    : return "OP_ADD";
  7258.     case OP_SUB                    : return "OP_SUB";
  7259.     case OP_MUL                    : return "OP_MUL";
  7260.     case OP_DIV                    : return "OP_DIV";
  7261.     case OP_MOD                    : return "OP_MOD";
  7262.     case OP_LSHIFT                 : return "OP_LSHIFT";
  7263.     case OP_RSHIFT                 : return "OP_RSHIFT";
  7264.     case OP_BOOLAND                : return "OP_BOOLAND";
  7265.     case OP_BOOLOR                 : return "OP_BOOLOR";
  7266.     case OP_NUMEQUAL               : return "OP_NUMEQUAL";
  7267.     case OP_NUMEQUALVERIFY         : return "OP_NUMEQUALVERIFY";
  7268.     case OP_NUMNOTEQUAL            : return "OP_NUMNOTEQUAL";
  7269.     case OP_LESSTHAN               : return "OP_LESSTHAN";
  7270.     case OP_GREATERTHAN            : return "OP_GREATERTHAN";
  7271.     case OP_LESSTHANOREQUAL        : return "OP_LESSTHANOREQUAL";
  7272.     case OP_GREATERTHANOREQUAL     : return "OP_GREATERTHANOREQUAL";
  7273.     case OP_MIN                    : return "OP_MIN";
  7274.     case OP_MAX                    : return "OP_MAX";
  7275.     case OP_WITHIN                 : return "OP_WITHIN";
  7276.     case OP_RIPEMD160              : return "OP_RIPEMD160";
  7277.     case OP_SHA1                   : return "OP_SHA1";
  7278.     case OP_SHA256                 : return "OP_SHA256";
  7279.     case OP_HASH160                : return "OP_HASH160";
  7280.     case OP_HASH256                : return "OP_HASH256";
  7281.     case OP_CODESEPARATOR          : return "OP_CODESEPARATOR";
  7282.     case OP_CHECKSIG               : return "OP_CHECKSIG";
  7283.     case OP_CHECKSIGVERIFY         : return "OP_CHECKSIGVERIFY";
  7284.     case OP_CHECKMULTISIG          : return "OP_CHECKMULTISIG";
  7285.     case OP_CHECKMULTISIGVERIFY    : return "OP_CHECKMULTISIGVERIFY";
  7286.     case OP_SINGLEBYTE_END         : return "OP_SINGLEBYTE_END";
  7287.     case OP_DOUBLEBYTE_BEGIN       : return "OP_DOUBLEBYTE_BEGIN";
  7288.     case OP_PUBKEY                 : return "OP_PUBKEY";
  7289.     case OP_PUBKEYHASH             : return "OP_PUBKEYHASH";
  7290.     case OP_INVALIDOPCODE          : return "OP_INVALIDOPCODE";
  7291.     default:
  7292.         return "UNKNOWN_OPCODE";
  7293.     }
  7294. };
  7295. inline string ValueString(const vector<unsigned char>& vch)
  7296. {
  7297.     if (vch.size() <= 4)
  7298.         return strprintf("%d", CBigNum(vch).getint());
  7299.     else
  7300.         return HexNumStr(vch.begin(), vch.end());
  7301. }
  7302. inline string StackString(const vector<vector<unsigned char> >& vStack)
  7303. {
  7304.     string str;
  7305.     foreach(const vector<unsigned char>& vch, vStack)
  7306.     {
  7307.         if (!str.empty())
  7308.             str += " ";
  7309.         str += ValueString(vch);
  7310.     }
  7311.     return str;
  7312. }
  7313. class CScript : public vector<unsigned char>
  7314. {
  7315. protected:
  7316.     CScript& push_int64(int64 n)
  7317.     {
  7318.         if (n == -1 || (n >= 1 && n <= 16))
  7319.         {
  7320.             push_back(n + (OP_1 - 1));
  7321.         }
  7322.         else
  7323.         {
  7324.             CBigNum bn(n);
  7325.             *this << bn.getvch();
  7326.         }
  7327.         return (*this);
  7328.     }
  7329.     CScript& push_uint64(uint64 n)
  7330.     {
  7331.         if (n == -1 || (n >= 1 && n <= 16))
  7332.         {
  7333.             push_back(n + (OP_1 - 1));
  7334.         }
  7335.         else
  7336.         {
  7337.             CBigNum bn(n);
  7338.             *this << bn.getvch();
  7339.         }
  7340.         return (*this);
  7341.     }
  7342. public:
  7343.     CScript() { }
  7344.     CScript(const CScript& b) : vector<unsigned char>(b.begin(), b.end()) { }
  7345.     CScript(const_iterator pbegin, const_iterator pend) : vector<unsigned char>(pbegin, pend) { }
  7346. #ifndef _MSC_VER
  7347.     CScript(const unsigned char* pbegin, const unsigned char* pend) : vector<unsigned char>(pbegin, pend) { }
  7348. #endif
  7349.     CScript& operator+=(const CScript& b)
  7350.     {
  7351.         insert(end(), b.begin(), b.end());
  7352.         return *this;
  7353.     }
  7354.     friend CScript operator+(const CScript& a, const CScript& b)
  7355.     {
  7356.         CScript ret = a;
  7357.         ret += b;
  7358.         return (ret);
  7359.     }
  7360.     explicit CScript(char b)           { operator<<(b); }
  7361.     explicit CScript(short b)          { operator<<(b); }
  7362.     explicit CScript(int b)            { operator<<(b); }
  7363.     explicit CScript(long b)           { operator<<(b); }
  7364.     explicit CScript(int64 b)          { operator<<(b); }
  7365.     explicit CScript(unsigned char b)  { operator<<(b); }
  7366.     explicit CScript(unsigned int b)   { operator<<(b); }
  7367.     explicit CScript(unsigned short b) { operator<<(b); }
  7368.     explicit CScript(unsigned long b)  { operator<<(b); }
  7369.     explicit CScript(uint64 b)         { operator<<(b); }
  7370.     explicit CScript(opcodetype b)     { operator<<(b); }
  7371.     explicit CScript(const uint256& b) { operator<<(b); }
  7372.     explicit CScript(const CBigNum& b) { operator<<(b); }
  7373.     explicit CScript(const vector<unsigned char>& b) { operator<<(b); }
  7374.     CScript& operator<<(char b)           { return (push_int64(b)); }
  7375.     CScript& operator<<(short b)          { return (push_int64(b)); }
  7376.     CScript& operator<<(int b)            { return (push_int64(b)); }
  7377.     CScript& operator<<(long b)           { return (push_int64(b)); }
  7378.     CScript& operator<<(int64 b)          { return (push_int64(b)); }
  7379.     CScript& operator<<(unsigned char b)  { return (push_uint64(b)); }
  7380.     CScript& operator<<(unsigned int b)   { return (push_uint64(b)); }
  7381.     CScript& operator<<(unsigned short b) { return (push_uint64(b)); }
  7382.     CScript& operator<<(unsigned long b)  { return (push_uint64(b)); }
  7383.     CScript& operator<<(uint64 b)         { return (push_uint64(b)); }
  7384.     CScript& operator<<(opcodetype opcode)
  7385.     {
  7386.         if (opcode <= OP_SINGLEBYTE_END)
  7387.         {
  7388.             insert(end(), (unsigned char)opcode);
  7389.         }
  7390.         else
  7391.         {
  7392.             assert(opcode >= OP_DOUBLEBYTE_BEGIN);
  7393.             insert(end(), (unsigned char)(opcode >> 8));
  7394.             insert(end(), (unsigned char)(opcode & 0xFF));
  7395.         }
  7396.         return (*this);
  7397.     }
  7398.     CScript& operator<<(const uint160& b)
  7399.     {
  7400.         insert(end(), sizeof(b));
  7401.         insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b));
  7402.         return (*this);
  7403.     }
  7404.     CScript& operator<<(const uint256& b)
  7405.     {
  7406.         insert(end(), sizeof(b));
  7407.         insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b));
  7408.         return (*this);
  7409.     }
  7410.     CScript& operator<<(const CBigNum& b)
  7411.     {
  7412.         *this << b.getvch();
  7413.         return (*this);
  7414.     }
  7415.     CScript& operator<<(const vector<unsigned char>& b)
  7416.     {
  7417.         if (b.size() < OP_PUSHDATA1)
  7418.         {
  7419.             insert(end(), (unsigned char)b.size());
  7420.         }
  7421.         else if (b.size() <= 0xff)
  7422.         {
  7423.             insert(end(), OP_PUSHDATA1);
  7424.             insert(end(), (unsigned char)b.size());
  7425.         }
  7426.         else
  7427.         {
  7428.             insert(end(), OP_PUSHDATA2);
  7429.             unsigned short nSize = b.size();
  7430.             insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize));
  7431.         }
  7432.         insert(end(), b.begin(), b.end());
  7433.         return (*this);
  7434.     }
  7435.     CScript& operator<<(const CScript& b)
  7436.     {
  7437.         assert(("warning: pushing a CScript onto a CScript with << is probably not intended, use + to concatenate", false));
  7438.         return (*this);
  7439.     }
  7440.     bool GetOp(iterator& pc, opcodetype& opcodeRet, vector<unsigned char>& vchRet)
  7441.     {
  7442.          const_iterator pc2 = pc;
  7443.          bool fRet = GetOp(pc2, opcodeRet, vchRet);
  7444.          pc = begin() + (pc2 - begin());
  7445.          return fRet;
  7446.     }
  7447.     bool GetOp(const_iterator& pc, opcodetype& opcodeRet, vector<unsigned char>& vchRet) const
  7448.     {
  7449.         opcodeRet = OP_INVALIDOPCODE;
  7450.         vchRet.clear();
  7451.         if (pc >= end())
  7452.             return false;
  7453.         unsigned int opcode = *pc++;
  7454.         if (opcode >= OP_SINGLEBYTE_END)
  7455.         {
  7456.             if (pc + 1 > end())
  7457.                 return false;
  7458.             opcode <<= 8;
  7459.             opcode |= *pc++;
  7460.         }
  7461.         if (opcode <= OP_PUSHDATA4)
  7462.         {
  7463.             unsigned int nSize = opcode;
  7464.             if (opcode == OP_PUSHDATA1)
  7465.             {
  7466.                 if (pc + 1 > end())
  7467.                     return false;
  7468.                 nSize = *pc++;
  7469.             }
  7470.             else if (opcode == OP_PUSHDATA2)
  7471.             {
  7472.                 if (pc + 2 > end())
  7473.                     return false;
  7474.                 nSize = 0;
  7475.                 memcpy(&nSize, &pc[0], 2);
  7476.                 pc += 2;
  7477.             }
  7478.             else if (opcode == OP_PUSHDATA4)
  7479.             {
  7480.                 if (pc + 4 > end())
  7481.                     return false;
  7482.                 memcpy(&nSize, &pc[0], 4);
  7483.                 pc += 4;
  7484.             }
  7485.             if (pc + nSize > end())
  7486.                 return false;
  7487.             vchRet.assign(pc, pc + nSize);
  7488.             pc += nSize;
  7489.         }
  7490.         opcodeRet = (opcodetype)opcode;
  7491.         return true;
  7492.     }
  7493.     void FindAndDelete(const CScript& b)
  7494.     {
  7495.         iterator pc = begin();
  7496.         opcodetype opcode;
  7497.         vector<unsigned char> vchPushValue;
  7498.         int count = 0;
  7499.         do
  7500.         {
  7501.             while (end() - pc >= b.size() && memcmp(&pc[0], &b[0], b.size()) == 0)
  7502.             {
  7503.                 erase(pc, pc + b.size());
  7504.                 count++;
  7505.             }
  7506.         }
  7507.         while (GetOp(pc, opcode, vchPushValue));
  7508.     }
  7509.     void PrintHex() const
  7510.     {
  7511.         printf("CScript(%s)\n", HexStr(begin(), end()).c_str());
  7512.     }
  7513.     string ToString() const
  7514.     {
  7515.         string str;
  7516.         opcodetype opcode;
  7517.         vector<unsigned char> vch;
  7518.         const_iterator it = begin();
  7519.         while (GetOp(it, opcode, vch))
  7520.         {
  7521.             if (!str.empty())
  7522.                 str += " ";
  7523.             if (opcode <= OP_PUSHDATA4)
  7524.                 str += ValueString(vch);
  7525.             else
  7526.                 str += GetOpName(opcode);
  7527.         }
  7528.         return str;
  7529.     }
  7530.     void print() const
  7531.     {
  7532.         printf("%s\n", ToString().c_str());
  7533.     }
  7534. };
  7535. bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType=0,
  7536.                 vector<vector<unsigned char> >* pvStackRet=NULL);
  7537. uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType);
  7538. bool IsMine(const CScript& scriptPubKey);
  7539. bool ExtractPubKey(const CScript& scriptPubKey, bool fMineOnly, vector<unsigned char>& vchPubKeyRet);
  7540. bool ExtractHash160(const CScript& scriptPubKey, uint160& hash160Ret);
  7541. bool SignSignature(const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL, CScript scriptPrereq=CScript());
  7542. bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, int nHashType=0);
  7543. #include <vector>
  7544. #include <map>
  7545. #include <boost/type_traits/is_fundamental.hpp>
  7546. #if defined(_MSC_VER) || defined(__BORLANDC__)
  7547. typedef __int64  int64;
  7548. typedef unsigned __int64  uint64;
  7549. #else
  7550. typedef long long  int64;
  7551. typedef unsigned long long  uint64;
  7552. #endif
  7553. #if defined(_MSC_VER) && _MSC_VER < 1300
  7554. #define for  if (false) ; else for
  7555. #endif
  7556. class CScript;
  7557. class CDataStream;
  7558. class CAutoFile;
  7559. static const int VERSION = 101;
  7560. enum
  7561. {
  7562.     SER_NETWORK         = (1 << 0),
  7563.     SER_DISK            = (1 << 1),
  7564.     SER_GETHASH         = (1 << 2),
  7565.     SER_SKIPSIG         = (1 << 16),
  7566.     SER_BLOCKHEADERONLY = (1 << 17),
  7567. };
  7568. #define IMPLEMENT_SERIALIZE(statements)    \
  7569.     unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const  \
  7570.     {                                           \
  7571.         CSerActionGetSerializeSize ser_action;  \
  7572.         const bool fGetSize = true;             \
  7573.         const bool fWrite = false;              \
  7574.         const bool fRead = false;               \
  7575.         unsigned int nSerSize = 0;              \
  7576.         ser_streamplaceholder s;                \
  7577.         s.nType = nType;                        \
  7578.         s.nVersion = nVersion;                  \
  7579.         {statements}                            \
  7580.         return nSerSize;                        \
  7581.     }                                           \
  7582.     template<typename Stream>                   \
  7583.     void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const  \
  7584.     {                                           \
  7585.         CSerActionSerialize ser_action;         \
  7586.         const bool fGetSize = false;            \
  7587.         const bool fWrite = true;               \
  7588.         const bool fRead = false;               \
  7589.         unsigned int nSerSize = 0;              \
  7590.         {statements}                            \
  7591.     }                                           \
  7592.     template<typename Stream>                   \
  7593.     void Unserialize(Stream& s, int nType=0, int nVersion=VERSION)  \
  7594.     {                                           \
  7595.         CSerActionUnserialize ser_action;       \
  7596.         const bool fGetSize = false;            \
  7597.         const bool fWrite = false;              \
  7598.         const bool fRead = true;                \
  7599.         unsigned int nSerSize = 0;              \
  7600.         {statements}                            \
  7601.     }
  7602. #define READWRITE(obj)      (nSerSize += ::SerReadWrite(s, (obj), nType, nVersion, ser_action))
  7603. #define WRITEDATA(s, obj)   s.write((char*)&(obj), sizeof(obj))
  7604. #define READDATA(s, obj)    s.read((char*)&(obj), sizeof(obj))
  7605. inline unsigned int GetSerializeSize(char a,           int, int=0) { return sizeof(a); }
  7606. inline unsigned int GetSerializeSize(signed char a,    int, int=0) { return sizeof(a); }
  7607. inline unsigned int GetSerializeSize(unsigned char a,  int, int=0) { return sizeof(a); }
  7608. inline unsigned int GetSerializeSize(signed short a,   int, int=0) { return sizeof(a); }
  7609. inline unsigned int GetSerializeSize(unsigned short a, int, int=0) { return sizeof(a); }
  7610. inline unsigned int GetSerializeSize(signed int a,     int, int=0) { return sizeof(a); }
  7611. inline unsigned int GetSerializeSize(unsigned int a,   int, int=0) { return sizeof(a); }
  7612. inline unsigned int GetSerializeSize(signed long a,    int, int=0) { return sizeof(a); }
  7613. inline unsigned int GetSerializeSize(unsigned long a,  int, int=0) { return sizeof(a); }
  7614. inline unsigned int GetSerializeSize(int64 a,          int, int=0) { return sizeof(a); }
  7615. inline unsigned int GetSerializeSize(uint64 a,         int, int=0) { return sizeof(a); }
  7616. inline unsigned int GetSerializeSize(float a,          int, int=0) { return sizeof(a); }
  7617. inline unsigned int GetSerializeSize(double a,         int, int=0) { return sizeof(a); }
  7618. template<typename Stream> inline void Serialize(Stream& s, char a,           int, int=0) { WRITEDATA(s, a); }
  7619. template<typename Stream> inline void Serialize(Stream& s, signed char a,    int, int=0) { WRITEDATA(s, a); }
  7620. template<typename Stream> inline void Serialize(Stream& s, unsigned char a,  int, int=0) { WRITEDATA(s, a); }
  7621. template<typename Stream> inline void Serialize(Stream& s, signed short a,   int, int=0) { WRITEDATA(s, a); }
  7622. template<typename Stream> inline void Serialize(Stream& s, unsigned short a, int, int=0) { WRITEDATA(s, a); }
  7623. template<typename Stream> inline void Serialize(Stream& s, signed int a,     int, int=0) { WRITEDATA(s, a); }
  7624. template<typename Stream> inline void Serialize(Stream& s, unsigned int a,   int, int=0) { WRITEDATA(s, a); }
  7625. template<typename Stream> inline void Serialize(Stream& s, signed long a,    int, int=0) { WRITEDATA(s, a); }
  7626. template<typename Stream> inline void Serialize(Stream& s, unsigned long a,  int, int=0) { WRITEDATA(s, a); }
  7627. template<typename Stream> inline void Serialize(Stream& s, int64 a,          int, int=0) { WRITEDATA(s, a); }
  7628. template<typename Stream> inline void Serialize(Stream& s, uint64 a,         int, int=0) { WRITEDATA(s, a); }
  7629. template<typename Stream> inline void Serialize(Stream& s, float a,          int, int=0) { WRITEDATA(s, a); }
  7630. template<typename Stream> inline void Serialize(Stream& s, double a,         int, int=0) { WRITEDATA(s, a); }
  7631. template<typename Stream> inline void Unserialize(Stream& s, char& a,           int, int=0) { READDATA(s, a); }
  7632. template<typename Stream> inline void Unserialize(Stream& s, signed char& a,    int, int=0) { READDATA(s, a); }
  7633. template<typename Stream> inline void Unserialize(Stream& s, unsigned char& a,  int, int=0) { READDATA(s, a); }
  7634. template<typename Stream> inline void Unserialize(Stream& s, signed short& a,   int, int=0) { READDATA(s, a); }
  7635. template<typename Stream> inline void Unserialize(Stream& s, unsigned short& a, int, int=0) { READDATA(s, a); }
  7636. template<typename Stream> inline void Unserialize(Stream& s, signed int& a,     int, int=0) { READDATA(s, a); }
  7637. template<typename Stream> inline void Unserialize(Stream& s, unsigned int& a,   int, int=0) { READDATA(s, a); }
  7638. template<typename Stream> inline void Unserialize(Stream& s, signed long& a,    int, int=0) { READDATA(s, a); }
  7639. template<typename Stream> inline void Unserialize(Stream& s, unsigned long& a,  int, int=0) { READDATA(s, a); }
  7640. template<typename Stream> inline void Unserialize(Stream& s, int64& a,          int, int=0) { READDATA(s, a); }
  7641. template<typename Stream> inline void Unserialize(Stream& s, uint64& a,         int, int=0) { READDATA(s, a); }
  7642. template<typename Stream> inline void Unserialize(Stream& s, float& a,          int, int=0) { READDATA(s, a); }
  7643. template<typename Stream> inline void Unserialize(Stream& s, double& a,         int, int=0) { READDATA(s, a); }
  7644. inline unsigned int GetSerializeSize(bool a, int, int=0)                          { return sizeof(char); }
  7645. template<typename Stream> inline void Serialize(Stream& s, bool a, int, int=0)    { char f=a; WRITEDATA(s, f); }
  7646. template<typename Stream> inline void Unserialize(Stream& s, bool& a, int, int=0) { char f; READDATA(s, f); a=f; }
  7647. inline unsigned int GetSizeOfCompactSize(uint64 nSize)
  7648. {
  7649.     if (nSize < UCHAR_MAX-2)     return sizeof(unsigned char);
  7650.     else if (nSize <= USHRT_MAX) return sizeof(unsigned char) + sizeof(unsigned short);
  7651.     else if (nSize <= UINT_MAX)  return sizeof(unsigned char) + sizeof(unsigned int);
  7652.     else                         return sizeof(unsigned char) + sizeof(uint64);
  7653. }
  7654. template<typename Stream>
  7655. void WriteCompactSize(Stream& os, uint64 nSize)
  7656. {
  7657.     if (nSize < UCHAR_MAX-2)
  7658.     {
  7659.         unsigned char chSize = nSize;
  7660.         WRITEDATA(os, chSize);
  7661.     }
  7662.     else if (nSize <= USHRT_MAX)
  7663.     {
  7664.         unsigned char chSize = UCHAR_MAX-2;
  7665.         unsigned short xSize = nSize;
  7666.         WRITEDATA(os, chSize);
  7667.         WRITEDATA(os, xSize);
  7668.     }
  7669.     else if (nSize <= UINT_MAX)
  7670.     {
  7671.         unsigned char chSize = UCHAR_MAX-1;
  7672.         unsigned int xSize = nSize;
  7673.         WRITEDATA(os, chSize);
  7674.         WRITEDATA(os, xSize);
  7675.     }
  7676.     else
  7677.     {
  7678.         unsigned char chSize = UCHAR_MAX;
  7679.         WRITEDATA(os, chSize);
  7680.         WRITEDATA(os, nSize);
  7681.     }
  7682.     return;
  7683. }
  7684. template<typename Stream>
  7685. uint64 ReadCompactSize(Stream& is)
  7686. {
  7687.     unsigned char chSize;
  7688.     READDATA(is, chSize);
  7689.     if (chSize < UCHAR_MAX-2)
  7690.     {
  7691.         return chSize;
  7692.     }
  7693.     else if (chSize == UCHAR_MAX-2)
  7694.     {
  7695.         unsigned short nSize;
  7696.         READDATA(is, nSize);
  7697.         return nSize;
  7698.     }
  7699.     else if (chSize == UCHAR_MAX-1)
  7700.     {
  7701.         unsigned int nSize;
  7702.         READDATA(is, nSize);
  7703.         return nSize;
  7704.     }
  7705.     else
  7706.     {
  7707.         uint64 nSize;
  7708.         READDATA(is, nSize);
  7709.         return nSize;
  7710.     }
  7711. }
  7712. #define FLATDATA(obj)   REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj)))
  7713. class CFlatData
  7714. {
  7715. protected:
  7716.     char* pbegin;
  7717.     char* pend;
  7718. public:
  7719.     CFlatData(void* pbeginIn, void* pendIn) : pbegin((char*)pbeginIn), pend((char*)pendIn) { }
  7720.     char* begin() { return pbegin; }
  7721.     const char* begin() const { return pbegin; }
  7722.     char* end() { return pend; }
  7723.     const char* end() const { return pend; }
  7724.     unsigned int GetSerializeSize(int, int=0) const
  7725.     {
  7726.         return pend - pbegin;
  7727.     }
  7728.     template<typename Stream>
  7729.     void Serialize(Stream& s, int, int=0) const
  7730.     {
  7731.         s.write(pbegin, pend - pbegin);
  7732.     }
  7733.     template<typename Stream>
  7734.     void Unserialize(Stream& s, int, int=0)
  7735.     {
  7736.         s.read(pbegin, pend - pbegin);
  7737.     }
  7738. };
  7739. template<std::size_t LEN>
  7740. class CFixedFieldString
  7741. {
  7742. protected:
  7743.     const string* pcstr;
  7744.     string* pstr;
  7745. public:
  7746.     explicit CFixedFieldString(const string& str) : pcstr(&str), pstr(NULL) { }
  7747.     explicit CFixedFieldString(string& str) : pcstr(&str), pstr(&str) { }
  7748.     unsigned int GetSerializeSize(int, int=0) const
  7749.     {
  7750.         return LEN;
  7751.     }
  7752.     template<typename Stream>
  7753.     void Serialize(Stream& s, int, int=0) const
  7754.     {
  7755.         char pszBuf[LEN];
  7756.         strncpy(pszBuf, pcstr->c_str(), LEN);
  7757.         s.write(pszBuf, LEN);
  7758.     }
  7759.     template<typename Stream>
  7760.     void Unserialize(Stream& s, int, int=0)
  7761.     {
  7762.         if (pstr == NULL)
  7763.             throw std::ios_base::failure("CFixedFieldString::Unserialize : trying to unserialize to const string");
  7764.         char pszBuf[LEN+1];
  7765.         s.read(pszBuf, LEN);
  7766.         pszBuf[LEN] = '\0';
  7767.         *pstr = pszBuf;
  7768.     }
  7769. };
  7770. template<typename C> unsigned int GetSerializeSize(const basic_string<C>& str, int, int=0);
  7771. template<typename Stream, typename C> void Serialize(Stream& os, const basic_string<C>& str, int, int=0);
  7772. template<typename Stream, typename C> void Unserialize(Stream& is, basic_string<C>& str, int, int=0);
  7773. template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&);
  7774. template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&);
  7775. template<typename T, typename A> inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion=VERSION);
  7776. 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&);
  7777. 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&);
  7778. template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion=VERSION);
  7779. 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&);
  7780. 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&);
  7781. template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion=VERSION);
  7782. extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion=VERSION);
  7783. template<typename Stream> void Serialize(Stream& os, const CScript& v, int nType, int nVersion=VERSION);
  7784. template<typename Stream> void Unserialize(Stream& is, CScript& v, int nType, int nVersion=VERSION);
  7785. template<typename K, typename T> unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion=VERSION);
  7786. template<typename Stream, typename K, typename T> void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion=VERSION);
  7787. template<typename Stream, typename K, typename T> void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion=VERSION);
  7788. 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);
  7789. 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);
  7790. 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);
  7791. template<typename K, typename Pred, typename A> unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion=VERSION);
  7792. 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);
  7793. template<typename Stream, typename K, typename Pred, typename A> void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion=VERSION);
  7794. template<typename T>
  7795. inline unsigned int GetSerializeSize(const T& a, long nType, int nVersion=VERSION)
  7796. {
  7797.     return a.GetSerializeSize((int)nType, nVersion);
  7798. }
  7799. template<typename Stream, typename T>
  7800. inline void Serialize(Stream& os, const T& a, long nType, int nVersion=VERSION)
  7801. {
  7802.     a.Serialize(os, (int)nType, nVersion);
  7803. }
  7804. template<typename Stream, typename T>
  7805. inline void Unserialize(Stream& is, T& a, long nType, int nVersion=VERSION)
  7806. {
  7807.     a.Unserialize(is, (int)nType, nVersion);
  7808. }
  7809. template<typename C>
  7810. unsigned int GetSerializeSize(const basic_string<C>& str, int, int)
  7811. {
  7812.     return GetSizeOfCompactSize(str.size()) + str.size() * sizeof(str[0]);
  7813. }
  7814. template<typename Stream, typename C>
  7815. void Serialize(Stream& os, const basic_string<C>& str, int, int)
  7816. {
  7817.     WriteCompactSize(os, str.size());
  7818.     if (!str.empty())
  7819.         os.write((char*)&str[0], str.size() * sizeof(str[0]));
  7820. }
  7821. template<typename Stream, typename C>
  7822. void Unserialize(Stream& is, basic_string<C>& str, int, int)
  7823. {
  7824.     unsigned int nSize = ReadCompactSize(is);
  7825.     str.resize(nSize);
  7826.     if (nSize != 0)
  7827.         is.read((char*)&str[0], nSize * sizeof(str[0]));
  7828. }
  7829. template<typename T, typename A>
  7830. unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&)
  7831. {
  7832.     return (GetSizeOfCompactSize(v.size()) + v.size() * sizeof(T));
  7833. }
  7834. template<typename T, typename A>
  7835. unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&)
  7836. {
  7837.     unsigned int nSize = GetSizeOfCompactSize(v.size());
  7838.     for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
  7839.         nSize += GetSerializeSize((*vi), nType, nVersion);
  7840.     return nSize;
  7841. }
  7842. template<typename T, typename A>
  7843. inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion)
  7844. {
  7845.     return GetSerializeSize_impl(v, nType, nVersion, boost::is_fundamental<T>());
  7846. }
  7847. template<typename Stream, typename T, typename A>
  7848. void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&)
  7849. {
  7850.     WriteCompactSize(os, v.size());
  7851.     if (!v.empty())
  7852.         os.write((char*)&v[0], v.size() * sizeof(T));
  7853. }
  7854. template<typename Stream, typename T, typename A>
  7855. void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&)
  7856. {
  7857.     WriteCompactSize(os, v.size());
  7858.     for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
  7859.         ::Serialize(os, (*vi), nType, nVersion);
  7860. }
  7861. template<typename Stream, typename T, typename A>
  7862. inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion)
  7863. {
  7864.     Serialize_impl(os, v, nType, nVersion, boost::is_fundamental<T>());
  7865. }
  7866. template<typename Stream, typename T, typename A>
  7867. void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&)
  7868. {
  7869.     v.clear();
  7870.     unsigned int nSize = ReadCompactSize(is);
  7871.     unsigned int i = 0;
  7872.     while (i < nSize)
  7873.     {
  7874.         unsigned int blk = min(nSize - i, 1 + 4999999 / sizeof(T));
  7875.         v.resize(i + blk);
  7876.         is.read((char*)&v[i], blk * sizeof(T));
  7877.         i += blk;
  7878.     }
  7879. }
  7880. template<typename Stream, typename T, typename A>
  7881. void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&)
  7882. {
  7883.     v.clear();
  7884.     unsigned int nSize = ReadCompactSize(is);
  7885.     unsigned int i = 0;
  7886.     unsigned int nMid = 0;
  7887.     while (nMid < nSize)
  7888.     {
  7889.         nMid += 5000000 / sizeof(T);
  7890.         if (nMid > nSize)
  7891.             nMid = nSize;
  7892.         v.resize(nMid);
  7893.         for (; i < nMid; i++)
  7894.             Unserialize(is, v[i], nType, nVersion);
  7895.     }
  7896. }
  7897. template<typename Stream, typename T, typename A>
  7898. inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion)
  7899. {
  7900.     Unserialize_impl(is, v, nType, nVersion, boost::is_fundamental<T>());
  7901. }
  7902. inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion)
  7903. {
  7904.     return GetSerializeSize((const vector<unsigned char>&)v, nType, nVersion);
  7905. }
  7906. template<typename Stream>
  7907. void Serialize(Stream& os, const CScript& v, int nType, int nVersion)
  7908. {
  7909.     Serialize(os, (const vector<unsigned char>&)v, nType, nVersion);
  7910. }
  7911. template<typename Stream>
  7912. void Unserialize(Stream& is, CScript& v, int nType, int nVersion)
  7913. {
  7914.     Unserialize(is, (vector<unsigned char>&)v, nType, nVersion);
  7915. }
  7916. template<typename K, typename T>
  7917. unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion)
  7918. {
  7919.     return GetSerializeSize(item.first, nType, nVersion) + GetSerializeSize(item.second, nType, nVersion);
  7920. }
  7921. template<typename Stream, typename K, typename T>
  7922. void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion)
  7923. {
  7924.     Serialize(os, item.first, nType, nVersion);
  7925.     Serialize(os, item.second, nType, nVersion);
  7926. }
  7927. template<typename Stream, typename K, typename T>
  7928. void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion)
  7929. {
  7930.     Unserialize(is, item.first, nType, nVersion);
  7931.     Unserialize(is, item.second, nType, nVersion);
  7932. }
  7933. template<typename K, typename T, typename Pred, typename A>
  7934. unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion)
  7935. {
  7936.     unsigned int nSize = GetSizeOfCompactSize(m.size());
  7937.     for (typename std::map<K, T, Pred, A>::const_iterator mi = m.begin(); mi != m.end(); ++mi)
  7938.         nSize += GetSerializeSize((*mi), nType, nVersion);
  7939.     return nSize;
  7940. }
  7941. template<typename Stream, typename K, typename T, typename Pred, typename A>
  7942. void Serialize(Stream& os, const std::map<K, T, Pred, A>& m, int nType, int nVersion)
  7943. {
  7944.     WriteCompactSize(os, m.size());
  7945.     for (typename std::map<K, T, Pred, A>::const_iterator mi = m.begin(); mi != m.end(); ++mi)
  7946.         Serialize(os, (*mi), nType, nVersion);
  7947. }
  7948. template<typename Stream, typename K, typename T, typename Pred, typename A>
  7949. void Unserialize(Stream& is, std::map<K, T, Pred, A>& m, int nType, int nVersion)
  7950. {
  7951.     m.clear();
  7952.     unsigned int nSize = ReadCompactSize(is);
  7953.     typename std::map<K, T, Pred, A>::iterator mi = m.begin();
  7954.     for (unsigned int i = 0; i < nSize; i++)
  7955.     {
  7956.         pair<K, T> item;
  7957.         Unserialize(is, item, nType, nVersion);
  7958.         mi = m.insert(mi, item);
  7959.     }
  7960. }
  7961. template<typename K, typename Pred, typename A>
  7962. unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion)
  7963. {
  7964.     unsigned int nSize = GetSizeOfCompactSize(m.size());
  7965.     for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it)
  7966.         nSize += GetSerializeSize((*it), nType, nVersion);
  7967.     return nSize;
  7968. }
  7969. template<typename Stream, typename K, typename Pred, typename A>
  7970. void Serialize(Stream& os, const std::set<K, Pred, A>& m, int nType, int nVersion)
  7971. {
  7972.     WriteCompactSize(os, m.size());
  7973.     for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it)
  7974.         Serialize(os, (*it), nType, nVersion);
  7975. }
  7976. template<typename Stream, typename K, typename Pred, typename A>
  7977. void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion)
  7978. {
  7979.     m.clear();
  7980.     unsigned int nSize = ReadCompactSize(is);
  7981.     typename std::set<K, Pred, A>::iterator it = m.begin();
  7982.     for (unsigned int i = 0; i < nSize; i++)
  7983.     {
  7984.         K key;
  7985.         Unserialize(is, key, nType, nVersion);
  7986.         it = m.insert(it, key);
  7987.     }
  7988. }
  7989. class CSerActionGetSerializeSize { };
  7990. class CSerActionSerialize { };
  7991. class CSerActionUnserialize { };
  7992. template<typename Stream, typename T>
  7993. inline unsigned int SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionGetSerializeSize ser_action)
  7994. {
  7995.     return ::GetSerializeSize(obj, nType, nVersion);
  7996. }
  7997. template<typename Stream, typename T>
  7998. inline unsigned int SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionSerialize ser_action)
  7999. {
  8000.     ::Serialize(s, obj, nType, nVersion);
  8001.     return 0;
  8002. }
  8003. template<typename Stream, typename T>
  8004. inline unsigned int SerReadWrite(Stream& s, T& obj, int nType, int nVersion, CSerActionUnserialize ser_action)
  8005. {
  8006.     ::Unserialize(s, obj, nType, nVersion);
  8007.     return 0;
  8008. }
  8009. struct ser_streamplaceholder
  8010. {
  8011.     int nType;
  8012.     int nVersion;
  8013. };
  8014. template<typename T>
  8015. struct secure_allocator : public std::allocator<T>
  8016. {
  8017.     typedef std::allocator<T> base;
  8018.     typedef typename base::size_type size_type;
  8019.     typedef typename base::difference_type  difference_type;
  8020.     typedef typename base::pointer pointer;
  8021.     typedef typename base::const_pointer const_pointer;
  8022.     typedef typename base::reference reference;
  8023.     typedef typename base::const_reference const_reference;
  8024.     typedef typename base::value_type value_type;
  8025.     secure_allocator() throw() {}
  8026.     secure_allocator(const secure_allocator& a) throw() : base(a) {}
  8027.     ~secure_allocator() throw() {}
  8028.     template<typename _Other> struct rebind
  8029.     { typedef secure_allocator<_Other> other; };
  8030.     void deallocate(T* p, std::size_t n)
  8031.     {
  8032.         if (p != NULL)
  8033.             memset(p, 0, sizeof(T) * n);
  8034.         allocator<T>::deallocate(p, n);
  8035.     }
  8036. };
  8037. class CDataStream
  8038. {
  8039. protected:
  8040.     typedef vector<char, secure_allocator<char> > vector_type;
  8041.     vector_type vch;
  8042.     unsigned int nReadPos;
  8043.     short state;
  8044.     short exceptmask;
  8045. public:
  8046.     int nType;
  8047.     int nVersion;
  8048.     typedef vector_type::allocator_type   allocator_type;
  8049.     typedef vector_type::size_type        size_type;
  8050.     typedef vector_type::difference_type  difference_type;
  8051.     typedef vector_type::reference        reference;
  8052.     typedef vector_type::const_reference  const_reference;
  8053.     typedef vector_type::value_type       value_type;
  8054.     typedef vector_type::iterator         iterator;
  8055.     typedef vector_type::const_iterator   const_iterator;
  8056.     typedef vector_type::reverse_iterator reverse_iterator;
  8057.     explicit CDataStream(int nTypeIn=0, int nVersionIn=VERSION)
  8058.     {
  8059.         Init(nTypeIn, nVersionIn);
  8060.     }
  8061.     CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn=0, int nVersionIn=VERSION) : vch(pbegin, pend)
  8062.     {
  8063.         Init(nTypeIn, nVersionIn);
  8064.     }
  8065. #if !defined(_MSC_VER) || _MSC_VER >= 1300
  8066.     CDataStream(const char* pbegin, const char* pend, int nTypeIn=0, int nVersionIn=VERSION) : vch(pbegin, pend)
  8067.     {
  8068.         Init(nTypeIn, nVersionIn);
  8069.     }
  8070. #endif
  8071.     CDataStream(const vector_type& vchIn, int nTypeIn=0, int nVersionIn=VERSION) : vch(vchIn.begin(), vchIn.end())
  8072.     {
  8073.         Init(nTypeIn, nVersionIn);
  8074.     }
  8075.     CDataStream(const vector<char>& vchIn, int nTypeIn=0, int nVersionIn=VERSION) : vch(vchIn.begin(), vchIn.end())
  8076.     {
  8077.         Init(nTypeIn, nVersionIn);
  8078.     }
  8079.     CDataStream(const vector<unsigned char>& vchIn, int nTypeIn=0, int nVersionIn=VERSION) : vch((char*)&vchIn.begin()[0], (char*)&vchIn.end()[0])
  8080.     {
  8081.         Init(nTypeIn, nVersionIn);
  8082.     }
  8083.     void Init(int nTypeIn=0, int nVersionIn=VERSION)
  8084.     {
  8085.         nReadPos = 0;
  8086.         nType = nTypeIn;
  8087.         nVersion = nVersionIn;
  8088.         state = 0;
  8089.         exceptmask = ios::badbit | ios::failbit;
  8090.     }
  8091.     CDataStream& operator+=(const CDataStream& b)
  8092.     {
  8093.         vch.insert(vch.end(), b.begin(), b.end());
  8094.         return *this;
  8095.     }
  8096.     friend CDataStream operator+(const CDataStream& a, const CDataStream& b)
  8097.     {
  8098.         CDataStream ret = a;
  8099.         ret += b;
  8100.         return (ret);
  8101.     }
  8102.     string str() const
  8103.     {
  8104.         return (string(begin(), end()));
  8105.     }
  8106.     const_iterator begin() const                     { return vch.begin() + nReadPos; }
  8107.     iterator begin()                                 { return vch.begin() + nReadPos; }
  8108.     const_iterator end() const                       { return vch.end(); }
  8109.     iterator end()                                   { return vch.end(); }
  8110.     size_type size() const                           { return vch.size() - nReadPos; }
  8111.     bool empty() const                               { return vch.size() == nReadPos; }
  8112.     void resize(size_type n, value_type c=0)         { vch.resize(n + nReadPos, c); }
  8113.     void reserve(size_type n)                        { vch.reserve(n + nReadPos); }
  8114.     const_reference operator[](size_type pos) const  { return vch[pos + nReadPos]; }
  8115.     reference operator[](size_type pos)              { return vch[pos + nReadPos]; }
  8116.     void clear()                                     { vch.clear(); nReadPos = 0; }
  8117.     iterator insert(iterator it, const char& x=char()) { return vch.insert(it, x); }
  8118.     void insert(iterator it, size_type n, const char& x) { vch.insert(it, n, x); }
  8119.     void insert(iterator it, const_iterator first, const_iterator last)
  8120.     {
  8121.         if (it == vch.begin() + nReadPos && last - first <= nReadPos)
  8122.         {
  8123.             nReadPos -= (last - first);
  8124.             memcpy(&vch[nReadPos], &first[0], last - first);
  8125.         }
  8126.         else
  8127.             vch.insert(it, first, last);
  8128.     }
  8129. #if !defined(_MSC_VER) || _MSC_VER >= 1300
  8130.     void insert(iterator it, const char* first, const char* last)
  8131.     {
  8132.         insert(it, (const_iterator)first, (const_iterator)last);
  8133.     }
  8134. #endif
  8135.     iterator erase(iterator it)
  8136.     {
  8137.         if (it == vch.begin() + nReadPos)
  8138.         {
  8139.             if (++nReadPos >= vch.size())
  8140.             {
  8141.                 nReadPos = 0;
  8142.                 return vch.erase(vch.begin(), vch.end());
  8143.             }
  8144.             return vch.begin() + nReadPos;
  8145.         }
  8146.         else
  8147.             return vch.erase(it);
  8148.     }
  8149.     iterator erase(iterator first, iterator last)
  8150.     {
  8151.         if (first == vch.begin() + nReadPos)
  8152.         {
  8153.             if (last == vch.end())
  8154.             {
  8155.                 nReadPos = 0;
  8156.                 return vch.erase(vch.begin(), vch.end());
  8157.             }
  8158.             else
  8159.             {
  8160.                 nReadPos = (last - vch.begin());
  8161.                 return last;
  8162.             }
  8163.         }
  8164.         else
  8165.             return vch.erase(first, last);
  8166.     }
  8167.     inline void Compact()
  8168.     {
  8169.         vch.erase(vch.begin(), vch.begin() + nReadPos);
  8170.         nReadPos = 0;
  8171.     }
  8172.     bool Rewind(size_type n)
  8173.     {
  8174.         if (n > nReadPos)
  8175.             return false;
  8176.         nReadPos -= n;
  8177.         return true;
  8178.     }
  8179.     void setstate(short bits, const char* psz)
  8180.     {
  8181.         state |= bits;
  8182.         if (state & exceptmask)
  8183.             throw std::ios_base::failure(psz);
  8184.     }
  8185.     bool eof() const             { return size() == 0; }
  8186.     bool fail() const            { return state & (ios::badbit | ios::failbit); }
  8187.     bool good() const            { return !eof() && (state == 0); }
  8188.     void clear(short n)          { state = n; }
  8189.     short exceptions()           { return exceptmask; }
  8190.     short exceptions(short mask) { short prev = exceptmask; exceptmask = mask; setstate(0, "CDataStream"); return prev; }
  8191.     CDataStream* rdbuf()         { return this; }
  8192.     int in_avail()               { return size(); }
  8193.     void SetType(int n)          { nType = n; }
  8194.     int GetType()                { return nType; }
  8195.     void SetVersion(int n)       { nVersion = n; }
  8196.     int GetVersion()             { return nVersion; }
  8197.     void ReadVersion()           { *this >> nVersion; }
  8198.     void WriteVersion()          { *this << nVersion; }
  8199.     CDataStream& read(char* pch, int nSize)
  8200.     {
  8201.         assert(nSize >= 0);
  8202.         unsigned int nReadPosNext = nReadPos + nSize;
  8203.         if (nReadPosNext >= vch.size())
  8204.         {
  8205.             if (nReadPosNext > vch.size())
  8206.             {
  8207.                 setstate(ios::failbit, "CDataStream::read() : end of data");
  8208.                 memset(pch, 0, nSize);
  8209.                 nSize = vch.size() - nReadPos;
  8210.             }
  8211.             memcpy(pch, &vch[nReadPos], nSize);
  8212.             nReadPos = 0;
  8213.             vch.clear();
  8214.             return (*this);
  8215.         }
  8216.         memcpy(pch, &vch[nReadPos], nSize);
  8217.         nReadPos = nReadPosNext;
  8218.         return (*this);
  8219.     }
  8220.     CDataStream& ignore(int nSize)
  8221.     {
  8222.         assert(nSize >= 0);
  8223.         unsigned int nReadPosNext = nReadPos + nSize;
  8224.         if (nReadPosNext >= vch.size())
  8225.         {
  8226.             if (nReadPosNext > vch.size())
  8227.             {
  8228.                 setstate(ios::failbit, "CDataStream::ignore() : end of data");
  8229.                 nSize = vch.size() - nReadPos;
  8230.             }
  8231.             nReadPos = 0;
  8232.             vch.clear();
  8233.             return (*this);
  8234.         }
  8235.         nReadPos = nReadPosNext;
  8236.         return (*this);
  8237.     }
  8238.     CDataStream& write(const char* pch, int nSize)
  8239.     {
  8240.         assert(nSize >= 0);
  8241.         vch.insert(vch.end(), pch, pch + nSize);
  8242.         return (*this);
  8243.     }
  8244.     template<typename Stream>
  8245.     void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const
  8246.     {
  8247.         if (!vch.empty())
  8248.             s.write((char*)&vch[0], vch.size() * sizeof(vch[0]));
  8249.     }
  8250.     template<typename T>
  8251.     unsigned int GetSerializeSize(const T& obj)
  8252.     {
  8253.         return ::GetSerializeSize(obj, nType, nVersion);
  8254.     }
  8255.     template<typename T>
  8256.     CDataStream& operator<<(const T& obj)
  8257.     {
  8258.         ::Serialize(*this, obj, nType, nVersion);
  8259.         return (*this);
  8260.     }
  8261.     template<typename T>
  8262.     CDataStream& operator>>(T& obj)
  8263.     {
  8264.         ::Unserialize(*this, obj, nType, nVersion);
  8265.         return (*this);
  8266.     }
  8267. };
  8268. #ifdef TESTCDATASTREAM
  8269. #include <iostream>
  8270. int main(int argc, char *argv[])
  8271. {
  8272.     vector<unsigned char> vch(0xcc, 250);
  8273.     printf("CDataStream:\n");
  8274.     for (int n = 1000; n <= 4500000; n *= 2)
  8275.     {
  8276.         CDataStream ss;
  8277.         time_t nStart = time(NULL);
  8278.         for (int i = 0; i < n; i++)
  8279.             ss.write((char*)&vch[0], vch.size());
  8280.         printf("n=%-10d %d seconds\n", n, time(NULL) - nStart);
  8281.     }
  8282.     printf("stringstream:\n");
  8283.     for (int n = 1000; n <= 4500000; n *= 2)
  8284.     {
  8285.         stringstream ss;
  8286.         time_t nStart = time(NULL);
  8287.         for (int i = 0; i < n; i++)
  8288.             ss.write((char*)&vch[0], vch.size());
  8289.         printf("n=%-10d %d seconds\n", n, time(NULL) - nStart);
  8290.     }
  8291. }
  8292. #endif
  8293. class CAutoFile
  8294. {
  8295. protected:
  8296.     FILE* file;
  8297.     short state;
  8298.     short exceptmask;
  8299. public:
  8300.     int nType;
  8301.     int nVersion;
  8302.     typedef FILE element_type;
  8303.     CAutoFile(FILE* filenew=NULL, int nTypeIn=SER_DISK, int nVersionIn=VERSION)
  8304.     {
  8305.         file = filenew;
  8306.         nType = nTypeIn;
  8307.         nVersion = nVersionIn;
  8308.         state = 0;
  8309.         exceptmask = ios::badbit | ios::failbit;
  8310.     }
  8311.     ~CAutoFile()
  8312.     {
  8313.         fclose();
  8314.     }
  8315.     void fclose()
  8316.     {
  8317.         if (file != NULL && file != stdin && file != stdout && file != stderr)
  8318.             ::fclose(file);
  8319.         file = NULL;
  8320.     }
  8321.     FILE* release()             { FILE* ret = file; file = NULL; return ret; }
  8322.     operator FILE*()            { return file; }
  8323.     FILE* operator->()          { return file; }
  8324.     FILE& operator*()           { return *file; }
  8325.     FILE** operator&()          { return &file; }
  8326.     FILE* operator=(FILE* pnew) { return file = pnew; }
  8327.     bool operator!()            { return (file == NULL); }
  8328.     void setstate(short bits, const char* psz)
  8329.     {
  8330.         state |= bits;
  8331.         if (state & exceptmask)
  8332.             throw std::ios_base::failure(psz);
  8333.     }
  8334.     bool fail() const            { return state & (ios::badbit | ios::failbit); }
  8335.     bool good() const            { return state == 0; }
  8336.     void clear(short n = 0)      { state = n; }
  8337.     short exceptions()           { return exceptmask; }
  8338.     short exceptions(short mask) { short prev = exceptmask; exceptmask = mask; setstate(0, "CAutoFile"); return prev; }
  8339.     void SetType(int n)          { nType = n; }
  8340.     int GetType()                { return nType; }
  8341.     void SetVersion(int n)       { nVersion = n; }
  8342.     int GetVersion()             { return nVersion; }
  8343.     void ReadVersion()           { *this >> nVersion; }
  8344.     void WriteVersion()          { *this << nVersion; }
  8345.     CAutoFile& read(char* pch, int nSize)
  8346.     {
  8347.         if (!file)
  8348.             throw std::ios_base::failure("CAutoFile::read : file handle is NULL");
  8349.         if (fread(pch, 1, nSize, file) != nSize)
  8350.             setstate(ios::failbit, feof(file) ? "CAutoFile::read : end of file" : "CAutoFile::read : fread failed");
  8351.         return (*this);
  8352.     }
  8353.     CAutoFile& write(const char* pch, int nSize)
  8354.     {
  8355.         if (!file)
  8356.             throw std::ios_base::failure("CAutoFile::write : file handle is NULL");
  8357.         if (fwrite(pch, 1, nSize, file) != nSize)
  8358.             setstate(ios::failbit, "CAutoFile::write : write failed");
  8359.         return (*this);
  8360.     }
  8361.     template<typename T>
  8362.     unsigned int GetSerializeSize(const T& obj)
  8363.     {
  8364.         return ::GetSerializeSize(obj, nType, nVersion);
  8365.     }
  8366.     template<typename T>
  8367.     CAutoFile& operator<<(const T& obj)
  8368.     {
  8369.         if (!file)
  8370.             throw std::ios_base::failure("CAutoFile::operator<< : file handle is NULL");
  8371.         ::Serialize(*this, obj, nType, nVersion);
  8372.         return (*this);
  8373.     }
  8374.     template<typename T>
  8375.     CAutoFile& operator>>(T& obj)
  8376.     {
  8377.         if (!file)
  8378.             throw std::ios_base::failure("CAutoFile::operator>> : file handle is NULL");
  8379.         ::Unserialize(*this, obj, nType, nVersion);
  8380.         return (*this);
  8381.     }
  8382. };
  8383. #include "headers.h"
  8384. #ifdef _MSC_VER
  8385. #include <crtdbg.h>
  8386. #endif
  8387. DEFINE_EVENT_TYPE(wxEVT_CROSSTHREADCALL)
  8388. DEFINE_EVENT_TYPE(wxEVT_REPLY1)
  8389. DEFINE_EVENT_TYPE(wxEVT_REPLY2)
  8390. DEFINE_EVENT_TYPE(wxEVT_REPLY3)
  8391. DEFINE_EVENT_TYPE(wxEVT_TABLEADDED)
  8392. DEFINE_EVENT_TYPE(wxEVT_TABLEUPDATED)
  8393. DEFINE_EVENT_TYPE(wxEVT_TABLEDELETED)
  8394. CMainFrame* pframeMain = NULL;
  8395. map<string, string> mapAddressBook;
  8396. void ThreadRequestProductDetails(void* parg);
  8397. void ThreadRandSendTest(void* parg);
  8398. bool fRandSendTest = false;
  8399. void RandSend();
  8400. void HandleCtrlA(wxKeyEvent& event)
  8401. {
  8402.     wxTextCtrl* textCtrl = (wxTextCtrl*)event.GetEventObject();
  8403.     if (event.GetModifiers() == wxMOD_CONTROL && event.GetKeyCode() == 'A')
  8404.         textCtrl->SetSelection(-1, -1);
  8405.     event.Skip();
  8406. }
  8407. bool Is24HourTime()
  8408. {
  8409.     return true;
  8410. }
  8411. string DateStr(int64 nTime)
  8412. {
  8413.     return (string)wxDateTime((time_t)nTime).FormatDate();
  8414. }
  8415. string DateTimeStr(int64 nTime)
  8416. {
  8417.     wxDateTime datetime((time_t)nTime);
  8418.     if (Is24HourTime())
  8419.         return (string)datetime.Format("%x %H:%M");
  8420.     else
  8421.         return (string)datetime.Format("%x ") + itostr((datetime.GetHour() + 11) % 12 + 1) + (string)datetime.Format(":%M %p");
  8422. }
  8423. wxString GetItemText(wxListCtrl* listCtrl, int nIndex, int nColumn)
  8424. {
  8425.     wxListItem item;
  8426.     item.m_itemId = nIndex;
  8427.     item.m_col = nColumn;
  8428.     item.m_mask = wxLIST_MASK_TEXT;
  8429.     if (!listCtrl->GetItem(item))
  8430.         return "";
  8431.     return item.GetText();
  8432. }
  8433. int InsertLine(wxListCtrl* listCtrl, const wxString& str0, const wxString& str1)
  8434. {
  8435.     int nIndex = listCtrl->InsertItem(listCtrl->GetItemCount(), str0);
  8436.     listCtrl->SetItem(nIndex, 1, str1);
  8437.     return nIndex;
  8438. }
  8439. int InsertLine(wxListCtrl* listCtrl, const wxString& str0, const wxString& str1, const wxString& str2, const wxString& str3, const wxString& str4)
  8440. {
  8441.     int nIndex = listCtrl->InsertItem(listCtrl->GetItemCount(), str0);
  8442.     listCtrl->SetItem(nIndex, 1, str1);
  8443.     listCtrl->SetItem(nIndex, 2, str2);
  8444.     listCtrl->SetItem(nIndex, 3, str3);
  8445.     listCtrl->SetItem(nIndex, 4, str4);
  8446.     return nIndex;
  8447. }
  8448. int InsertLine(wxListCtrl* listCtrl, void* pdata, const wxString& str0, const wxString& str1, const wxString& str2, const wxString& str3, const wxString& str4)
  8449. {
  8450.     int nIndex = listCtrl->InsertItem(listCtrl->GetItemCount(), str0);
  8451.     listCtrl->SetItemPtrData(nIndex, (wxUIntPtr)pdata);
  8452.     listCtrl->SetItem(nIndex, 1, str1);
  8453.     listCtrl->SetItem(nIndex, 2, str2);
  8454.     listCtrl->SetItem(nIndex, 3, str3);
  8455.     listCtrl->SetItem(nIndex, 4, str4);
  8456.     return nIndex;
  8457. }
  8458. void SetSelection(wxListCtrl* listCtrl, int nIndex)
  8459. {
  8460.     int nSize = listCtrl->GetItemCount();
  8461.     long nState = (wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED);
  8462.     for (int i = 0; i < nSize; i++)
  8463.         listCtrl->SetItemState(i, (i == nIndex ? nState : 0), nState);
  8464. }
  8465. int GetSelection(wxListCtrl* listCtrl)
  8466. {
  8467.     int nSize = listCtrl->GetItemCount();
  8468.     for (int i = 0; i < nSize; i++)
  8469.         if (listCtrl->GetItemState(i, wxLIST_STATE_FOCUSED))
  8470.             return i;
  8471.     return -1;
  8472. }
  8473. string HtmlEscape(const char* psz, bool fMultiLine=false)
  8474. {
  8475.     int len = 0;
  8476.     for (const char* p = psz; *p; p++)
  8477.     {
  8478.         if (*p == '<') len += 4;
  8479.         else if (*p == '>') len += 4;
  8480.         else if (*p == '&') len += 5;
  8481.         else if (*p == '"') len += 6;
  8482.         else if (*p == ' ' && p > psz && p[-1] == ' ' && p[1] == ' ') len += 6;
  8483.         else if (*p == '\n' && fMultiLine) len += 5;
  8484.         else
  8485.             len++;
  8486.     }
  8487.     string str;
  8488.     str.reserve(len);
  8489.     for (const char* p = psz; *p; p++)
  8490.     {
  8491.              if (*p == '<') str += "&lt;";
  8492.         else if (*p == '>') str += "&gt;";
  8493.         else if (*p == '&') str += "&amp;";
  8494.         else if (*p == '"') str += "&quot;";
  8495.         else if (*p == ' ' && p > psz && p[-1] == ' ' && p[1] == ' ') str += "&nbsp;";
  8496.         else if (*p == '\n' && fMultiLine) str += "<br>\n";
  8497.         else
  8498.             str += *p;
  8499.     }
  8500.     return str;
  8501. }
  8502. string HtmlEscape(const string& str, bool fMultiLine=false)
  8503. {
  8504.     return HtmlEscape(str.c_str(), fMultiLine);
  8505. }
  8506. void AddToMyProducts(CProduct product)
  8507. {
  8508.     CProduct& productInsert = mapMyProducts[product.GetHash()];
  8509.     productInsert = product;
  8510.     InsertLine(pframeMain->m_listCtrlProductsSent, &productInsert,
  8511.                 product.mapValue["category"],
  8512.                 product.mapValue["title"].substr(0, 100),
  8513.                 product.mapValue["description"].substr(0, 100),
  8514.                 product.mapValue["price"],
  8515.                 "");
  8516. }
  8517. set<void*> setCallbackAvailable;
  8518. CCriticalSection cs_setCallbackAvailable;
  8519. void AddCallbackAvailable(void* p)
  8520. {
  8521.     CRITICAL_BLOCK(cs_setCallbackAvailable)
  8522.         setCallbackAvailable.insert(p);
  8523. }
  8524. void RemoveCallbackAvailable(void* p)
  8525. {
  8526.     CRITICAL_BLOCK(cs_setCallbackAvailable)
  8527.         setCallbackAvailable.erase(p);
  8528. }
  8529. bool IsCallbackAvailable(void* p)
  8530. {
  8531.     CRITICAL_BLOCK(cs_setCallbackAvailable)
  8532.         return setCallbackAvailable.count(p);
  8533.     return false;
  8534. }
  8535. template<typename T>
  8536. void AddPendingCustomEvent(wxEvtHandler* pevthandler, int nEventID, const T pbeginIn, const T pendIn)
  8537. {
  8538.     if (!pevthandler)
  8539.         return;
  8540.     const char* pbegin = (pendIn != pbeginIn) ? &pbeginIn[0] : NULL;
  8541.     const char* pend = pbegin + (pendIn - pbeginIn) * sizeof(pbeginIn[0]);
  8542.     wxCommandEvent event(nEventID);
  8543.     wxString strData(wxChar(0), (pend - pbegin) / sizeof(wxChar) + 1);
  8544.     memcpy(&strData[0], pbegin, pend - pbegin);
  8545.     event.SetString(strData);
  8546.     event.SetInt(pend - pbegin);
  8547.     pevthandler->AddPendingEvent(event);
  8548. }
  8549. template<class T>
  8550. void AddPendingCustomEvent(wxEvtHandler* pevthandler, int nEventID, const T& obj)
  8551. {
  8552.     CDataStream ss;
  8553.     ss << obj;
  8554.     AddPendingCustomEvent(pevthandler, nEventID, ss.begin(), ss.end());
  8555. }
  8556. void AddPendingReplyEvent1(void* pevthandler, CDataStream& vRecv)
  8557. {
  8558.     if (IsCallbackAvailable(pevthandler))
  8559.         AddPendingCustomEvent((wxEvtHandler*)pevthandler, wxEVT_REPLY1, vRecv.begin(), vRecv.end());
  8560. }
  8561. void AddPendingReplyEvent2(void* pevthandler, CDataStream& vRecv)
  8562. {
  8563.     if (IsCallbackAvailable(pevthandler))
  8564.         AddPendingCustomEvent((wxEvtHandler*)pevthandler, wxEVT_REPLY2, vRecv.begin(), vRecv.end());
  8565. }
  8566. void AddPendingReplyEvent3(void* pevthandler, CDataStream& vRecv)
  8567. {
  8568.     if (IsCallbackAvailable(pevthandler))
  8569.         AddPendingCustomEvent((wxEvtHandler*)pevthandler, wxEVT_REPLY3, vRecv.begin(), vRecv.end());
  8570. }
  8571. CDataStream GetStreamFromEvent(const wxCommandEvent& event)
  8572. {
  8573.     wxString strData = event.GetString();
  8574.     return CDataStream(strData.begin(), strData.begin() + event.GetInt(), SER_NETWORK);
  8575. }
  8576. CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent)
  8577. {
  8578.     Connect(wxEVT_CROSSTHREADCALL, wxCommandEventHandler(CMainFrame::OnCrossThreadCall), NULL, this);
  8579.     fRefreshListCtrl = false;
  8580.     fRefreshListCtrlRunning = false;
  8581.     fOnSetFocusAddress = false;
  8582.     pindexBestLast = NULL;
  8583.     m_choiceFilter->SetSelection(0);
  8584.     m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + "  ");
  8585.     m_listCtrl->SetFocus();
  8586.     SetIcon(wxICON(bitcoin));
  8587.     m_menuOptions->Check(wxID_OPTIONSGENERATEBITCOINS, fGenerateBitcoins);
  8588.     m_toolBar->ClearTools();
  8589.     wxBitmap bmpSend(wxT("send20"), wxBITMAP_TYPE_RESOURCE);
  8590.     bmpSend.SetMask(new wxMask(wxBitmap(wxT("send20mask"), wxBITMAP_TYPE_RESOURCE)));
  8591.     m_toolBar->AddTool(wxID_BUTTONSEND, wxT("&Send Coins"), bmpSend, wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString);
  8592.     wxBitmap bmpAddressBook(wxT("addressbook20"), wxBITMAP_TYPE_RESOURCE);
  8593.     bmpAddressBook.SetMask(new wxMask(wxBitmap(wxT("addressbook20mask"), wxBITMAP_TYPE_RESOURCE)));
  8594.     m_toolBar->AddTool(wxID_BUTTONRECEIVE, wxT("&Address Book"), bmpAddressBook, wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString);
  8595.     m_toolBar->Realize();
  8596.     int nDateWidth = DateTimeStr(1229413914).size() * 6 + 8;
  8597.     m_listCtrl->InsertColumn(0, "",             wxLIST_FORMAT_LEFT,     0);
  8598.     m_listCtrl->InsertColumn(1, "",             wxLIST_FORMAT_LEFT,     0);
  8599.     m_listCtrl->InsertColumn(2, "Status",       wxLIST_FORMAT_LEFT,    90);
  8600.     m_listCtrl->InsertColumn(3, "Date",         wxLIST_FORMAT_LEFT,   nDateWidth);
  8601.     m_listCtrl->InsertColumn(4, "Description",  wxLIST_FORMAT_LEFT,   409 - nDateWidth);
  8602.     m_listCtrl->InsertColumn(5, "Debit",        wxLIST_FORMAT_RIGHT,   79);
  8603.     m_listCtrl->InsertColumn(6, "Credit",       wxLIST_FORMAT_RIGHT,   79);
  8604.     int pnWidths[3] = { -100, 81, 286 };
  8605.     m_statusBar->SetFieldsCount(3, pnWidths);
  8606.     vector<unsigned char> vchPubKey;
  8607.     if (CWalletDB("r").ReadDefaultKey(vchPubKey))
  8608.         m_textCtrlAddress->SetValue(PubKeyToAddress(vchPubKey));
  8609.     RefreshListCtrl();
  8610. }
  8611. CMainFrame::~CMainFrame()
  8612. {
  8613.     pframeMain = NULL;
  8614. }
  8615. void Shutdown(void* parg)
  8616. {
  8617.     static CCriticalSection cs_Shutdown;
  8618.     CRITICAL_BLOCK(cs_Shutdown)
  8619.     {
  8620.         fShutdown = true;
  8621.         nTransactionsUpdated++;
  8622.         DBFlush(false);
  8623.         StopNode();
  8624.         DBFlush(true);
  8625.         printf("Bitcoin exiting\n");
  8626.         exit(0);
  8627.     }
  8628. }
  8629. void CMainFrame::OnClose(wxCloseEvent& event)
  8630. {
  8631.     Destroy();
  8632.     _beginthread(Shutdown, 0, NULL);
  8633. }
  8634. void CMainFrame::OnMouseEvents(wxMouseEvent& event)
  8635. {
  8636.     RandAddSeed();
  8637.     RAND_add(&event.m_x, sizeof(event.m_x), 0.25);
  8638.     RAND_add(&event.m_y, sizeof(event.m_y), 0.25);
  8639. }
  8640. void CMainFrame::OnListColBeginDrag(wxListEvent& event)
  8641. {
  8642.      if (event.GetColumn() <= 1 && !fDebug)
  8643.         event.Veto();
  8644. }
  8645. 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)
  8646. {
  8647.     string str0 = strSort;
  8648.     long nData = *(long*)&hashKey;
  8649.     if (fNew)
  8650.     {
  8651.         nIndex = m_listCtrl->InsertItem(0, str0);
  8652.     }
  8653.     else
  8654.     {
  8655.         if (nIndex == -1)
  8656.         {
  8657.             while ((nIndex = m_listCtrl->FindItem(nIndex, nData)) != -1)
  8658.                 if (GetItemText(m_listCtrl, nIndex, 1) == hashKey.ToString())
  8659.                     break;
  8660.             if (nIndex == -1)
  8661.             {
  8662.                 printf("CMainFrame::InsertLine : Couldn't find item to be updated\n");
  8663.                 return;
  8664.             }
  8665.         }
  8666.         if (GetItemText(m_listCtrl, nIndex, 0) != str0)
  8667.         {
  8668.             m_listCtrl->DeleteItem(nIndex);
  8669.             nIndex = m_listCtrl->InsertItem(0, str0);
  8670.         }
  8671.     }
  8672.     m_listCtrl->SetItem(nIndex, 1, hashKey.ToString());
  8673.     m_listCtrl->SetItem(nIndex, 2, str2);
  8674.     m_listCtrl->SetItem(nIndex, 3, str3);
  8675.     m_listCtrl->SetItem(nIndex, 4, str4);
  8676.     m_listCtrl->SetItem(nIndex, 5, str5);
  8677.     m_listCtrl->SetItem(nIndex, 6, str6);
  8678.     m_listCtrl->SetItemData(nIndex, nData);
  8679. }
  8680. string FormatTxStatus(const CWalletTx& wtx)
  8681. {
  8682.     int nDepth = wtx.GetDepthInMainChain();
  8683.     if (!wtx.IsFinal())
  8684.         return strprintf("Open for %d blocks", nBestHeight - wtx.nLockTime);
  8685.     else if (nDepth < 6)
  8686.         return strprintf("%d/unconfirmed", nDepth);
  8687.     else
  8688.         return strprintf("%d blocks", nDepth);
  8689. }
  8690. void CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex)
  8691. {
  8692.     int64 nTime = wtx.nTimeDisplayed = wtx.GetTxTime();
  8693.     int64 nCredit = wtx.GetCredit();
  8694.     int64 nDebit = wtx.GetDebit();
  8695.     int64 nNet = nCredit - nDebit;
  8696.     uint256 hash = wtx.GetHash();
  8697.     string strStatus = FormatTxStatus(wtx);
  8698.     map<string, string> mapValue = wtx.mapValue;
  8699.     CBlockIndex* pindex = NULL;
  8700.     map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(wtx.hashBlock);
  8701.     if (mi != mapBlockIndex.end())
  8702.         pindex = (*mi).second;
  8703.     string strSort = strprintf("%010d-%01d-%010u",
  8704.         (pindex ? pindex->nHeight : INT_MAX),
  8705.         (wtx.IsCoinBase() ? 1 : 0),
  8706.         wtx.nTimeReceived);
  8707.     if (nNet > 0 || wtx.IsCoinBase())
  8708.     {
  8709.         string strDescription;
  8710.         if (wtx.IsCoinBase())
  8711.         {
  8712.             strDescription = "Generated";
  8713.             if (nCredit == 0)
  8714.             {
  8715.                 int64 nUnmatured = 0;
  8716.                 foreach(const CTxOut& txout, wtx.vout)
  8717.                     nUnmatured += txout.GetCredit();
  8718.                 if (wtx.IsInMainChain())
  8719.                     strDescription += strprintf(" (%s matures in %d blocks)", FormatMoney(nUnmatured).c_str(), wtx.GetBlocksToMaturity());
  8720.                 else
  8721.                     strDescription += " (not accepted)";
  8722.             }
  8723.         }
  8724.         else if (!mapValue["from"].empty() || !mapValue["message"].empty())
  8725.         {
  8726.             if (!mapValue["from"].empty())
  8727.                 strDescription += "From: " + mapValue["from"];
  8728.             if (!mapValue["message"].empty())
  8729.             {
  8730.                 if (!strDescription.empty())
  8731.                     strDescription += " - ";
  8732.                 strDescription += mapValue["message"];
  8733.             }
  8734.         }
  8735.         else
  8736.         {
  8737.             foreach(const CTxOut& txout, wtx.vout)
  8738.             {
  8739.                 if (txout.IsMine())
  8740.                 {
  8741.                     vector<unsigned char> vchPubKey;
  8742.                     if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey))
  8743.                     {
  8744.                         string strAddress = PubKeyToAddress(vchPubKey);
  8745.                         if (mapAddressBook.count(strAddress))
  8746.                         {
  8747.                             strDescription += "Received with: ";
  8748.                             if (!mapAddressBook[strAddress].empty())
  8749.                                 strDescription += mapAddressBook[strAddress] + " ";
  8750.                             strDescription += strAddress;
  8751.                         }
  8752.                     }
  8753.                     break;
  8754.                 }
  8755.             }
  8756.         }
  8757.         string strDescription2;
  8758.         foreach(int c, strDescription)
  8759.             if (c >= ' ')
  8760.                 strDescription2 += c;
  8761.         InsertLine(fNew, nIndex, hash, strSort,
  8762.                    strStatus,
  8763.                    nTime ? DateTimeStr(nTime) : "",
  8764.                    strDescription2,
  8765.                    "",
  8766.                    FormatMoney(nNet, true));
  8767.     }
  8768.     else
  8769.     {
  8770.         bool fAllFromMe = true;
  8771.         foreach(const CTxIn& txin, wtx.vin)
  8772.             fAllFromMe = fAllFromMe && txin.IsMine();
  8773.         bool fAllToMe = true;
  8774.         foreach(const CTxOut& txout, wtx.vout)
  8775.             fAllToMe = fAllToMe && txout.IsMine();
  8776.         if (fAllFromMe && fAllToMe)
  8777.         {
  8778.             int64 nValue = wtx.vout[0].nValue;
  8779.             InsertLine(fNew, nIndex, hash, strSort,
  8780.                        strStatus,
  8781.                        nTime ? DateTimeStr(nTime) : "",
  8782.                        "Payment to yourself",
  8783.                        FormatMoney(nNet - nValue, true),
  8784.                        FormatMoney(nValue, true));
  8785.         }
  8786.         else if (fAllFromMe)
  8787.         {
  8788.             int64 nTxFee = nDebit - wtx.GetValueOut();
  8789.             for (int nOut = 0; nOut < wtx.vout.size(); nOut++)
  8790.             {
  8791.                 const CTxOut& txout = wtx.vout[nOut];
  8792.                 if (txout.IsMine())
  8793.                     continue;
  8794.                 string strAddress;
  8795.                 if (!mapValue["to"].empty())
  8796.                 {
  8797.                     strAddress = mapValue["to"];
  8798.                 }
  8799.                 else
  8800.                 {                
  8801.                     uint160 hash160;
  8802.                     if (ExtractHash160(txout.scriptPubKey, hash160))
  8803.                         strAddress = Hash160ToAddress(hash160);
  8804.                 }
  8805.                 string strDescription = "To: ";
  8806.                 if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty())
  8807.                     strDescription += mapAddressBook[strAddress] + " ";
  8808.                 strDescription += strAddress;
  8809.                 if (!mapValue["message"].empty())
  8810.                 {
  8811.                     if (!strDescription.empty())
  8812.                         strDescription += " - ";
  8813.                     strDescription += mapValue["message"];
  8814.                 }
  8815.                 string strDescription2;
  8816.                 foreach(int c, strDescription)
  8817.                     if (c >= ' ')
  8818.                         strDescription2 += c;
  8819.                 int64 nValue = txout.nValue;
  8820.                 if (nOut == 0 && nTxFee > 0)
  8821.                     nValue += nTxFee;
  8822.                 InsertLine(fNew, nIndex, hash, strprintf("%s-%d", strSort.c_str(), nOut),
  8823.                            strStatus,
  8824.                            nTime ? DateTimeStr(nTime) : "",
  8825.                            strDescription2,
  8826.                            FormatMoney(-nValue, true),
  8827.                            "");
  8828.             }
  8829.         }
  8830.         else
  8831.         {
  8832.             bool fAllMine = true;
  8833.             foreach(const CTxOut& txout, wtx.vout)
  8834.                 fAllMine = fAllMine && txout.IsMine();
  8835.             foreach(const CTxIn& txin, wtx.vin)
  8836.                 fAllMine = fAllMine && txin.IsMine();
  8837.             InsertLine(fNew, nIndex, hash, strSort,
  8838.                        strStatus,
  8839.                        nTime ? DateTimeStr(nTime) : "",
  8840.                        "",
  8841.                        FormatMoney(nNet, true),
  8842.                        "");
  8843.         }
  8844.     }
  8845. }
  8846. void CMainFrame::RefreshStatus()
  8847. {
  8848.     static int nLastTop;
  8849.     int nTop = m_listCtrl->GetTopItem();
  8850.     if (nTop == nLastTop && pindexBestLast == pindexBest)
  8851.         return;
  8852.     TRY_CRITICAL_BLOCK(cs_mapWallet)
  8853.     {
  8854.         int nStart = nTop;
  8855.         int nEnd = min(nStart + 100, m_listCtrl->GetItemCount());
  8856.         if (pindexBestLast == pindexBest)
  8857.         {
  8858.             if (nStart >= nLastTop && nStart < nLastTop + 100)
  8859.                 nStart = nLastTop + 100;
  8860.             if (nEnd >= nLastTop && nEnd < nLastTop + 100)
  8861.                 nEnd = nLastTop;
  8862.         }
  8863.         nLastTop = nTop;
  8864.         pindexBestLast = pindexBest;
  8865.         for (int nIndex = nStart; nIndex < nEnd; nIndex++)
  8866.         {
  8867.             uint256 hash((string)GetItemText(m_listCtrl, nIndex, 1));
  8868.             map<uint256, CWalletTx>::iterator mi = mapWallet.find(hash);
  8869.             if (mi == mapWallet.end())
  8870.             {
  8871.                 printf("CMainFrame::RefreshStatus() : tx not found in mapWallet\n");
  8872.                 continue;
  8873.             }
  8874.             const CWalletTx& wtx = (*mi).second;
  8875.             if (wtx.IsCoinBase() || wtx.GetTxTime() != wtx.nTimeDisplayed)
  8876.                 InsertTransaction(wtx, false, nIndex);
  8877.             else
  8878.                 m_listCtrl->SetItem(nIndex, 2, FormatTxStatus(wtx));
  8879.         }
  8880.     }
  8881. }
  8882. void CMainFrame::RefreshListCtrl()
  8883. {
  8884.     fRefreshListCtrl = true;
  8885.     ::wxWakeUpIdle();
  8886. }
  8887. void CMainFrame::OnIdle(wxIdleEvent& event)
  8888. {
  8889.     if (fRefreshListCtrl)
  8890.     {
  8891.         bool fEntered = false;
  8892.         vector<pair<unsigned int, uint256> > vSorted;
  8893.         TRY_CRITICAL_BLOCK(cs_mapWallet)
  8894.         {
  8895.             printf("RefreshListCtrl starting\n");
  8896.             fEntered = true;
  8897.             fRefreshListCtrl = false;
  8898.             vWalletUpdated.clear();
  8899.             vSorted.reserve(mapWallet.size());
  8900.             for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
  8901.             {
  8902.                 const CWalletTx& wtx = (*it).second;
  8903.                 unsigned int nTime = UINT_MAX - wtx.GetTxTime();
  8904.                 vSorted.push_back(make_pair(nTime, (*it).first));
  8905.             }
  8906.             m_listCtrl->DeleteAllItems();
  8907.         }
  8908.         if (!fEntered)
  8909.             return;
  8910.         sort(vSorted.begin(), vSorted.end());
  8911.         for (int i = 0; i < vSorted.size();)
  8912.         {
  8913.             if (fShutdown)
  8914.                 return;
  8915.             bool fEntered = false;
  8916.             TRY_CRITICAL_BLOCK(cs_mapWallet)
  8917.             {
  8918.                 fEntered = true;
  8919.                 uint256& hash = vSorted[i++].second;
  8920.                 map<uint256, CWalletTx>::iterator mi = mapWallet.find(hash);
  8921.                 if (mi != mapWallet.end())
  8922.                     InsertTransaction((*mi).second, true);
  8923.             }
  8924.             if (!fEntered || i == 100 || i % 500 == 0)
  8925.                 wxYield();
  8926.         }
  8927.         printf("RefreshListCtrl done\n");
  8928.     }
  8929.     else
  8930.     {
  8931.         static int64 nLastTime;
  8932.         if (GetTime() > nLastTime + 30)
  8933.         {
  8934.             TRY_CRITICAL_BLOCK(cs_mapWallet)
  8935.             {
  8936.                 nLastTime = GetTime();
  8937.                 for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
  8938.                 {
  8939.                     CWalletTx& wtx = (*it).second;
  8940.                     if (wtx.nTimeDisplayed && wtx.nTimeDisplayed != wtx.GetTxTime())
  8941.                         InsertTransaction(wtx, false);
  8942.                 }
  8943.             }
  8944.         }
  8945.     }
  8946. }
  8947. void CMainFrame::OnPaint(wxPaintEvent& event)
  8948. {
  8949.     event.Skip();
  8950. }
  8951. void CMainFrame::OnPaintListCtrl(wxPaintEvent& event)
  8952. {
  8953.     if (!vWalletUpdated.empty())
  8954.     {
  8955.         TRY_CRITICAL_BLOCK(cs_mapWallet)
  8956.         {
  8957.             pair<uint256, bool> item;
  8958.             foreach(item, vWalletUpdated)
  8959.             {
  8960.                 bool fNew = item.second;
  8961.                 map<uint256, CWalletTx>::iterator mi = mapWallet.find(item.first);
  8962.                 if (mi != mapWallet.end())
  8963.                 {
  8964.                     printf("vWalletUpdated: %s %s\n", (*mi).second.GetHash().ToString().substr(0,6).c_str(), fNew ? "new" : "");
  8965.                     InsertTransaction((*mi).second, fNew);
  8966.                 }
  8967.             }
  8968.             m_listCtrl->ScrollList(0, INT_MAX);
  8969.             vWalletUpdated.clear();
  8970.         }
  8971.     }
  8972.     RefreshStatus();
  8973.     string strGen = "";
  8974.     if (fGenerateBitcoins)
  8975.         strGen = "    Generating";
  8976.     if (fGenerateBitcoins && vNodes.empty())
  8977.         strGen = "(not connected)";
  8978.     m_statusBar->SetStatusText(strGen, 1);
  8979.     string strStatus = strprintf("     %d connections     %d blocks     %d transactions", vNodes.size(), nBestHeight + 1, m_listCtrl->GetItemCount());
  8980.     m_statusBar->SetStatusText(strStatus, 2);
  8981.     TRY_CRITICAL_BLOCK(cs_mapWallet)
  8982.         m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + "  ");
  8983.     m_listCtrl->OnPaint(event);
  8984. }
  8985. void CrossThreadCall(wxCommandEvent& event)
  8986. {
  8987.     if (pframeMain)
  8988.         pframeMain->GetEventHandler()->AddPendingEvent(event);
  8989. }
  8990. void CrossThreadCall(int nID, void* pdata)
  8991. {
  8992.     wxCommandEvent event;
  8993.     event.SetInt(nID);
  8994.     event.SetClientData(pdata);
  8995.     if (pframeMain)
  8996.         pframeMain->GetEventHandler()->AddPendingEvent(event);
  8997. }
  8998. void CMainFrame::OnCrossThreadCall(wxCommandEvent& event)
  8999. {
  9000.     void* pdata = event.GetClientData();
  9001.     switch (event.GetInt())
  9002.     {
  9003.         case UICALL_ADDORDER:
  9004.         {
  9005.             break;
  9006.         }
  9007.         case UICALL_UPDATEORDER:
  9008.         {
  9009.             break;
  9010.         }
  9011.     }
  9012. }
  9013. void CMainFrame::OnMenuFileExit(wxCommandEvent& event)
  9014. {
  9015.     Close(true);
  9016. }
  9017. void CMainFrame::OnMenuOptionsGenerate(wxCommandEvent& event)
  9018. {
  9019.     fGenerateBitcoins = event.IsChecked();
  9020.     nTransactionsUpdated++;
  9021.     CWalletDB().WriteSetting("fGenerateBitcoins", fGenerateBitcoins);
  9022.     if (fGenerateBitcoins)
  9023.         if (_beginthread(ThreadBitcoinMiner, 0, NULL) == -1)
  9024.             printf("Error: _beginthread(ThreadBitcoinMiner) failed\n");
  9025.  
  9026.     Refresh();
  9027.     wxPaintEvent eventPaint;
  9028.     AddPendingEvent(eventPaint);
  9029. }
  9030. void CMainFrame::OnMenuOptionsOptions(wxCommandEvent& event)
  9031. {
  9032.     COptionsDialog dialog(this);
  9033.     dialog.ShowModal();
  9034. }
  9035. void CMainFrame::OnMenuHelpAbout(wxCommandEvent& event)
  9036. {
  9037.     CAboutDialog dialog(this);
  9038.     dialog.ShowModal();
  9039. }
  9040. void CMainFrame::OnButtonSend(wxCommandEvent& event)
  9041. {
  9042.     if (fRandSendTest)
  9043.     {
  9044.         RandSend();
  9045.         return;
  9046.     }
  9047.     CSendDialog dialog(this);
  9048.     dialog.ShowModal();
  9049. }
  9050. void CMainFrame::OnButtonAddressBook(wxCommandEvent& event)
  9051. {
  9052.     CAddressBookDialog dialogAddr(this, "", false);
  9053.     if (dialogAddr.ShowModal() == 2)
  9054.     {
  9055.         CSendDialog dialogSend(this, dialogAddr.GetAddress());
  9056.         dialogSend.ShowModal();
  9057.     }
  9058. }
  9059. void CMainFrame::OnSetFocusAddress(wxFocusEvent& event)
  9060. {
  9061.     m_textCtrlAddress->SetSelection(-1, -1);
  9062.     fOnSetFocusAddress = true;
  9063.     event.Skip();
  9064. }
  9065. void CMainFrame::OnMouseEventsAddress(wxMouseEvent& event)
  9066. {
  9067.     if (fOnSetFocusAddress)
  9068.         m_textCtrlAddress->SetSelection(-1, -1);
  9069.     fOnSetFocusAddress = false;
  9070.     event.Skip();
  9071. }
  9072. void CMainFrame::OnButtonCopy(wxCommandEvent& event)
  9073. {
  9074.     if (wxTheClipboard->Open())
  9075.     {
  9076.         wxTheClipboard->SetData(new wxTextDataObject(m_textCtrlAddress->GetValue()));
  9077.         wxTheClipboard->Close();
  9078.     }
  9079. }
  9080. void CMainFrame::OnButtonChange(wxCommandEvent& event)
  9081. {
  9082.     CYourAddressDialog dialog(this, string(m_textCtrlAddress->GetValue()));
  9083.     if (!dialog.ShowModal())
  9084.         return;
  9085.     string strAddress = (string)dialog.GetAddress();
  9086.     if (strAddress != m_textCtrlAddress->GetValue())
  9087.     {
  9088.         uint160 hash160;
  9089.         if (!AddressToHash160(strAddress, hash160))
  9090.             return;
  9091.         if (!mapPubKeys.count(hash160))
  9092.             return;
  9093.         CWalletDB().WriteDefaultKey(mapPubKeys[hash160]);
  9094.         m_textCtrlAddress->SetValue(strAddress);
  9095.     }
  9096. }
  9097. void CMainFrame::OnListItemActivatedAllTransactions(wxListEvent& event)
  9098. {
  9099.     uint256 hash((string)GetItemText(m_listCtrl, event.GetIndex(), 1));
  9100.     CWalletTx wtx;
  9101.     CRITICAL_BLOCK(cs_mapWallet)
  9102.     {
  9103.         map<uint256, CWalletTx>::iterator mi = mapWallet.find(hash);
  9104.         if (mi == mapWallet.end())
  9105.         {
  9106.             printf("CMainFrame::OnListItemActivatedAllTransactions() : tx not found in mapWallet\n");
  9107.             return;
  9108.         }
  9109.         wtx = (*mi).second;
  9110.     }
  9111.     CTxDetailsDialog dialog(this, wtx);
  9112.     dialog.ShowModal();
  9113. }
  9114. void CMainFrame::OnListItemActivatedProductsSent(wxListEvent& event)
  9115. {
  9116.     CProduct& product = *(CProduct*)event.GetItem().GetData();
  9117.     CEditProductDialog* pdialog = new CEditProductDialog(this);
  9118.     pdialog->SetProduct(product);
  9119.     pdialog->Show();
  9120. }
  9121. void CMainFrame::OnListItemActivatedOrdersSent(wxListEvent& event)
  9122. {
  9123.     CWalletTx& order = *(CWalletTx*)event.GetItem().GetData();
  9124.     CViewOrderDialog* pdialog = new CViewOrderDialog(this, order, false);
  9125.     pdialog->Show();
  9126. }
  9127. void CMainFrame::OnListItemActivatedOrdersReceived(wxListEvent& event)
  9128. {
  9129.     CWalletTx& order = *(CWalletTx*)event.GetItem().GetData();
  9130.     CViewOrderDialog* pdialog = new CViewOrderDialog(this, order, true);
  9131.     pdialog->Show();
  9132. }
  9133. CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetailsDialogBase(parent)
  9134. {
  9135.     string strHTML;
  9136.     strHTML.reserve(4000);
  9137.     int64 nTime = wtx.GetTxTime();
  9138.     int64 nCredit = wtx.GetCredit();
  9139.     int64 nDebit = wtx.GetDebit();
  9140.     int64 nNet = nCredit - nDebit;
  9141.     strHTML += "<b>Status:</b> " + FormatTxStatus(wtx) + "<br>";
  9142.     strHTML += "<b>Date:</b> " + (nTime ? DateTimeStr(nTime) : "") + "<br>";
  9143.     if (wtx.IsCoinBase())
  9144.     {
  9145.         strHTML += "<b>Source:</b> Generated<br>";
  9146.     }
  9147.     else if (!wtx.mapValue["from"].empty())
  9148.     {
  9149.         if (!wtx.mapValue["from"].empty())
  9150.             strHTML += "<b>From:</b> " + HtmlEscape(wtx.mapValue["from"]) + "<br>";
  9151.     }
  9152.     else
  9153.     {
  9154.         foreach(const CTxOut& txout, wtx.vout)
  9155.         {
  9156.             if (txout.IsMine())
  9157.             {
  9158.                 vector<unsigned char> vchPubKey;
  9159.                 if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey))
  9160.                 {
  9161.                     string strAddress = PubKeyToAddress(vchPubKey);
  9162.                     if (mapAddressBook.count(strAddress))
  9163.                     {
  9164.                         strHTML += "<b>Received with:</b> ";
  9165.                         if (!mapAddressBook[strAddress].empty())
  9166.                             strHTML += mapAddressBook[strAddress] + " ";
  9167.                         strHTML += HtmlEscape(strAddress);
  9168.                         strHTML += "<br>";
  9169.                     }
  9170.                 }
  9171.                 break;
  9172.             }
  9173.         }
  9174.     }
  9175.     string strAddress;
  9176.     if (!wtx.mapValue["to"].empty())
  9177.     {
  9178.         strAddress = wtx.mapValue["to"];
  9179.         strHTML += "<b>To:</b> ";
  9180.         if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty())
  9181.             strHTML += mapAddressBook[strAddress] + " ";
  9182.         strHTML += HtmlEscape(strAddress) + "<br>";
  9183.     }
  9184.     if (wtx.IsCoinBase() && nCredit == 0)
  9185.     {/
  9186.         int64 nUnmatured = 0;
  9187.         foreach(const CTxOut& txout, wtx.vout)
  9188.             nUnmatured += txout.GetCredit();
  9189.         if (wtx.IsInMainChain())
  9190.             strHTML += strprintf("<b>Credit:</b> (%s matures in %d blocks)<br>", FormatMoney(nUnmatured).c_str(), wtx.GetBlocksToMaturity());
  9191.         else
  9192.             strHTML += "<b>Credit:</b> (not accepted)<br>";
  9193.     }
  9194.     else if (nNet > 0)
  9195.     {
  9196.         strHTML += "<b>Credit:</b> " + FormatMoney(nNet) + "<br>";
  9197.     }
  9198.     else
  9199.     {
  9200.         bool fAllFromMe = true;
  9201.         foreach(const CTxIn& txin, wtx.vin)
  9202.             fAllFromMe = fAllFromMe && txin.IsMine();
  9203.         bool fAllToMe = true;
  9204.         foreach(const CTxOut& txout, wtx.vout)
  9205.             fAllToMe = fAllToMe && txout.IsMine();
  9206.         if (fAllFromMe)
  9207.         {
  9208.             foreach(const CTxOut& txout, wtx.vout)
  9209.             {
  9210.                 if (txout.IsMine())
  9211.                     continue;
  9212.                 string strAddress;
  9213.                 if (!wtx.mapValue["to"].empty())
  9214.                 {
  9215.                     strAddress = wtx.mapValue["to"];
  9216.                 }
  9217.                 else
  9218.                 {
  9219.                     uint160 hash160;
  9220.                     if (ExtractHash160(txout.scriptPubKey, hash160))
  9221.                         strAddress = Hash160ToAddress(hash160);
  9222.                 }
  9223.                 strHTML += "<b>Debit:</b> " + FormatMoney(-txout.nValue) + " &nbsp;&nbsp; ";
  9224.                 strHTML += "(to ";
  9225.                 if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty())
  9226.                     strHTML += mapAddressBook[strAddress] + " ";
  9227.                 strHTML += strAddress;
  9228.                 strHTML += ")<br>";
  9229.             }
  9230.             if (fAllToMe)
  9231.             {
  9232.                 int64 nValue = wtx.vout[0].nValue;
  9233.                 strHTML += "<b>Debit:</b> " + FormatMoney(-nValue) + "<br>";
  9234.                 strHTML += "<b>Credit:</b> " + FormatMoney(nValue) + "<br>";
  9235.             }
  9236.             int64 nTxFee = nDebit - wtx.GetValueOut();
  9237.             if (nTxFee > 0)
  9238.                 strHTML += "<b>Transaction fee:</b> " + FormatMoney(-nTxFee) + "<br>";
  9239.         }
  9240.         else
  9241.         {
  9242.             foreach(const CTxIn& txin, wtx.vin)
  9243.                 if (txin.IsMine())
  9244.                     strHTML += "<b>Debit:</b> " + FormatMoney(-txin.GetDebit()) + "<br>";
  9245.             foreach(const CTxOut& txout, wtx.vout)
  9246.                 if (txout.IsMine())
  9247.                     strHTML += "<b>Credit:</b> " + FormatMoney(txout.GetCredit()) + "<br>";
  9248.         }
  9249.     }
  9250.     strHTML += "<b>Net amount:</b> " + FormatMoney(nNet, true) + "<br>";
  9251.     if (!wtx.mapValue["message"].empty())
  9252.         strHTML += "<br><b>Message:</b><br>" + HtmlEscape(wtx.mapValue["message"], true) + "<br>";
  9253.     if (fDebug)
  9254.     {
  9255.         strHTML += "<hr><br>debug print<br><br>";
  9256.         foreach(const CTxIn& txin, wtx.vin)
  9257.             if (txin.IsMine())
  9258.                 strHTML += "<b>Debit:</b> " + FormatMoney(-txin.GetDebit()) + "<br>";
  9259.         foreach(const CTxOut& txout, wtx.vout)
  9260.             if (txout.IsMine())
  9261.                 strHTML += "<b>Credit:</b> " + FormatMoney(txout.GetCredit()) + "<br>";
  9262.         strHTML += "<b>Inputs:</b><br>";
  9263.         CRITICAL_BLOCK(cs_mapWallet)
  9264.         {
  9265.             foreach(const CTxIn& txin, wtx.vin)
  9266.             {
  9267.                 COutPoint prevout = txin.prevout;
  9268.                 map<uint256, CWalletTx>::iterator mi = mapWallet.find(prevout.hash);
  9269.                 if (mi != mapWallet.end())
  9270.                 {
  9271.                     const CWalletTx& prev = (*mi).second;
  9272.                     if (prevout.n < prev.vout.size())
  9273.                     {
  9274.                         strHTML += HtmlEscape(prev.ToString(), true);
  9275.                         strHTML += " &nbsp;&nbsp; " + FormatTxStatus(prev) + ", ";
  9276.                         strHTML = strHTML + "IsMine=" + (prev.vout[prevout.n].IsMine() ? "true" : "false") + "<br>";
  9277.                     }
  9278.                 }
  9279.             }
  9280.         }
  9281.         strHTML += "<br><hr><br><b>Transaction:</b><br>";
  9282.         strHTML += HtmlEscape(wtx.ToString(), true);
  9283.     }
  9284.     string(strHTML.begin(), strHTML.end()).swap(strHTML);
  9285.     m_htmlWin->SetPage(strHTML);
  9286.     m_buttonOK->SetFocus();
  9287. }
  9288. void CTxDetailsDialog::OnButtonOK(wxCommandEvent& event)
  9289. {
  9290.     Close();
  9291. }
  9292. COptionsDialog::COptionsDialog(wxWindow* parent) : COptionsDialogBase(parent)
  9293. {
  9294.     m_textCtrlTransactionFee->SetValue(FormatMoney(nTransactionFee));
  9295.     m_buttonOK->SetFocus();
  9296. }
  9297. void COptionsDialog::OnKillFocusTransactionFee(wxFocusEvent& event)
  9298. {
  9299.     int64 nTmp = nTransactionFee;
  9300.     ParseMoney(m_textCtrlTransactionFee->GetValue(), nTmp);
  9301.     m_textCtrlTransactionFee->SetValue(FormatMoney(nTmp));
  9302. }
  9303. void COptionsDialog::OnButtonOK(wxCommandEvent& event)
  9304. {
  9305.     int64 nPrevTransactionFee = nTransactionFee;
  9306.     if (ParseMoney(m_textCtrlTransactionFee->GetValue(), nTransactionFee) && nTransactionFee != nPrevTransactionFee)
  9307.         CWalletDB().WriteSetting("nTransactionFee", nTransactionFee);
  9308.     Close();
  9309. }
  9310. void COptionsDialog::OnButtonCancel(wxCommandEvent& event)
  9311. {
  9312.     Close();
  9313. }
  9314. CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent)
  9315. {
  9316.     m_staticTextVersion->SetLabel(strprintf("version 0.%d.%d Alpha", VERSION/100, VERSION%100));
  9317.     wxString str = m_staticTextMain->GetLabel();
  9318.     if (str.Find('Â') != wxNOT_FOUND)
  9319.         str.Remove(str.Find('Â'), 1);
  9320.     m_staticTextMain->SetLabel(str);
  9321. }
  9322. void CAboutDialog::OnButtonOK(wxCommandEvent& event)
  9323. {
  9324.     Close();
  9325. }
  9326. CSendDialog::CSendDialog(wxWindow* parent, const wxString& strAddress) : CSendDialogBase(parent)
  9327. {
  9328.     m_textCtrlAddress->SetValue(strAddress);
  9329.     m_choiceTransferType->SetSelection(0);
  9330.     m_bitmapCheckMark->Show(false);
  9331.     wxBitmap bmpSend(wxT("send16"), wxBITMAP_TYPE_RESOURCE);
  9332.     bmpSend.SetMask(new wxMask(wxBitmap(wxT("send16masknoshadow"), wxBITMAP_TYPE_RESOURCE)));
  9333.     wxIcon iconSend;
  9334.     iconSend.CopyFromBitmap(bmpSend);
  9335.     SetIcon(iconSend);
  9336.     wxCommandEvent event;
  9337.     OnTextAddress(event);
  9338.     m_buttonPaste->MoveAfterInTabOrder(m_buttonCancel);
  9339.     m_buttonAddress->MoveAfterInTabOrder(m_buttonPaste);
  9340.     this->Layout();
  9341. }
  9342. void CSendDialog::OnTextAddress(wxCommandEvent& event)
  9343. {
  9344.     bool fBitcoinAddress = IsValidBitcoinAddress(m_textCtrlAddress->GetValue());
  9345.     m_bitmapCheckMark->Show(fBitcoinAddress);
  9346.     bool fEnable = !fBitcoinAddress;
  9347.     m_staticTextFrom->Enable(fEnable);
  9348.     m_textCtrlFrom->Enable(fEnable);
  9349.     m_staticTextMessage->Enable(fEnable);
  9350.     m_textCtrlMessage->Enable(fEnable);
  9351.     m_textCtrlMessage->SetBackgroundColour(wxSystemSettings::GetColour(fEnable ? wxSYS_COLOUR_WINDOW : wxSYS_COLOUR_BTNFACE));
  9352. }
  9353. void CSendDialog::OnKillFocusAmount(wxFocusEvent& event)
  9354. {
  9355.     if (m_textCtrlAmount->GetValue().Trim().empty())
  9356.         return;
  9357.     int64 nTmp;
  9358.     if (ParseMoney(m_textCtrlAmount->GetValue(), nTmp))
  9359.         m_textCtrlAmount->SetValue(FormatMoney(nTmp));
  9360. }
  9361. void CSendDialog::OnButtonAddressBook(wxCommandEvent& event)
  9362. {
  9363.     CAddressBookDialog dialog(this, m_textCtrlAddress->GetValue(), true);
  9364.     if (dialog.ShowModal())
  9365.         m_textCtrlAddress->SetValue(dialog.GetAddress());
  9366. }
  9367. void CSendDialog::OnButtonPaste(wxCommandEvent& event)
  9368. {
  9369.     if (wxTheClipboard->Open())
  9370.     {
  9371.         if (wxTheClipboard->IsSupported(wxDF_TEXT))
  9372.         {
  9373.             wxTextDataObject data;
  9374.             wxTheClipboard->GetData(data);
  9375.             m_textCtrlAddress->SetValue(data.GetText());
  9376.         }
  9377.         wxTheClipboard->Close();
  9378.     }
  9379. }
  9380. void CSendDialog::OnButtonSend(wxCommandEvent& event)
  9381. {
  9382.     CWalletTx wtx;
  9383.     string strAddress = (string)m_textCtrlAddress->GetValue();
  9384.     int64 nValue = 0;
  9385.     if (!ParseMoney(m_textCtrlAmount->GetValue(), nValue) || nValue <= 0)
  9386.     {
  9387.         wxMessageBox("Error in amount ");
  9388.         return;
  9389.     }
  9390.     if (nValue > GetBalance())
  9391.     {
  9392.         wxMessageBox("Amount exceeds your balance ");
  9393.         return;
  9394.     }
  9395.     if (nValue + nTransactionFee > GetBalance())
  9396.     {
  9397.         wxMessageBox(string("Total exceeds your balance when the ") + FormatMoney(nTransactionFee) + " transaction fee is included ");
  9398.         return;
  9399.     }
  9400.     uint160 hash160;
  9401.     bool fBitcoinAddress = AddressToHash160(strAddress, hash160);
  9402.     if (fBitcoinAddress)
  9403.     {
  9404.         CScript scriptPubKey;
  9405.         scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG;
  9406.         if (!SendMoney(scriptPubKey, nValue, wtx))
  9407.             return;
  9408.         wxMessageBox("Payment sent ", "Sending...");
  9409.     }
  9410.     else
  9411.     {
  9412.         CAddress addr(strAddress.c_str());
  9413.         if (addr.ip == 0)
  9414.         {
  9415.             wxMessageBox("Invalid address ");
  9416.             return;
  9417.         }
  9418.         wtx.mapValue["to"] = strAddress;
  9419.         wtx.mapValue["from"] = m_textCtrlFrom->GetValue();
  9420.         wtx.mapValue["message"] = m_textCtrlMessage->GetValue();
  9421.         CSendingDialog* pdialog = new CSendingDialog(this, addr, nValue, wtx);
  9422.         if (!pdialog->ShowModal())
  9423.             return;
  9424.     }
  9425.     if (!mapAddressBook.count(strAddress))
  9426.         SetAddressBookName(strAddress, "");
  9427.     EndModal(true);
  9428. }
  9429. void CSendDialog::OnButtonCancel(wxCommandEvent& event)
  9430. {
  9431.     EndModal(false);
  9432. }
  9433. CSendingDialog::CSendingDialog(wxWindow* parent, const CAddress& addrIn, int64 nPriceIn, const CWalletTx& wtxIn) : CSendingDialogBase(NULL)
  9434. {
  9435.     addr = addrIn;
  9436.     nPrice = nPriceIn;
  9437.     wtx = wtxIn;
  9438.     start = wxDateTime::UNow();
  9439.     strStatus = "";
  9440.     fCanCancel = true;
  9441.     fAbort = false;
  9442.     fSuccess = false;
  9443.     fUIDone = false;
  9444.     fWorkDone = false;
  9445.     SetTitle(strprintf("Sending %s to %s...", FormatMoney(nPrice).c_str(), wtx.mapValue["to"].c_str()));
  9446.     m_textCtrlStatus->SetValue("");
  9447.     _beginthread(SendingDialogStartTransfer, 0, this);
  9448. }
  9449. CSendingDialog::~CSendingDialog()
  9450. {
  9451.     printf("~CSendingDialog()\n");
  9452. }
  9453. void CSendingDialog::Close()
  9454. {
  9455.     if (IsModal())
  9456.         EndModal(fSuccess);
  9457.     else
  9458.         Show(false);
  9459.     if (fWorkDone)
  9460.         Destroy();
  9461.     else
  9462.         fUIDone = true;
  9463. }
  9464. void CSendingDialog::OnClose(wxCloseEvent& event)
  9465. {
  9466.     if (!event.CanVeto() || fWorkDone || fAbort || !fCanCancel)
  9467.     {
  9468.         Close();
  9469.     }
  9470.     else
  9471.     {
  9472.         event.Veto();
  9473.         wxCommandEvent cmdevent;
  9474.         OnButtonCancel(cmdevent);
  9475.     }
  9476. }
  9477. void CSendingDialog::OnButtonOK(wxCommandEvent& event)
  9478. {
  9479.     if (fWorkDone)
  9480.         Close();
  9481. }
  9482. void CSendingDialog::OnButtonCancel(wxCommandEvent& event)
  9483. {
  9484.     if (fCanCancel)
  9485.         fAbort = true;
  9486. }
  9487. void CSendingDialog::OnPaint(wxPaintEvent& event)
  9488. {
  9489.     if (strStatus.size() > 130)
  9490.         m_textCtrlStatus->SetValue(string("\n") + strStatus);
  9491.     else
  9492.         m_textCtrlStatus->SetValue(string("\n\n") + strStatus);
  9493.     m_staticTextSending->SetFocus();
  9494.     if (!fCanCancel)
  9495.         m_buttonCancel->Enable(false);
  9496.     if (fWorkDone)
  9497.     {
  9498.         m_buttonOK->Enable(true);
  9499.         m_buttonOK->SetFocus();
  9500.         m_buttonCancel->Enable(false);
  9501.     }
  9502.     if (fAbort && fCanCancel && IsShown())
  9503.     {
  9504.         strStatus = "CANCELLED";
  9505.         m_buttonOK->Enable(true);
  9506.         m_buttonOK->SetFocus();
  9507.         m_buttonCancel->Enable(false);
  9508.         m_buttonCancel->SetLabel("Cancelled");
  9509.         Close();
  9510.         wxMessageBox("Transfer cancelled ", "Sending...", wxOK, this);
  9511.     }
  9512.     event.Skip();
  9513.     if (fRandSendTest && fWorkDone && fSuccess)
  9514.     {
  9515.         Close();
  9516.         Sleep(1000);
  9517.         RandSend();
  9518.     }
  9519. }
  9520. void CSendingDialog::Repaint()
  9521. {
  9522.     Refresh();
  9523.     wxPaintEvent event;
  9524.     AddPendingEvent(event);
  9525. }
  9526. bool CSendingDialog::Status()
  9527. {
  9528.     if (fUIDone)
  9529.     {
  9530.         Destroy();
  9531.         return false;
  9532.     }
  9533.     if (fAbort && fCanCancel)
  9534.     {
  9535.         strStatus = "CANCELLED";
  9536.         Repaint();
  9537.         fWorkDone = true;
  9538.         return false;
  9539.     }
  9540.     return true;
  9541. }
  9542. bool CSendingDialog::Status(const string& str)
  9543. {
  9544.     if (!Status())
  9545.         return false;
  9546.     strStatus = str;
  9547.     Repaint();
  9548.     return true;
  9549. }
  9550. bool CSendingDialog::Error(const string& str)
  9551. {
  9552.     fCanCancel = false;
  9553.     fWorkDone = true;
  9554.     Status(string("Error: ") + str);
  9555.     return false;
  9556. }
  9557. void SendingDialogStartTransfer(void* parg)
  9558. {
  9559.     ((CSendingDialog*)parg)->StartTransfer();
  9560. }
  9561. void CSendingDialog::StartTransfer()
  9562. {  
  9563.     if (nPrice + nTransactionFee > GetBalance())
  9564.     {
  9565.         Error("You don't have enough money");
  9566.         return;
  9567.     }
  9568.     if (!Status("Connecting..."))
  9569.         return;
  9570.     CNode* pnode = ConnectNode(addr, 5 * 60);
  9571.     if (!pnode)
  9572.     {
  9573.         Error("Unable to connect");
  9574.         return;
  9575.     }
  9576.     if (!Status("Requesting public key..."))
  9577.         return;
  9578.     pnode->PushRequest("checkorder", wtx, SendingDialogOnReply2, this);
  9579. }
  9580. void SendingDialogOnReply2(void* parg, CDataStream& vRecv)
  9581. {
  9582.     ((CSendingDialog*)parg)->OnReply2(vRecv);
  9583. }
  9584. void CSendingDialog::OnReply2(CDataStream& vRecv)
  9585. {
  9586.     if (!Status("Received public key..."))
  9587.         return;
  9588.     CScript scriptPubKey;
  9589.     int nRet;
  9590.     try
  9591.     {
  9592.         vRecv >> nRet;
  9593.         if (nRet > 0)
  9594.         {
  9595.             string strMessage;
  9596.             vRecv >> strMessage;
  9597.             Error("Transfer was not accepted");
  9598.             return;
  9599.         }
  9600.         vRecv >> scriptPubKey;
  9601.     }
  9602.     catch (...)
  9603.     {
  9604.         Error("Invalid response received");
  9605.         return;
  9606.     }
  9607.     CNode* pnode = ConnectNode(addr, 5 * 60);
  9608.     if (!pnode)
  9609.     {
  9610.         Error("Lost connection");
  9611.         return;
  9612.     }
  9613.     while (wxDateTime::UNow() < start + wxTimeSpan(0, 0, 0, 2 * 1000))
  9614.     {
  9615.         Sleep(200);
  9616.         if (!Status())
  9617.             return;
  9618.     }
  9619.     CRITICAL_BLOCK(cs_main)
  9620.     {
  9621.         if (!Status("Creating transaction..."))
  9622.             return;
  9623.         if (nPrice + nTransactionFee > GetBalance())
  9624.         {
  9625.             Error("You don't have enough money");
  9626.             return;
  9627.         }
  9628.         int64 nFeeRequired;
  9629.         if (!CreateTransaction(scriptPubKey, nPrice, wtx, nFeeRequired))
  9630.         {
  9631.             if (nPrice + nFeeRequired > GetBalance())
  9632.                 Error(strprintf("This is an oversized transaction that requires a transaction fee of %s", FormatMoney(nFeeRequired).c_str()));
  9633.             else
  9634.                 Error("Transaction creation failed");
  9635.             return;
  9636.         }
  9637.         Sleep(50);
  9638.         if (!Status())
  9639.             return;
  9640.         fCanCancel = false;
  9641.         if (fAbort)
  9642.         {
  9643.             fCanCancel = true;
  9644.             if (!Status())
  9645.                 return;
  9646.             fCanCancel = false;
  9647.         }
  9648.         if (!Status("Sending payment..."))
  9649.             return;
  9650.         if (!CommitTransactionSpent(wtx))
  9651.         {
  9652.             Error("Error finalizing payment");
  9653.             return;
  9654.         }
  9655.         pnode->PushRequest("submitorder", wtx, SendingDialogOnReply3, this);
  9656.         if (!wtx.AcceptTransaction())
  9657.             printf("ERROR: CSendingDialog : wtxNew.AcceptTransaction() %s failed\n", wtx.GetHash().ToString().c_str());
  9658.         wtx.RelayWalletTransaction();
  9659.         Status("Waiting for confirmation...");
  9660.         MainFrameRepaint();
  9661.     }
  9662. }
  9663. void SendingDialogOnReply3(void* parg, CDataStream& vRecv)
  9664. {
  9665.     ((CSendingDialog*)parg)->OnReply3(vRecv);
  9666. }
  9667. void CSendingDialog::OnReply3(CDataStream& vRecv)
  9668. {
  9669.     int nRet;
  9670.     try
  9671.     {
  9672.         vRecv >> nRet;
  9673.         if (nRet > 0)
  9674.         {
  9675.             Error("The payment was sent, but the recipient was unable to verify it.\n"
  9676.                   "The transaction is recorded and will credit to the recipient if it is valid,\n"
  9677.                   "but without comment information.");
  9678.             return;
  9679.         }
  9680.     }
  9681.     catch (...)
  9682.     {
  9683.         Error("Payment was sent, but an invalid response was received");
  9684.         return;
  9685.     }
  9686.     fSuccess = true;
  9687.     fWorkDone = true;
  9688.     Status("Payment completed");
  9689. }
  9690. CYourAddressDialog::CYourAddressDialog(wxWindow* parent, const string& strInitSelected) : CYourAddressDialogBase(parent)
  9691. {
  9692.     m_listCtrl->InsertColumn(0, "Name", wxLIST_FORMAT_LEFT, 200);
  9693.     m_listCtrl->InsertColumn(1, "Bitcoin Address", wxLIST_FORMAT_LEFT, 350);
  9694.     m_listCtrl->SetFocus();
  9695.     CRITICAL_BLOCK(cs_mapKeys)
  9696.     {
  9697.         foreach(const PAIRTYPE(string, string)& item, mapAddressBook)
  9698.         {
  9699.             string strAddress = item.first;
  9700.             string strName = item.second;
  9701.             uint160 hash160;
  9702.             bool fMine = (AddressToHash160(strAddress, hash160) && mapPubKeys.count(hash160));
  9703.             if (fMine)
  9704.             {
  9705.                 int nIndex = InsertLine(m_listCtrl, strName, strAddress);
  9706.                 if (strAddress == strInitSelected)
  9707.                     m_listCtrl->SetItemState(nIndex, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED);
  9708.             }
  9709.         }
  9710.     }
  9711. }
  9712. wxString CYourAddressDialog::GetAddress()
  9713. {
  9714.     int nIndex = GetSelection(m_listCtrl);
  9715.     if (nIndex == -1)
  9716.         return "";
  9717.     return GetItemText(m_listCtrl, nIndex, 1);
  9718. }
  9719. void CYourAddressDialog::OnListEndLabelEdit(wxListEvent& event)
  9720. {
  9721.     if (event.IsEditCancelled())
  9722.         return;
  9723.     string strAddress = (string)GetItemText(m_listCtrl, event.GetIndex(), 1);
  9724.     SetAddressBookName(strAddress, string(event.GetText()));
  9725.     pframeMain->RefreshListCtrl();
  9726. }
  9727. void CYourAddressDialog::OnListItemSelected(wxListEvent& event)
  9728. {
  9729. }
  9730. void CYourAddressDialog::OnListItemActivated(wxListEvent& event)
  9731. {
  9732.     EndModal(true);
  9733. }
  9734. void CYourAddressDialog::OnButtonRename(wxCommandEvent& event)
  9735. {
  9736.     int nIndex = GetSelection(m_listCtrl);
  9737.     if (nIndex == -1)
  9738.         return;
  9739.     string strName = (string)m_listCtrl->GetItemText(nIndex);
  9740.     string strAddress = (string)GetItemText(m_listCtrl, nIndex, 1);
  9741.     CGetTextFromUserDialog dialog(this, "Rename Bitcoin Address", "New Name", strName);
  9742.     if (!dialog.ShowModal())
  9743.         return;
  9744.     strName = dialog.GetValue();
  9745.     SetAddressBookName(strAddress, strName);
  9746.     m_listCtrl->SetItemText(nIndex, strName);
  9747.     pframeMain->RefreshListCtrl();
  9748. }
  9749. void CYourAddressDialog::OnButtonNew(wxCommandEvent& event)
  9750. {
  9751.     CGetTextFromUserDialog dialog(this, "New Bitcoin Address", "Name", "");
  9752.     if (!dialog.ShowModal())
  9753.         return;
  9754.     string strName = dialog.GetValue();
  9755.     string strAddress = PubKeyToAddress(GenerateNewKey());
  9756.     SetAddressBookName(strAddress, strName);
  9757.     int nIndex = InsertLine(m_listCtrl, strName, strAddress);
  9758.     SetSelection(m_listCtrl, nIndex);
  9759.     m_listCtrl->SetFocus();
  9760. }
  9761. void CYourAddressDialog::OnButtonCopy(wxCommandEvent& event)
  9762. {
  9763.     if (wxTheClipboard->Open())
  9764.     {
  9765.         wxTheClipboard->SetData(new wxTextDataObject(GetAddress()));
  9766.         wxTheClipboard->Close();
  9767.     }
  9768. }
  9769. void CYourAddressDialog::OnButtonOK(wxCommandEvent& event)
  9770. {
  9771.     EndModal(true);
  9772. }
  9773. void CYourAddressDialog::OnButtonCancel(wxCommandEvent& event)
  9774. {
  9775.     EndModal(false);
  9776. }
  9777. void CYourAddressDialog::OnClose(wxCloseEvent& event)
  9778. {
  9779.     EndModal(false);
  9780. }
  9781. CAddressBookDialog::CAddressBookDialog(wxWindow* parent, const wxString& strInitSelected, bool fSendingIn) : CAddressBookDialogBase(parent)
  9782. {
  9783.     fSending = fSendingIn;
  9784.     if (!fSending)
  9785.         m_buttonCancel->Show(false);
  9786.     m_listCtrl->InsertColumn(0, "Name", wxLIST_FORMAT_LEFT, 200);
  9787.     m_listCtrl->InsertColumn(1, "Address", wxLIST_FORMAT_LEFT, 350);
  9788.     m_listCtrl->SetFocus();
  9789.     wxBitmap bmpAddressBook(wxT("addressbook16"), wxBITMAP_TYPE_RESOURCE);
  9790.     bmpAddressBook.SetMask(new wxMask(wxBitmap(wxT("addressbook16mask"), wxBITMAP_TYPE_RESOURCE)));
  9791.     wxIcon iconAddressBook;
  9792.     iconAddressBook.CopyFromBitmap(bmpAddressBook);
  9793.     SetIcon(iconAddressBook);
  9794.     CRITICAL_BLOCK(cs_mapKeys)
  9795.     {
  9796.         foreach(const PAIRTYPE(string, string)& item, mapAddressBook)
  9797.         {
  9798.             string strAddress = item.first;
  9799.             string strName = item.second;
  9800.             uint160 hash160;
  9801.             bool fMine = (AddressToHash160(strAddress, hash160) && mapPubKeys.count(hash160));
  9802.             if (!fMine)
  9803.             {
  9804.                 int nIndex = InsertLine(m_listCtrl, strName, strAddress);
  9805.                 if (strAddress == strInitSelected)
  9806.                     m_listCtrl->SetItemState(nIndex, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED);
  9807.             }
  9808.         }
  9809.     }
  9810. }
  9811. wxString CAddressBookDialog::GetAddress()
  9812. {
  9813.     int nIndex = GetSelection(m_listCtrl);
  9814.     if (nIndex == -1)
  9815.         return "";
  9816.     return GetItemText(m_listCtrl, nIndex, 1);
  9817. }
  9818. void CAddressBookDialog::OnListEndLabelEdit(wxListEvent& event)
  9819. {
  9820.     if (event.IsEditCancelled())
  9821.         return;
  9822.     string strAddress = (string)GetItemText(m_listCtrl, event.GetIndex(), 1);
  9823.     SetAddressBookName(strAddress, string(event.GetText()));
  9824.     pframeMain->RefreshListCtrl();
  9825. }
  9826. void CAddressBookDialog::OnListItemSelected(wxListEvent& event)
  9827. {
  9828. }
  9829. void CAddressBookDialog::OnListItemActivated(wxListEvent& event)
  9830. {
  9831.     if (fSending)
  9832.     {      
  9833.         EndModal(GetAddress() != "" ? 2 : 0);
  9834.     }
  9835.     else
  9836.     {
  9837.         wxCommandEvent event;
  9838.         OnButtonEdit(event);
  9839.     }
  9840. }
  9841. void CAddressBookDialog::OnButtonEdit(wxCommandEvent& event)
  9842. {
  9843.     int nIndex = GetSelection(m_listCtrl);
  9844.     if (nIndex == -1)
  9845.         return;
  9846.     string strName = (string)m_listCtrl->GetItemText(nIndex);
  9847.     string strAddress = (string)GetItemText(m_listCtrl, nIndex, 1);
  9848.     string strAddressOrg = strAddress;
  9849.     CGetTextFromUserDialog dialog(this, "Edit Address", "Name", strName, "Address", strAddress);
  9850.     if (!dialog.ShowModal())
  9851.         return;
  9852.     strName = dialog.GetValue1();
  9853.     strAddress = dialog.GetValue2();
  9854.     if (strAddress != strAddressOrg)
  9855.         CWalletDB().EraseName(strAddressOrg);
  9856.     SetAddressBookName(strAddress, strName);
  9857.     m_listCtrl->SetItem(nIndex, 1, strAddress);
  9858.     m_listCtrl->SetItemText(nIndex, strName);
  9859.     pframeMain->RefreshListCtrl();
  9860. }
  9861. void CAddressBookDialog::OnButtonNew(wxCommandEvent& event)
  9862. {
  9863.     CGetTextFromUserDialog dialog(this, "New Address", "Name", "", "Address", "");
  9864.     if (!dialog.ShowModal())
  9865.         return;
  9866.     string strName = dialog.GetValue1();
  9867.     string strAddress = dialog.GetValue2();
  9868.     SetAddressBookName(strAddress, strName);
  9869.     int nIndex = InsertLine(m_listCtrl, strName, strAddress);
  9870.     SetSelection(m_listCtrl, nIndex);
  9871.     m_listCtrl->SetFocus();
  9872. }
  9873. void CAddressBookDialog::OnButtonDelete(wxCommandEvent& event)
  9874. {
  9875.     for (int nIndex = m_listCtrl->GetItemCount()-1; nIndex >= 0; nIndex--)
  9876.     {
  9877.         if (m_listCtrl->GetItemState(nIndex, wxLIST_STATE_SELECTED))
  9878.         {
  9879.             string strAddress = (string)GetItemText(m_listCtrl, nIndex, 1);
  9880.             CWalletDB().EraseName(strAddress);
  9881.             m_listCtrl->DeleteItem(nIndex);
  9882.         }
  9883.     }
  9884.     pframeMain->RefreshListCtrl();
  9885. }
  9886. void CAddressBookDialog::OnButtonCopy(wxCommandEvent& event)
  9887. {
  9888.     if (wxTheClipboard->Open())
  9889.     {
  9890.         wxTheClipboard->SetData(new wxTextDataObject(GetAddress()));
  9891.         wxTheClipboard->Close();
  9892.     }
  9893. }
  9894. void CAddressBookDialog::OnButtonOK(wxCommandEvent& event)
  9895. {
  9896.     EndModal(GetAddress() != "" ? 1 : 0);
  9897. }
  9898. void CAddressBookDialog::OnButtonCancel(wxCommandEvent& event)
  9899. {
  9900.     EndModal(0);
  9901. }
  9902. void CAddressBookDialog::OnClose(wxCloseEvent& event)
  9903. {
  9904.     EndModal(0);
  9905. }
  9906. bool CompareIntStringPairBestFirst(const pair<int, string>& item1, const pair<int, string>& item2)
  9907. {
  9908.     return (item1.first > item2.first);
  9909. }
  9910. CProductsDialog::CProductsDialog(wxWindow* parent) : CProductsDialogBase(parent)
  9911. {
  9912.     m_listCtrl->InsertColumn(0, "Title",  wxLIST_FORMAT_LEFT, 200);
  9913.     m_listCtrl->InsertColumn(1, "Price",  wxLIST_FORMAT_LEFT, 80);
  9914.     m_listCtrl->InsertColumn(2, "Seller", wxLIST_FORMAT_LEFT, 80);
  9915.     m_listCtrl->InsertColumn(3, "Stars",  wxLIST_FORMAT_LEFT, 50);
  9916.     m_listCtrl->InsertColumn(4, "Power",  wxLIST_FORMAT_LEFT, 50);
  9917.  
  9918.     map<string, int> mapTopCategories;
  9919.     CRITICAL_BLOCK(cs_mapProducts)
  9920.         for (map<uint256, CProduct>::iterator mi = mapProducts.begin(); mi != mapProducts.end(); ++mi)
  9921.             mapTopCategories[(*mi).second.mapValue["category"]]++;
  9922.  
  9923.     vector<pair<int, string> > vTopCategories;
  9924.     for (map<string, int>::iterator mi = mapTopCategories.begin(); mi != mapTopCategories.end(); ++mi)
  9925.         vTopCategories.push_back(make_pair((*mi).second, (*mi).first));
  9926.     sort(vTopCategories.begin(), vTopCategories.end(), CompareIntStringPairBestFirst);
  9927.     int nLimit = 250;
  9928.     for (vector<pair<int, string> >::iterator it = vTopCategories.begin(); it != vTopCategories.end() && nLimit-- > 0; ++it)
  9929.         m_comboBoxCategory->Append((*it).second);
  9930. }
  9931. void CProductsDialog::OnCombobox(wxCommandEvent& event)
  9932. {
  9933.     OnButtonSearch(event);
  9934. }
  9935. bool CompareProductsBestFirst(const CProduct* p1, const CProduct* p2)
  9936. {
  9937.     return (p1->nAtoms > p2->nAtoms);
  9938. }
  9939. void CProductsDialog::OnButtonSearch(wxCommandEvent& event)
  9940. {
  9941.     string strCategory = (string)m_comboBoxCategory->GetValue();
  9942.     string strSearch = (string)m_textCtrlSearch->GetValue();
  9943.     vector<CProduct*> vProductsFound;
  9944.     CRITICAL_BLOCK(cs_mapProducts)
  9945.     {
  9946.         for (map<uint256, CProduct>::iterator mi = mapProducts.begin(); mi != mapProducts.end(); ++mi)
  9947.         {
  9948.             CProduct& product = (*mi).second;
  9949.             if (product.mapValue["category"].find(strCategory) != -1)
  9950.             {
  9951.                 if (product.mapValue["title"].find(strSearch) != -1 ||
  9952.                     product.mapValue["description"].find(strSearch) != -1 ||
  9953.                     product.mapValue["seller"].find(strSearch) != -1)
  9954.                 {
  9955.                     vProductsFound.push_back(&product);
  9956.                 }
  9957.             }
  9958.         }
  9959.     }
  9960.     sort(vProductsFound.begin(), vProductsFound.end(), CompareProductsBestFirst);
  9961.     foreach(CProduct* pproduct, vProductsFound)
  9962.     {
  9963.         InsertLine(m_listCtrl,
  9964.                    pproduct->mapValue["title"],
  9965.                    pproduct->mapValue["price"],
  9966.                    pproduct->mapValue["seller"],
  9967.                    pproduct->mapValue["stars"],
  9968.                    itostr(pproduct->nAtoms));
  9969.     }
  9970. }
  9971. void CProductsDialog::OnListItemActivated(wxListEvent& event)
  9972. {
  9973.     CViewProductDialog* pdialog = new CViewProductDialog(this, m_vProduct[event.GetIndex()]);
  9974.     pdialog->Show();
  9975. }
  9976. CEditProductDialog::CEditProductDialog(wxWindow* parent) : CEditProductDialogBase(parent)
  9977. {
  9978.     m_textCtrlLabel[0 ] = m_textCtrlLabel0;
  9979.     m_textCtrlLabel[1 ] = m_textCtrlLabel1;
  9980.     m_textCtrlLabel[2 ] = m_textCtrlLabel2;
  9981.     m_textCtrlLabel[3 ] = m_textCtrlLabel3;
  9982.     m_textCtrlLabel[4 ] = m_textCtrlLabel4;
  9983.     m_textCtrlLabel[5 ] = m_textCtrlLabel5;
  9984.     m_textCtrlLabel[6 ] = m_textCtrlLabel6;
  9985.     m_textCtrlLabel[7 ] = m_textCtrlLabel7;
  9986.     m_textCtrlLabel[8 ] = m_textCtrlLabel8;
  9987.     m_textCtrlLabel[9 ] = m_textCtrlLabel9;
  9988.     m_textCtrlLabel[10] = m_textCtrlLabel10;
  9989.     m_textCtrlLabel[11] = m_textCtrlLabel11;
  9990.     m_textCtrlLabel[12] = m_textCtrlLabel12;
  9991.     m_textCtrlLabel[13] = m_textCtrlLabel13;
  9992.     m_textCtrlLabel[14] = m_textCtrlLabel14;
  9993.     m_textCtrlLabel[15] = m_textCtrlLabel15;
  9994.     m_textCtrlLabel[16] = m_textCtrlLabel16;
  9995.     m_textCtrlLabel[17] = m_textCtrlLabel17;
  9996.     m_textCtrlLabel[18] = m_textCtrlLabel18;
  9997.     m_textCtrlLabel[19] = m_textCtrlLabel19;
  9998.     m_textCtrlField[0 ] = m_textCtrlField0;
  9999.     m_textCtrlField[1 ] = m_textCtrlField1;
  10000.     m_textCtrlField[2 ] = m_textCtrlField2;
  10001.     m_textCtrlField[3 ] = m_textCtrlField3;
  10002.     m_textCtrlField[4 ] = m_textCtrlField4;
  10003.     m_textCtrlField[5 ] = m_textCtrlField5;
  10004.     m_textCtrlField[6 ] = m_textCtrlField6;
  10005.     m_textCtrlField[7 ] = m_textCtrlField7;
  10006.     m_textCtrlField[8 ] = m_textCtrlField8;
  10007.     m_textCtrlField[9 ] = m_textCtrlField9;
  10008.     m_textCtrlField[10] = m_textCtrlField10;
  10009.     m_textCtrlField[11] = m_textCtrlField11;
  10010.     m_textCtrlField[12] = m_textCtrlField12;
  10011.     m_textCtrlField[13] = m_textCtrlField13;
  10012.     m_textCtrlField[14] = m_textCtrlField14;
  10013.     m_textCtrlField[15] = m_textCtrlField15;
  10014.     m_textCtrlField[16] = m_textCtrlField16;
  10015.     m_textCtrlField[17] = m_textCtrlField17;
  10016.     m_textCtrlField[18] = m_textCtrlField18;
  10017.     m_textCtrlField[19] = m_textCtrlField19;
  10018.     m_buttonDel[0 ] = m_buttonDel0;
  10019.     m_buttonDel[1 ] = m_buttonDel1;
  10020.     m_buttonDel[2 ] = m_buttonDel2;
  10021.     m_buttonDel[3 ] = m_buttonDel3;
  10022.     m_buttonDel[4 ] = m_buttonDel4;
  10023.     m_buttonDel[5 ] = m_buttonDel5;
  10024.     m_buttonDel[6 ] = m_buttonDel6;
  10025.     m_buttonDel[7 ] = m_buttonDel7;
  10026.     m_buttonDel[8 ] = m_buttonDel8;
  10027.     m_buttonDel[9 ] = m_buttonDel9;
  10028.     m_buttonDel[10] = m_buttonDel10;
  10029.     m_buttonDel[11] = m_buttonDel11;
  10030.     m_buttonDel[12] = m_buttonDel12;
  10031.     m_buttonDel[13] = m_buttonDel13;
  10032.     m_buttonDel[14] = m_buttonDel14;
  10033.     m_buttonDel[15] = m_buttonDel15;
  10034.     m_buttonDel[16] = m_buttonDel16;
  10035.     m_buttonDel[17] = m_buttonDel17;
  10036.     m_buttonDel[18] = m_buttonDel18;
  10037.     m_buttonDel[19] = m_buttonDel19;
  10038.     for (int i = 1; i < FIELDS_MAX; i++)
  10039.         ShowLine(i, false);
  10040.     LayoutAll();
  10041. }
  10042. void CEditProductDialog::LayoutAll()
  10043. {
  10044.     m_scrolledWindow->Layout();
  10045.     m_scrolledWindow->GetSizer()->Fit(m_scrolledWindow);
  10046.     this->Layout();
  10047. }
  10048. void CEditProductDialog::ShowLine(int i, bool fShow)
  10049. {
  10050.     m_textCtrlLabel[i]->Show(fShow);
  10051.     m_textCtrlField[i]->Show(fShow);
  10052.     m_buttonDel[i]->Show(fShow);
  10053. }
  10054. void CEditProductDialog::OnButtonDel0(wxCommandEvent& event)  { OnButtonDel(event, 0); }
  10055. void CEditProductDialog::OnButtonDel1(wxCommandEvent& event)  { OnButtonDel(event, 1); }
  10056. void CEditProductDialog::OnButtonDel2(wxCommandEvent& event)  { OnButtonDel(event, 2); }
  10057. void CEditProductDialog::OnButtonDel3(wxCommandEvent& event)  { OnButtonDel(event, 3); }
  10058. void CEditProductDialog::OnButtonDel4(wxCommandEvent& event)  { OnButtonDel(event, 4); }
  10059. void CEditProductDialog::OnButtonDel5(wxCommandEvent& event)  { OnButtonDel(event, 5); }
  10060. void CEditProductDialog::OnButtonDel6(wxCommandEvent& event)  { OnButtonDel(event, 6); }
  10061. void CEditProductDialog::OnButtonDel7(wxCommandEvent& event)  { OnButtonDel(event, 7); }
  10062. void CEditProductDialog::OnButtonDel8(wxCommandEvent& event)  { OnButtonDel(event, 8); }
  10063. void CEditProductDialog::OnButtonDel9(wxCommandEvent& event)  { OnButtonDel(event, 9); }
  10064. void CEditProductDialog::OnButtonDel10(wxCommandEvent& event) { OnButtonDel(event, 10); }
  10065. void CEditProductDialog::OnButtonDel11(wxCommandEvent& event) { OnButtonDel(event, 11); }
  10066. void CEditProductDialog::OnButtonDel12(wxCommandEvent& event) { OnButtonDel(event, 12); }
  10067. void CEditProductDialog::OnButtonDel13(wxCommandEvent& event) { OnButtonDel(event, 13); }
  10068. void CEditProductDialog::OnButtonDel14(wxCommandEvent& event) { OnButtonDel(event, 14); }
  10069. void CEditProductDialog::OnButtonDel15(wxCommandEvent& event) { OnButtonDel(event, 15); }
  10070. void CEditProductDialog::OnButtonDel16(wxCommandEvent& event) { OnButtonDel(event, 16); }
  10071. void CEditProductDialog::OnButtonDel17(wxCommandEvent& event) { OnButtonDel(event, 17); }
  10072. void CEditProductDialog::OnButtonDel18(wxCommandEvent& event) { OnButtonDel(event, 18); }
  10073. void CEditProductDialog::OnButtonDel19(wxCommandEvent& event) { OnButtonDel(event, 19); }
  10074. void CEditProductDialog::OnButtonDel(wxCommandEvent& event, int n)
  10075. {
  10076.     Freeze();
  10077.     int x, y;
  10078.     m_scrolledWindow->GetViewStart(&x, &y);
  10079.     int i;
  10080.     for (i = n; i < FIELDS_MAX-1; i++)
  10081.     {
  10082.         m_textCtrlLabel[i]->SetValue(m_textCtrlLabel[i+1]->GetValue());
  10083.         m_textCtrlField[i]->SetValue(m_textCtrlField[i+1]->GetValue());
  10084.         if (!m_buttonDel[i+1]->IsShown())
  10085.             break;
  10086.     }
  10087.     m_textCtrlLabel[i]->SetValue("");
  10088.     m_textCtrlField[i]->SetValue("");
  10089.     ShowLine(i, false);
  10090.     m_buttonAddField->Enable(true);
  10091.     LayoutAll();
  10092.     m_scrolledWindow->Scroll(0, y);
  10093.     Thaw();
  10094. }
  10095. void CEditProductDialog::OnButtonAddField(wxCommandEvent& event)
  10096. {
  10097.     for (int i = 0; i < FIELDS_MAX; i++)
  10098.     {
  10099.         if (!m_buttonDel[i]->IsShown())
  10100.         {
  10101.             Freeze();
  10102.             ShowLine(i, true);
  10103.             if (i == FIELDS_MAX-1)
  10104.                 m_buttonAddField->Enable(false);
  10105.             LayoutAll();
  10106.             m_scrolledWindow->Scroll(0, 99999);
  10107.             Thaw();
  10108.             break;
  10109.         }
  10110.     }
  10111. }
  10112. void CEditProductDialog::OnButtonSend(wxCommandEvent& event)
  10113. {
  10114.     CProduct product;
  10115.     GetProduct(product);
  10116.     product.vchPubKeyFrom = keyUser.GetPubKey();
  10117.     if (!keyUser.Sign(product.GetSigHash(), product.vchSig))
  10118.     {
  10119.         wxMessageBox("Error digitally signing the product ");
  10120.         return;
  10121.     }
  10122.     AddToMyProducts(product);
  10123.     product.mapDetails.clear();
  10124.     product.vOrderForm.clear();
  10125.     if (!keyUser.Sign(product.GetSigHash(), product.vchSig))
  10126.     {
  10127.         wxMessageBox("Error digitally signing the product ");
  10128.         return;
  10129.     }
  10130.     if (!product.CheckProduct())
  10131.     {
  10132.         wxMessageBox("Errors found in product ");
  10133.         return;
  10134.     }
  10135.     AdvertStartPublish(pnodeLocalHost, MSG_PRODUCT, 0, product);
  10136.     Destroy();
  10137. }
  10138. void CEditProductDialog::OnButtonPreview(wxCommandEvent& event)
  10139. {
  10140.     CProduct product;
  10141.     GetProduct(product);
  10142.     CViewProductDialog* pdialog = new CViewProductDialog(this, product);
  10143.     pdialog->Show();
  10144. }
  10145. void CEditProductDialog::OnButtonCancel(wxCommandEvent& event)
  10146. {
  10147.     Destroy();
  10148. }
  10149. void CEditProductDialog::SetProduct(const CProduct& productIn)
  10150. {
  10151.     CProduct product = productIn;
  10152.     m_comboBoxCategory->SetValue(product.mapValue["category"]);
  10153.     m_textCtrlTitle->SetValue(product.mapValue["title"]);
  10154.     m_textCtrlPrice->SetValue(product.mapValue["price"]);
  10155.     m_textCtrlDescription->SetValue(product.mapValue["description"]);
  10156.     m_textCtrlInstructions->SetValue(product.mapValue["instructions"]);
  10157.     for (int i = 0; i < FIELDS_MAX; i++)
  10158.     {
  10159.         bool fUsed = i < product.vOrderForm.size();
  10160.         m_buttonDel[i]->Show(fUsed);
  10161.         m_textCtrlLabel[i]->Show(fUsed);
  10162.         m_textCtrlField[i]->Show(fUsed);
  10163.         if (!fUsed)
  10164.             continue;
  10165.         m_textCtrlLabel[i]->SetValue(product.vOrderForm[i].first);
  10166.         string strControl = product.vOrderForm[i].second;
  10167.         if (strControl.substr(0, 5) == "text=")
  10168.             m_textCtrlField[i]->SetValue("");
  10169.         else if (strControl.substr(0, 7) == "choice=")
  10170.             m_textCtrlField[i]->SetValue(strControl.substr(7));
  10171.         else
  10172.             m_textCtrlField[i]->SetValue(strControl);
  10173.     }
  10174. }
  10175. void CEditProductDialog::GetProduct(CProduct& product)
  10176. {
  10177.     product.mapValue["category"]     = m_comboBoxCategory->GetValue().Trim();
  10178.     product.mapValue["title"]        = m_textCtrlTitle->GetValue().Trim();
  10179.     product.mapValue["price"]        = m_textCtrlPrice->GetValue().Trim();
  10180.     product.mapValue["description"]  = m_textCtrlDescription->GetValue().Trim();
  10181.     product.mapValue["instructions"] = m_textCtrlInstructions->GetValue().Trim();
  10182.     for (int i = 0; i < FIELDS_MAX; i++)
  10183.     {
  10184.         if (m_buttonDel[i]->IsShown())
  10185.         {
  10186.             string strLabel = (string)m_textCtrlLabel[i]->GetValue().Trim();
  10187.             string strControl = (string)m_textCtrlField[i]->GetValue();
  10188.             if (strControl.empty())
  10189.                 strControl = "text=";
  10190.             else
  10191.                 strControl = "choice=" + strControl;
  10192.             product.vOrderForm.push_back(make_pair(strLabel, strControl));
  10193.         }
  10194.     }
  10195. }
  10196. CViewProductDialog::CViewProductDialog(wxWindow* parent, const CProduct& productIn) : CViewProductDialogBase(parent)
  10197. {
  10198.     Connect(wxEVT_REPLY1, wxCommandEventHandler(CViewProductDialog::OnReply1), NULL, this);
  10199.     AddCallbackAvailable(GetEventHandler());
  10200.     product = productIn;
  10201.     UpdateProductDisplay(false);
  10202.     m_buttonBack->Enable(false);
  10203.     m_buttonNext->Enable(!product.vOrderForm.empty());
  10204.     m_htmlWinReviews->Show(true);
  10205.     m_scrolledWindow->Show(false);
  10206.     this->Layout();
  10207.     _beginthread(ThreadRequestProductDetails, 0, new pair<CProduct, wxEvtHandler*>(product, GetEventHandler()));
  10208. }
  10209. CViewProductDialog::~CViewProductDialog()
  10210. {
  10211.     RemoveCallbackAvailable(GetEventHandler());
  10212. }
  10213. void ThreadRequestProductDetails(void* parg)
  10214. {
  10215.     pair<CProduct, wxEvtHandler*>* pitem = (pair<CProduct, wxEvtHandler*>*)parg;
  10216.     CProduct product = pitem->first;
  10217.     wxEvtHandler* pevthandler = pitem->second;
  10218.     delete pitem;
  10219.     CNode* pnode = ConnectNode(product.addr, 5 * 60);
  10220.     if (!pnode)
  10221.     {
  10222.         CDataStream ssEmpty;
  10223.         AddPendingReplyEvent1(pevthandler, ssEmpty);
  10224.         return;
  10225.     }
  10226.     pnode->PushRequest("getdetails", product.GetHash(), AddPendingReplyEvent1, (void*)pevthandler);
  10227. }
  10228. void CViewProductDialog::OnReply1(wxCommandEvent& event)
  10229. {
  10230.     CDataStream ss = GetStreamFromEvent(event);
  10231.     if (ss.empty())
  10232.     {
  10233.         product.mapValue["description"] = "-- CAN'T CONNECT TO SELLER --\n";
  10234.         UpdateProductDisplay(true);
  10235.         return;
  10236.     }
  10237.     int nRet;
  10238.     CProduct product2;
  10239.     try
  10240.     {
  10241.         ss >> nRet;
  10242.         if (nRet > 0)
  10243.             throw false;
  10244.         ss >> product2;
  10245.         if (product2.GetHash() != product.GetHash())
  10246.             throw false;
  10247.         if (!product2.CheckSignature())
  10248.             throw false;
  10249.     }
  10250.     catch (...)
  10251.     {
  10252.         product.mapValue["description"] = "-- INVALID RESPONSE --\n";
  10253.         UpdateProductDisplay(true);
  10254.         return;
  10255.     }
  10256.     product = product2;
  10257.     UpdateProductDisplay(true);
  10258. }
  10259. bool CompareReviewsBestFirst(const CReview* p1, const CReview* p2)
  10260. {
  10261.     return (p1->nAtoms > p2->nAtoms);
  10262. }
  10263. void CViewProductDialog::UpdateProductDisplay(bool fDetails)
  10264. {
  10265.     string strHTML;
  10266.     strHTML.reserve(4000);
  10267.     strHTML += "<html>\n"
  10268.                "<head>\n"
  10269.                "<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n"
  10270.                "</head>\n"
  10271.                "<body>\n";
  10272.     strHTML += "<b>Category:</b> " + HtmlEscape(product.mapValue["category"]) + "<br>\n";
  10273.     strHTML += "<b>Title:</b> "    + HtmlEscape(product.mapValue["title"])    + "<br>\n";
  10274.     strHTML += "<b>Price:</b> "    + HtmlEscape(product.mapValue["price"])    + "<br>\n";
  10275.     if (!fDetails)
  10276.         strHTML += "<b>Loading details...</b><br>\n<br>\n";
  10277.     else
  10278.         strHTML += HtmlEscape(product.mapValue["description"], true) + "<br>\n<br>\n";
  10279.     strHTML += "<b>Reviews:</b><br>\n<br>\n";
  10280.     if (!product.vchPubKeyFrom.empty())
  10281.     {
  10282.         CReviewDB reviewdb("r");
  10283.         vector<CReview> vReviews;
  10284.         reviewdb.ReadReviews(product.GetUserHash(), vReviews);
  10285.         vector<CReview*> vSortedReviews;
  10286.         vSortedReviews.reserve(vReviews.size());
  10287.         for (vector<CReview>::reverse_iterator it = vReviews.rbegin(); it != vReviews.rend(); ++it)
  10288.         {
  10289.             CReview& review = *it;
  10290.             CUser user;
  10291.             reviewdb.ReadUser(review.GetUserHash(), user);
  10292.             review.nAtoms = user.GetAtomCount();
  10293.             vSortedReviews.push_back(&review);
  10294.         }
  10295.         reviewdb.Close();
  10296.         stable_sort(vSortedReviews.begin(), vSortedReviews.end(), CompareReviewsBestFirst);
  10297.         foreach(CReview* preview, vSortedReviews)
  10298.         {
  10299.             CReview& review = *preview;
  10300.             int nStars = atoi(review.mapValue["stars"].c_str());
  10301.             if (nStars < 1 || nStars > 5)
  10302.                 continue;
  10303.             strHTML += "<b>" + itostr(nStars) + (nStars == 1 ? " star" : " stars") + "</b>";
  10304.             strHTML += " &nbsp;&nbsp;&nbsp; ";
  10305.             strHTML += DateStr(atoi64(review.mapValue["date"])) + "<br>\n";
  10306.             strHTML += HtmlEscape(review.mapValue["review"], true);
  10307.             strHTML += "<br>\n<br>\n";
  10308.         }
  10309.     }
  10310.     strHTML += "</body>\n</html>\n";
  10311.     string(strHTML.begin(), strHTML.end()).swap(strHTML);
  10312.     m_htmlWinReviews->SetPage(strHTML);
  10313.     if (product.vOrderForm.empty())
  10314.         return;
  10315.     m_staticTextInstructions->SetLabel(product.mapValue["instructions"]);
  10316.     for (int i = 0; i < FIELDS_MAX; i++)
  10317.     {
  10318.         m_staticTextLabel[i] = NULL;
  10319.         m_textCtrlField[i] = NULL;
  10320.         m_choiceField[i] = NULL;
  10321.     }
  10322.     wxBoxSizer* bSizer21 = (wxBoxSizer*)m_scrolledWindow->GetSizer();
  10323.     wxFlexGridSizer* fgSizer;
  10324.     fgSizer = new wxFlexGridSizer(0, 2, 0, 0);
  10325.     fgSizer->AddGrowableCol(1);
  10326.     fgSizer->SetFlexibleDirection(wxBOTH);
  10327.     fgSizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
  10328.     wxWindow* windowLast = NULL;
  10329.     for (int i = 0; i < product.vOrderForm.size(); i++)
  10330.     {
  10331.         string strLabel = product.vOrderForm[i].first;
  10332.         string strControl = product.vOrderForm[i].second;
  10333.         if (strLabel.size() < 20)
  10334.             strLabel.insert(strLabel.begin(), 20 - strLabel.size(), ' ');
  10335.         m_staticTextLabel[i] = new wxStaticText(m_scrolledWindow, wxID_ANY, strLabel, wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
  10336.         m_staticTextLabel[i]->Wrap(-1);
  10337.         fgSizer->Add(m_staticTextLabel[i], 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5);
  10338.         if (strControl.substr(0, 5) == "text=")
  10339.         {
  10340.             m_textCtrlField[i] = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
  10341.             fgSizer->Add(m_textCtrlField[i], 1, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5);
  10342.             windowLast = m_textCtrlField[i];
  10343.         }
  10344.         else if (strControl.substr(0, 7) == "choice=")
  10345.         {
  10346.             vector<string> vChoices;
  10347.             ParseString(strControl.substr(7), ',', vChoices);
  10348.             wxArrayString arraystring;
  10349.             foreach(const string& str, vChoices)
  10350.                 arraystring.Add(str);
  10351.             m_choiceField[i] = new wxChoice(m_scrolledWindow, wxID_ANY, wxDefaultPosition, wxDefaultSize, arraystring, 0);
  10352.             fgSizer->Add(m_choiceField[i], 0, wxALL|wxALIGN_CENTER_VERTICAL, 5);
  10353.             windowLast = m_choiceField[i];
  10354.         }
  10355.         else
  10356.         {
  10357.             m_textCtrlField[i] = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
  10358.             fgSizer->Add(m_textCtrlField[i], 1, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5);
  10359.             m_staticTextLabel[i]->Show(false);
  10360.             m_textCtrlField[i]->Show(false);
  10361.         }
  10362.     }
  10363.     bSizer21->Insert(2, fgSizer, 0, wxEXPAND|wxRIGHT|wxLEFT, 5);
  10364.     m_scrolledWindow->Layout();
  10365.     bSizer21->Fit(m_scrolledWindow);
  10366.     this->Layout();
  10367.     m_buttonSubmitForm->MoveAfterInTabOrder(windowLast);
  10368.     m_buttonCancelForm->MoveAfterInTabOrder(m_buttonSubmitForm);
  10369.     this->Layout();
  10370. }
  10371. void CViewProductDialog::GetOrder(CWalletTx& wtx)
  10372. {
  10373.     wtx.SetNull();
  10374.     for (int i = 0; i < product.vOrderForm.size(); i++)
  10375.     {
  10376.         string strValue;
  10377.         if (m_textCtrlField[i])
  10378.             strValue = m_textCtrlField[i]->GetValue().Trim();
  10379.         else
  10380.             strValue = m_choiceField[i]->GetStringSelection();
  10381.         wtx.vOrderForm.push_back(make_pair(m_staticTextLabel[i]->GetLabel(), strValue));
  10382.     }
  10383. }
  10384. void CViewProductDialog::OnButtonSubmitForm(wxCommandEvent& event)
  10385. {
  10386.     m_buttonSubmitForm->Enable(false);
  10387.     m_buttonCancelForm->Enable(false);
  10388.     CWalletTx wtx;
  10389.     GetOrder(wtx);
  10390.     CSendingDialog* pdialog = new CSendingDialog(this, product.addr, atoi64(product.mapValue["price"]), wtx);
  10391.     if (!pdialog->ShowModal())
  10392.     {
  10393.         m_buttonSubmitForm->Enable(true);
  10394.         m_buttonCancelForm->Enable(true);
  10395.         return;
  10396.     }
  10397. }
  10398. void CViewProductDialog::OnButtonCancelForm(wxCommandEvent& event)
  10399. {
  10400.     Destroy();
  10401. }
  10402. void CViewProductDialog::OnButtonBack(wxCommandEvent& event)
  10403. {
  10404.     Freeze();
  10405.     m_htmlWinReviews->Show(true);
  10406.     m_scrolledWindow->Show(false);
  10407.     m_buttonBack->Enable(false);
  10408.     m_buttonNext->Enable(!product.vOrderForm.empty());
  10409.     this->Layout();
  10410.     Thaw();
  10411. }
  10412. void CViewProductDialog::OnButtonNext(wxCommandEvent& event)
  10413. {
  10414.     if (!product.vOrderForm.empty())
  10415.     {
  10416.         Freeze();
  10417.         m_htmlWinReviews->Show(false);
  10418.         m_scrolledWindow->Show(true);
  10419.         m_buttonBack->Enable(true);
  10420.         m_buttonNext->Enable(false);
  10421.         this->Layout();
  10422.         Thaw();
  10423.     }
  10424. }
  10425. void CViewProductDialog::OnButtonCancel(wxCommandEvent& event)
  10426. {
  10427.     Destroy();
  10428. }
  10429. CViewOrderDialog::CViewOrderDialog(wxWindow* parent, CWalletTx order, bool fReceived) : CViewOrderDialogBase(parent)
  10430. {
  10431.     int64 nPrice = (fReceived ? order.GetCredit() : order.GetDebit());
  10432.     string strHTML;
  10433.     strHTML.reserve(4000);
  10434.     strHTML += "<html>\n"
  10435.                "<head>\n"
  10436.                "<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n"
  10437.                "</head>\n"
  10438.                "<body>\n";
  10439.     strHTML += "<b>Time:</b> "   + HtmlEscape(DateTimeStr(order.nTimeReceived)) + "<br>\n";
  10440.     strHTML += "<b>Price:</b> "  + HtmlEscape(FormatMoney(nPrice)) + "<br>\n";
  10441.     strHTML += "<b>Status:</b> " + HtmlEscape(FormatTxStatus(order)) + "<br>\n";
  10442.     strHTML += "<table>\n";
  10443.     for (int i = 0; i < order.vOrderForm.size(); i++)
  10444.     {
  10445.         strHTML += " <tr><td><b>" + HtmlEscape(order.vOrderForm[i].first) + ":</b></td>";
  10446.         strHTML += "<td>" + HtmlEscape(order.vOrderForm[i].second) + "</td></tr>\n";
  10447.     }
  10448.     strHTML += "</table>\n";
  10449.     strHTML += "</body>\n</html>\n";
  10450.     string(strHTML.begin(), strHTML.end()).swap(strHTML);
  10451.     m_htmlWin->SetPage(strHTML);
  10452. }
  10453. void CViewOrderDialog::OnButtonOK(wxCommandEvent& event)
  10454. {
  10455.     Destroy();
  10456. }
  10457. CEditReviewDialog::CEditReviewDialog(wxWindow* parent) : CEditReviewDialogBase(parent)
  10458. {
  10459. }
  10460. void CEditReviewDialog::OnButtonSubmit(wxCommandEvent& event)
  10461. {
  10462.     if (m_choiceStars->GetSelection() == -1)
  10463.     {
  10464.         wxMessageBox("Please select a rating ");
  10465.         return;
  10466.     }
  10467.     CReview review;
  10468.     GetReview(review);
  10469.     review.vchPubKeyFrom = keyUser.GetPubKey();
  10470.     if (!keyUser.Sign(review.GetSigHash(), review.vchSig))
  10471.     {
  10472.         wxMessageBox("Unable to digitally sign the review ");
  10473.         return;
  10474.     }
  10475.     if (!review.AcceptReview())
  10476.     {
  10477.         wxMessageBox("Save failed ");
  10478.         return;
  10479.     }
  10480.     RelayMessage(CInv(MSG_REVIEW, review.GetHash()), review);
  10481.     Destroy();
  10482. }
  10483. void CEditReviewDialog::OnButtonCancel(wxCommandEvent& event)
  10484. {
  10485.     Destroy();
  10486. }
  10487. void CEditReviewDialog::GetReview(CReview& review)
  10488. {
  10489.     review.mapValue["time"]   = i64tostr(GetAdjustedTime());
  10490.     review.mapValue["stars"]  = itostr(m_choiceStars->GetSelection()+1);
  10491.     review.mapValue["review"] = m_textCtrlReview->GetValue();
  10492. }
  10493. class CMyApp: public wxApp
  10494. {
  10495.   public:
  10496.     CMyApp(){};
  10497.     ~CMyApp(){};
  10498.     bool OnInit();
  10499.     bool OnInit2();
  10500.     int OnExit();
  10501.     virtual bool OnExceptionInMainLoop();
  10502.     virtual void OnUnhandledException();
  10503.     virtual void OnFatalException();
  10504. };
  10505. IMPLEMENT_APP(CMyApp)
  10506. bool CMyApp::OnInit()
  10507. {
  10508.     try
  10509.     {
  10510.         return OnInit2();
  10511.     }
  10512.     catch (std::exception& e) {
  10513.         PrintException(&e, "OnInit()");
  10514.     } catch (...) {
  10515.         PrintException(NULL, "OnInit()");
  10516.     }
  10517.     return false;
  10518. }
  10519. map<string, string> ParseParameters(int argc, char* argv[])
  10520. {
  10521.     map<string, string> mapArgs;
  10522.     for (int i = 0; i < argc; i++)
  10523.     {
  10524.         char psz[10000];
  10525.         strcpy(psz, argv[i]);
  10526.         char* pszValue = "";
  10527.         if (strchr(psz, '='))
  10528.         {
  10529.             pszValue = strchr(psz, '=');
  10530.             *pszValue++ = '\0';
  10531.         }
  10532.         strlwr(psz);
  10533.         if (psz[0] == '-')
  10534.             psz[0] = '/';
  10535.         mapArgs[psz] = pszValue;
  10536.     }
  10537.     return mapArgs;
  10538. }
  10539. bool CMyApp::OnInit2()
  10540. {
  10541. #ifdef _MSC_VER
  10542.     _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
  10543.     _CrtSetReportFile(_CRT_WARN, CreateFile("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0));
  10544. #endif
  10545.     printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
  10546.     printf("Bitcoin CMyApp::OnInit()\n");
  10547.     wxString strMutexName = wxString("Bitcoin.") + getenv("HOMEPATH");
  10548.     for (int i = 0; i < strMutexName.size(); i++)
  10549.         if (!isalnum(strMutexName[i]))
  10550.             strMutexName[i] = '.';
  10551.     wxSingleInstanceChecker* psingleinstancechecker = new wxSingleInstanceChecker(strMutexName);
  10552.     if (psingleinstancechecker->IsAnotherRunning())
  10553.     {
  10554.         printf("Existing instance found\n");
  10555.         unsigned int nStart = GetTime();
  10556.         loop
  10557.         {
  10558.             HWND hwndPrev = FindWindow("wxWindowClassNR", "Bitcoin");
  10559.             if (hwndPrev)
  10560.             {
  10561.                 if (IsIconic(hwndPrev))
  10562.                     ShowWindow(hwndPrev, SW_RESTORE);
  10563.                 SetForegroundWindow(hwndPrev);
  10564.                 return false;
  10565.             }
  10566.             if (GetTime() > nStart + 60)
  10567.                 return false;
  10568.             delete psingleinstancechecker;
  10569.             Sleep(1000);
  10570.             psingleinstancechecker = new wxSingleInstanceChecker(strMutexName);
  10571.             if (!psingleinstancechecker->IsAnotherRunning())
  10572.                 break;
  10573.         }
  10574.     }
  10575.     wxImage::AddHandler(new wxPNGHandler);
  10576.     map<string, string> mapArgs = ParseParameters(argc, argv);
  10577.     if (mapArgs.count("/datadir"))
  10578.         strSetDataDir = mapArgs["/datadir"];
  10579.     if (mapArgs.count("/proxy"))
  10580.         addrProxy = CAddress(mapArgs["/proxy"].c_str());
  10581.     if (mapArgs.count("/debug"))
  10582.         fDebug = true;
  10583.     if (mapArgs.count("/dropmessages"))
  10584.     {
  10585.         nDropMessagesTest = atoi(mapArgs["/dropmessages"]);
  10586.         if (nDropMessagesTest == 0)
  10587.             nDropMessagesTest = 20;
  10588.     }
  10589.     if (mapArgs.count("/loadblockindextest"))
  10590.     {
  10591.         CTxDB txdb("r");
  10592.         txdb.LoadBlockIndex();
  10593.         PrintBlockTree();
  10594.         ExitProcess(0);
  10595.     }
  10596.     string strErrors;
  10597.     int64 nStart, nEnd;
  10598.     printf("Loading addresses...\n");
  10599.     QueryPerformanceCounter((LARGE_INTEGER*)&nStart);
  10600.     if (!LoadAddresses())
  10601.         strErrors += "Error loading addr.dat      \n";
  10602.     QueryPerformanceCounter((LARGE_INTEGER*)&nEnd);
  10603.     printf(" addresses   %20I64d\n", nEnd - nStart);
  10604.     printf("Loading block index...\n");
  10605.     QueryPerformanceCounter((LARGE_INTEGER*)&nStart);
  10606.     if (!LoadBlockIndex())
  10607.         strErrors += "Error loading blkindex.dat      \n";
  10608.     QueryPerformanceCounter((LARGE_INTEGER*)&nEnd);
  10609.     printf(" block index %20I64d\n", nEnd - nStart);
  10610.     printf("Loading wallet...\n");
  10611.     QueryPerformanceCounter((LARGE_INTEGER*)&nStart);
  10612.     if (!LoadWallet())
  10613.         strErrors += "Error loading wallet.dat      \n";
  10614.     QueryPerformanceCounter((LARGE_INTEGER*)&nEnd);
  10615.     printf(" wallet      %20I64d\n", nEnd - nStart);
  10616.     printf("Done loading\n");
  10617.         printf("mapBlockIndex.size() = %d\n",   mapBlockIndex.size());
  10618.         printf("nBestHeight = %d\n",            nBestHeight);
  10619.         printf("mapKeys.size() = %d\n",         mapKeys.size());
  10620.         printf("mapPubKeys.size() = %d\n",      mapPubKeys.size());
  10621.         printf("mapWallet.size() = %d\n",       mapWallet.size());
  10622.         printf("mapAddressBook.size() = %d\n",  mapAddressBook.size());
  10623.     if (!strErrors.empty())
  10624.     {
  10625.         wxMessageBox(strErrors);
  10626.         OnExit();
  10627.         return false;
  10628.     }
  10629.     ReacceptWalletTransactions();
  10630.     if (mapArgs.count("/printblockindex") || mapArgs.count("/printblocktree"))
  10631.     {
  10632.         PrintBlockTree();
  10633.         OnExit();
  10634.         return false;
  10635.     }
  10636.     if (mapArgs.count("/gen"))
  10637.     {
  10638.         if (mapArgs["/gen"].empty())
  10639.             fGenerateBitcoins = true;
  10640.         else
  10641.             fGenerateBitcoins = atoi(mapArgs["/gen"].c_str());
  10642.     }
  10643.     {
  10644.         pframeMain = new CMainFrame(NULL);
  10645.         pframeMain->Show();
  10646.         if (!StartNode(strErrors))
  10647.             wxMessageBox(strErrors);
  10648.         if (fGenerateBitcoins)
  10649.             if (_beginthread(ThreadBitcoinMiner, 0, NULL) == -1)
  10650.                 printf("Error: _beginthread(ThreadBitcoinMiner) failed\n");
  10651.         if (argc >= 2 && stricmp(argv[1], "/send") == 0)
  10652.         {
  10653.             int64 nValue = 1;
  10654.             if (argc >= 3)
  10655.                 ParseMoney(argv[2], nValue);
  10656.             string strAddress;
  10657.             if (argc >= 4)
  10658.                 strAddress = argv[3];
  10659.             CAddress addr(strAddress.c_str());
  10660.             CWalletTx wtx;
  10661.             wtx.mapValue["to"] = strAddress;
  10662.             wtx.mapValue["from"] = addrLocalHost.ToString();
  10663.             wtx.mapValue["message"] = "command line send";
  10664.             CSendingDialog* pdialog = new CSendingDialog(pframeMain, addr, nValue, wtx);
  10665.             if (!pdialog->ShowModal())
  10666.                 return false;
  10667.         }
  10668.         if (mapArgs.count("/randsendtest"))
  10669.         {
  10670.             if (!mapArgs["/randsendtest"].empty())
  10671.                 _beginthread(ThreadRandSendTest, 0, new string(mapArgs["/randsendtest"]));
  10672.             else
  10673.                 fRandSendTest = true;
  10674.             fDebug = true;
  10675.         }
  10676.     }
  10677.     return true;
  10678. }
  10679. int CMyApp::OnExit()
  10680. {
  10681.     Shutdown(NULL);
  10682.     return wxApp::OnExit();
  10683. }
  10684. bool CMyApp::OnExceptionInMainLoop()
  10685. {
  10686.     try
  10687.     {
  10688.         throw;
  10689.     }
  10690.     catch (std::exception& e)
  10691.     {
  10692.         PrintException(&e, "CMyApp::OnExceptionInMainLoop()");
  10693.         wxLogWarning(_T("Exception %s %s"), typeid(e).name(), e.what());
  10694.         Sleep(1000);
  10695.         throw;
  10696.     }
  10697.     catch (...)
  10698.     {
  10699.         PrintException(NULL, "CMyApp::OnExceptionInMainLoop()");
  10700.         wxLogWarning(_T("Unknown exception"));
  10701.         Sleep(1000);
  10702.         throw;
  10703.     }
  10704.     return true;
  10705. }
  10706. void CMyApp::OnUnhandledException()
  10707. {
  10708.     try
  10709.     {
  10710.         throw;
  10711.     }
  10712.     catch (std::exception& e)
  10713.     {
  10714.         PrintException(&e, "CMyApp::OnUnhandledException()");
  10715.         wxLogWarning(_T("Exception %s %s"), typeid(e).name(), e.what());
  10716.         Sleep(1000);
  10717.         throw;
  10718.     }
  10719.     catch (...)
  10720.     {
  10721.         PrintException(NULL, "CMyApp::OnUnhandledException()");
  10722.         wxLogWarning(_T("Unknown exception"));
  10723.         Sleep(1000);
  10724.         throw;
  10725.     }
  10726. }
  10727. void CMyApp::OnFatalException()
  10728. {
  10729.     wxMessageBox("Program has crashed and will terminate. ", "", wxOK | wxICON_ERROR);
  10730. }
  10731. void MainFrameRepaint()
  10732. {
  10733.     if (pframeMain)
  10734.     {
  10735.         printf("MainFrameRepaint()\n");
  10736.         wxPaintEvent event;
  10737.         pframeMain->Refresh();
  10738.         pframeMain->AddPendingEvent(event);
  10739.     }
  10740. }
  10741. void ThreadRandSendTest(void* parg)
  10742. {
  10743.     string strAddress = *(string*)parg;
  10744.     uint160 hash160;
  10745.     if (!AddressToHash160(strAddress, hash160))
  10746.     {
  10747.         wxMessageBox(strprintf("ThreadRandSendTest: Bitcoin address '%s' not valid ", strAddress.c_str()));
  10748.         return;
  10749.     }
  10750.     loop
  10751.     {
  10752.         Sleep(GetRand(30) * 1000 + 100);
  10753.         CWalletTx wtx;
  10754.         wtx.mapValue["to"] = strAddress;
  10755.         wtx.mapValue["from"] = addrLocalHost.ToString();
  10756.         static int nRep;
  10757.         wtx.mapValue["message"] = strprintf("randsendtest %d\n", ++nRep);
  10758.         int64 nValue = (GetRand(9) + 1) * 100 * CENT;
  10759.         if (GetBalance() < nValue)
  10760.         {
  10761.             wxMessageBox("Out of money ");
  10762.             return;
  10763.         }
  10764.         nValue += (nRep % 100) * CENT;
  10765.         CScript scriptPubKey;
  10766.         scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG;
  10767.         if (!SendMoney(scriptPubKey, nValue, wtx))
  10768.             return;
  10769.     }
  10770. }
  10771. void RandSend()
  10772. {
  10773.     CWalletTx wtx;
  10774.     while (vNodes.empty())
  10775.         Sleep(1000);
  10776.     CAddress addr;
  10777.     CRITICAL_BLOCK(cs_vNodes)
  10778.         addr = vNodes[GetRand(vNodes.size())]->addr;
  10779.     wtx.mapValue["to"] = addr.ToString();
  10780.     wtx.mapValue["from"] = addrLocalHost.ToString();
  10781.     static int nRep;
  10782.     wtx.mapValue["message"] = strprintf("randsendtest %d\n", ++nRep);
  10783.     int64 nValue = (GetRand(999) + 1) * CENT;
  10784.     if (GetBalance() < nValue)
  10785.     {
  10786.         wxMessageBox("Out of money ");
  10787.         return;
  10788.     }
  10789.     CSendingDialog* pdialog = new CSendingDialog(pframeMain, addr, nValue, wtx);
  10790.     if (!pdialog->Show())
  10791.         wxMessageBox("ShowModal Failed ");
  10792. }
  10793. DECLARE_EVENT_TYPE(wxEVT_CROSSTHREADCALL, -1)
  10794. DECLARE_EVENT_TYPE(wxEVT_REPLY1, -1)
  10795. DECLARE_EVENT_TYPE(wxEVT_REPLY2, -1)
  10796. DECLARE_EVENT_TYPE(wxEVT_REPLY3, -1)
  10797. DECLARE_EVENT_TYPE(wxEVT_TABLEADDED, -1)
  10798. DECLARE_EVENT_TYPE(wxEVT_TABLEUPDATED, -1)
  10799. DECLARE_EVENT_TYPE(wxEVT_TABLEDELETED, -1)
  10800. enum
  10801. {
  10802.     UICALL_ADDORDER = 1,
  10803.     UICALL_UPDATEORDER,
  10804. };
  10805. extern void HandleCtrlA(wxKeyEvent& event);
  10806. extern string DateTimeStr(int64 nTime);
  10807. extern string FormatTxStatus(const CWalletTx& wtx);
  10808. extern void CrossThreadCall(int nID, void* pdata);
  10809. extern void MainFrameRepaint();
  10810. class CMainFrame : public CMainFrameBase
  10811. {
  10812. protected:
  10813.     void OnClose(wxCloseEvent& event);
  10814.     void OnMouseEvents(wxMouseEvent& event);
  10815.     void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); }
  10816.     void OnIdle(wxIdleEvent& event);
  10817.     void OnPaint(wxPaintEvent& event);
  10818.     void OnPaintListCtrl(wxPaintEvent& event);
  10819.     void OnMenuFileExit(wxCommandEvent& event);
  10820.     void OnMenuOptionsGenerate(wxCommandEvent& event);
  10821.     void OnMenuOptionsOptions(wxCommandEvent& event);
  10822.     void OnMenuHelpAbout(wxCommandEvent& event);
  10823.     void OnButtonSend(wxCommandEvent& event);
  10824.     void OnButtonAddressBook(wxCommandEvent& event);
  10825.     void OnSetFocusAddress(wxFocusEvent& event);
  10826.     void OnMouseEventsAddress(wxMouseEvent& event);
  10827.     void OnButtonCopy(wxCommandEvent& event);
  10828.     void OnButtonChange(wxCommandEvent& event);
  10829.     void OnListColBeginDrag(wxListEvent& event);
  10830.     void OnListItemActivatedAllTransactions(wxListEvent& event);
  10831.     void OnListItemActivatedProductsSent(wxListEvent& event);
  10832.     void OnListItemActivatedOrdersSent(wxListEvent& event);
  10833.     void OnListItemActivatedOrdersReceived(wxListEvent& event);
  10834. public:
  10835.     CMainFrame(wxWindow* parent);
  10836.     ~CMainFrame();
  10837.     bool fRefreshListCtrl;
  10838.     bool fRefreshListCtrlRunning;
  10839.     bool fOnSetFocusAddress;
  10840.     CBlockIndex* pindexBestLast;
  10841.     set<uint256> setUnmaturedDisplayed;
  10842.     void OnCrossThreadCall(wxCommandEvent& event);
  10843.     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);
  10844.     void InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex=-1);
  10845.     void RefreshListCtrl();
  10846.     void RefreshStatus();
  10847. };
  10848. class CTxDetailsDialog : public CTxDetailsDialogBase
  10849. {
  10850. protected:
  10851.     void OnButtonOK(wxCommandEvent& event);
  10852. public:
  10853.     CTxDetailsDialog(wxWindow* parent, CWalletTx wtx);
  10854.     CWalletTx wtx;
  10855. };
  10856. class COptionsDialog : public COptionsDialogBase
  10857. {
  10858. protected:
  10859.     void OnKillFocusTransactionFee(wxFocusEvent& event);
  10860.     void OnButtonOK(wxCommandEvent& event);
  10861.     void OnButtonCancel(wxCommandEvent& event);
  10862. public:
  10863.     COptionsDialog(wxWindow* parent);
  10864. };
  10865. class CAboutDialog : public CAboutDialogBase
  10866. {
  10867. protected:
  10868.     void OnButtonOK(wxCommandEvent& event);
  10869. public:
  10870.     CAboutDialog(wxWindow* parent);
  10871. };
  10872. class CSendDialog : public CSendDialogBase
  10873. {
  10874. protected:
  10875.     void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); }
  10876.     void OnTextAddress(wxCommandEvent& event);
  10877.     void OnKillFocusAmount(wxFocusEvent& event);
  10878.     void OnButtonAddressBook(wxCommandEvent& event);
  10879.     void OnButtonPaste(wxCommandEvent& event);
  10880.     void OnButtonSend(wxCommandEvent& event);
  10881.     void OnButtonCancel(wxCommandEvent& event);
  10882. public:
  10883.     CSendDialog(wxWindow* parent, const wxString& strAddress="");
  10884. };
  10885. class CSendingDialog : public CSendingDialogBase
  10886. {
  10887. public:
  10888.     void OnClose(wxCloseEvent& event);
  10889.     void OnButtonOK(wxCommandEvent& event);
  10890.     void OnButtonCancel(wxCommandEvent& event);
  10891.     void OnPaint(wxPaintEvent& event);
  10892. public:
  10893.     CSendingDialog(wxWindow* parent, const CAddress& addrIn, int64 nPriceIn, const CWalletTx& wtxIn);
  10894.     ~CSendingDialog();
  10895.     CAddress addr;
  10896.     int64 nPrice;
  10897.     CWalletTx wtx;
  10898.     wxDateTime start;
  10899.     string strStatus;
  10900.     bool fCanCancel;
  10901.     bool fAbort;
  10902.     bool fSuccess;
  10903.     bool fUIDone;
  10904.     bool fWorkDone;
  10905.     void Close();
  10906.     void Repaint();
  10907.     bool Status();
  10908.     bool Status(const string& str);
  10909.     bool Error(const string& str);
  10910.     void StartTransfer();
  10911.     void OnReply2(CDataStream& vRecv);
  10912.     void OnReply3(CDataStream& vRecv);
  10913. };
  10914. void SendingDialogStartTransfer(void* parg);
  10915. void SendingDialogOnReply2(void* parg, CDataStream& vRecv);
  10916. void SendingDialogOnReply3(void* parg, CDataStream& vRecv);
  10917. class CYourAddressDialog : public CYourAddressDialogBase
  10918. {
  10919. protected:
  10920.     void OnListEndLabelEdit(wxListEvent& event);
  10921.     void OnListItemSelected(wxListEvent& event);
  10922.     void OnListItemActivated(wxListEvent& event);
  10923.     void OnButtonRename(wxCommandEvent& event);
  10924.     void OnButtonNew(wxCommandEvent& event);
  10925.     void OnButtonCopy(wxCommandEvent& event);
  10926.     void OnButtonOK(wxCommandEvent& event);
  10927.     void OnButtonCancel(wxCommandEvent& event);
  10928.     void OnClose(wxCloseEvent& event);
  10929. public:
  10930.     CYourAddressDialog(wxWindow* parent);
  10931.     CYourAddressDialog(wxWindow* parent, const string& strInitSelected);
  10932.     wxString GetAddress();
  10933. };
  10934. class CAddressBookDialog : public CAddressBookDialogBase
  10935. {
  10936. protected:
  10937.     void OnListEndLabelEdit(wxListEvent& event);
  10938.     void OnListItemSelected(wxListEvent& event);
  10939.     void OnListItemActivated(wxListEvent& event);
  10940.     void OnButtonEdit(wxCommandEvent& event);
  10941.     void OnButtonDelete(wxCommandEvent& event);
  10942.     void OnButtonNew(wxCommandEvent& event);
  10943.     void OnButtonCopy(wxCommandEvent& event);
  10944.     void OnButtonOK(wxCommandEvent& event);
  10945.     void OnButtonCancel(wxCommandEvent& event);
  10946.     void OnClose(wxCloseEvent& event);
  10947. public:
  10948.     CAddressBookDialog(wxWindow* parent, const wxString& strInitSelected, bool fSendingIn);
  10949.     bool fSending;
  10950.     wxString GetAddress();
  10951. };
  10952. class CProductsDialog : public CProductsDialogBase
  10953. {
  10954. protected:
  10955.     void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); }
  10956.     void OnCombobox(wxCommandEvent& event);
  10957.     void OnButtonSearch(wxCommandEvent& event);
  10958.     void OnListItemActivated(wxListEvent& event);
  10959. public:
  10960.     CProductsDialog(wxWindow* parent);
  10961.     vector<CProduct> m_vProduct;
  10962. };
  10963. class CEditProductDialog : public CEditProductDialogBase
  10964. {
  10965. protected:
  10966.     void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); }
  10967.     void OnButtonDel0(wxCommandEvent& event);
  10968.     void OnButtonDel1(wxCommandEvent& event);
  10969.     void OnButtonDel2(wxCommandEvent& event);
  10970.     void OnButtonDel3(wxCommandEvent& event);
  10971.     void OnButtonDel4(wxCommandEvent& event);
  10972.     void OnButtonDel5(wxCommandEvent& event);
  10973.     void OnButtonDel6(wxCommandEvent& event);
  10974.     void OnButtonDel7(wxCommandEvent& event);
  10975.     void OnButtonDel8(wxCommandEvent& event);
  10976.     void OnButtonDel9(wxCommandEvent& event);
  10977.     void OnButtonDel10(wxCommandEvent& event);
  10978.     void OnButtonDel11(wxCommandEvent& event);
  10979.     void OnButtonDel12(wxCommandEvent& event);
  10980.     void OnButtonDel13(wxCommandEvent& event);
  10981.     void OnButtonDel14(wxCommandEvent& event);
  10982.     void OnButtonDel15(wxCommandEvent& event);
  10983.     void OnButtonDel16(wxCommandEvent& event);
  10984.     void OnButtonDel17(wxCommandEvent& event);
  10985.     void OnButtonDel18(wxCommandEvent& event);
  10986.     void OnButtonDel19(wxCommandEvent& event);
  10987.     void OnButtonAddField(wxCommandEvent& event);
  10988.     void OnButtonSend(wxCommandEvent& event);
  10989.     void OnButtonPreview(wxCommandEvent& event);
  10990.     void OnButtonCancel(wxCommandEvent& event);
  10991. public:
  10992.     CEditProductDialog(wxWindow* parent);
  10993.     enum { FIELDS_MAX = 20 };
  10994.     wxTextCtrl* m_textCtrlLabel[FIELDS_MAX];
  10995.     wxTextCtrl* m_textCtrlField[FIELDS_MAX];
  10996.     wxButton*   m_buttonDel[FIELDS_MAX];
  10997.     void LayoutAll();
  10998.     void ShowLine(int i, bool fShow=true);
  10999.     void OnButtonDel(wxCommandEvent& event, int n);
  11000.     void SetProduct(const CProduct& productIn);
  11001.     void GetProduct(CProduct& product);
  11002. };
  11003. class CViewProductDialog : public CViewProductDialogBase
  11004. {
  11005. protected:
  11006.     void OnButtonSubmitForm(wxCommandEvent& event);
  11007.     void OnButtonCancelForm(wxCommandEvent& event);
  11008.     void OnButtonBack(wxCommandEvent& event);
  11009.     void OnButtonNext(wxCommandEvent& event);
  11010.     void OnButtonCancel(wxCommandEvent& event);
  11011. public:
  11012.     CViewProductDialog(wxWindow* parent, const CProduct& productIn);
  11013.     ~CViewProductDialog();
  11014.     CProduct product;
  11015.     enum { FIELDS_MAX = 20 };
  11016.     wxStaticText* m_staticTextLabel[FIELDS_MAX];
  11017.     wxTextCtrl*   m_textCtrlField[FIELDS_MAX];
  11018.     wxChoice*     m_choiceField[FIELDS_MAX];
  11019.     void GetOrder(CWalletTx& order);
  11020.     void UpdateProductDisplay(bool fDetails);
  11021.     void OnReply1(wxCommandEvent& event);
  11022. };
  11023. class CViewOrderDialog : public CViewOrderDialogBase
  11024. {
  11025. protected:
  11026.     void OnButtonOK(wxCommandEvent& event);
  11027. public:
  11028.     CViewOrderDialog(wxWindow* parent, CWalletTx order, bool fReceived);
  11029.     bool fReceived;
  11030. };
  11031. class CEditReviewDialog : public CEditReviewDialogBase
  11032. {
  11033. protected:
  11034.     void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); }
  11035.     void OnButtonSubmit(wxCommandEvent& event);
  11036.     void OnButtonCancel(wxCommandEvent& event);
  11037. public:
  11038.     CEditReviewDialog(wxWindow* parent);
  11039.     void GetReview(CReview& review);
  11040. };
  11041. class CGetTextFromUserDialog : public CGetTextFromUserDialogBase
  11042. {
  11043. protected:
  11044.     void OnButtonOK(wxCommandEvent& event)     { EndModal(true); }
  11045.     void OnButtonCancel(wxCommandEvent& event) { EndModal(false); }
  11046.     void OnClose(wxCloseEvent& event)          { EndModal(false); }
  11047.     void OnKeyDown(wxKeyEvent& event)
  11048.     {
  11049.         if (event.GetKeyCode() == '\r' || event.GetKeyCode() == WXK_NUMPAD_ENTER)
  11050.             EndModal(true);
  11051.         else
  11052.             HandleCtrlA(event);
  11053.     }
  11054. public:
  11055.     CGetTextFromUserDialog(wxWindow* parent,
  11056.                            const string& strCaption,
  11057.                            const string& strMessage1,
  11058.                            const string& strValue1="",
  11059.                            const string& strMessage2="",
  11060.                            const string& strValue2="") : CGetTextFromUserDialogBase(parent, wxID_ANY, strCaption)
  11061.     {
  11062.         m_staticTextMessage1->SetLabel(strMessage1);
  11063.         m_textCtrl1->SetValue(strValue1);
  11064.         if (!strMessage2.empty())
  11065.         {
  11066.             m_staticTextMessage2->Show(true);
  11067.             m_staticTextMessage2->SetLabel(strMessage2);
  11068.             m_textCtrl2->Show(true);
  11069.             m_textCtrl2->SetValue(strValue2);
  11070.             SetSize(wxDefaultCoord, 180);
  11071.         }
  11072.     }
  11073.     string GetValue()  { return (string)m_textCtrl1->GetValue(); }
  11074.     string GetValue1() { return (string)m_textCtrl1->GetValue(); }
  11075.     string GetValue2() { return (string)m_textCtrl2->GetValue(); }
  11076. };
  11077. #include <limits.h>
  11078. #include <string>
  11079. #if defined(_MSC_VER) || defined(__BORLANDC__)
  11080. typedef __int64  int64;
  11081. typedef unsigned __int64  uint64;
  11082. #else
  11083. typedef long long  int64;
  11084. typedef unsigned long long  uint64;
  11085. #endif
  11086. #if defined(_MSC_VER) && _MSC_VER < 1300
  11087. #define for  if (false) ; else for
  11088. #endif
  11089. inline int Testuint256AdHoc(vector<string> vArg);
  11090. template<unsigned int BITS>
  11091. class base_uint
  11092. {
  11093. protected:
  11094.     enum { WIDTH=BITS/32 };
  11095.     unsigned int pn[WIDTH];
  11096. public:
  11097.     bool operator!() const
  11098.     {
  11099.         for (int i = 0; i < WIDTH; i++)
  11100.             if (pn[i] != 0)
  11101.                 return false;
  11102.         return true;
  11103.     }
  11104.     const base_uint operator~() const
  11105.     {
  11106.         base_uint ret;
  11107.         for (int i = 0; i < WIDTH; i++)
  11108.             ret.pn[i] = ~pn[i];
  11109.         return ret;
  11110.     }
  11111.     const base_uint operator-() const
  11112.     {
  11113.         base_uint ret;
  11114.         for (int i = 0; i < WIDTH; i++)
  11115.             ret.pn[i] = ~pn[i];
  11116.         ret++;
  11117.         return ret;
  11118.     }
  11119.     base_uint& operator=(uint64 b)
  11120.     {
  11121.         pn[0] = (unsigned int)b;
  11122.         pn[1] = (unsigned int)(b >> 32);
  11123.         for (int i = 2; i < WIDTH; i++)
  11124.             pn[i] = 0;
  11125.         return *this;
  11126.     }
  11127.     base_uint& operator^=(const base_uint& b)
  11128.     {
  11129.         for (int i = 0; i < WIDTH; i++)
  11130.             pn[i] ^= b.pn[i];
  11131.         return *this;
  11132.     }
  11133.     base_uint& operator&=(const base_uint& b)
  11134.     {
  11135.         for (int i = 0; i < WIDTH; i++)
  11136.             pn[i] &= b.pn[i];
  11137.         return *this;
  11138.     }
  11139.     base_uint& operator|=(const base_uint& b)
  11140.     {
  11141.         for (int i = 0; i < WIDTH; i++)
  11142.             pn[i] |= b.pn[i];
  11143.         return *this;
  11144.     }
  11145.     base_uint& operator^=(uint64 b)
  11146.     {
  11147.         pn[0] ^= (unsigned int)b;
  11148.         pn[1] ^= (unsigned int)(b >> 32);
  11149.         return *this;
  11150.     }
  11151.     base_uint& operator&=(uint64 b)
  11152.     {
  11153.         pn[0] &= (unsigned int)b;
  11154.         pn[1] &= (unsigned int)(b >> 32);
  11155.         return *this;
  11156.     }
  11157.     base_uint& operator|=(uint64 b)
  11158.     {
  11159.         pn[0] |= (unsigned int)b;
  11160.         pn[1] |= (unsigned int)(b >> 32);
  11161.         return *this;
  11162.     }
  11163.     base_uint& operator<<=(unsigned int shift)
  11164.     {
  11165.         base_uint a(*this);
  11166.         for (int i = 0; i < WIDTH; i++)
  11167.             pn[i] = 0;
  11168.         int k = shift / 32;
  11169.         shift = shift % 32;
  11170.         for (int i = 0; i < WIDTH; i++)
  11171.         {
  11172.             if (i+k+1 < WIDTH && shift != 0)
  11173.                 pn[i+k+1] |= (a.pn[i] >> (32-shift));
  11174.             if (i+k < WIDTH)
  11175.                 pn[i+k] |= (a.pn[i] << shift);
  11176.         }
  11177.         return *this;
  11178.     }
  11179.     base_uint& operator>>=(unsigned int shift)
  11180.     {
  11181.         base_uint a(*this);
  11182.         for (int i = 0; i < WIDTH; i++)
  11183.             pn[i] = 0;
  11184.         int k = shift / 32;
  11185.         shift = shift % 32;
  11186.         for (int i = 0; i < WIDTH; i++)
  11187.         {
  11188.             if (i-k-1 >= 0 && shift != 0)
  11189.                 pn[i-k-1] |= (a.pn[i] << (32-shift));
  11190.             if (i-k >= 0)
  11191.                 pn[i-k] |= (a.pn[i] >> shift);
  11192.         }
  11193.         return *this;
  11194.     }
  11195.     base_uint& operator+=(const base_uint& b)
  11196.     {
  11197.         uint64 carry = 0;
  11198.         for (int i = 0; i < WIDTH; i++)
  11199.         {
  11200.             uint64 n = carry + pn[i] + b.pn[i];
  11201.             pn[i] = n & 0xffffffff;
  11202.             carry = n >> 32;
  11203.         }
  11204.         return *this;
  11205.     }
  11206.     base_uint& operator-=(const base_uint& b)
  11207.     {
  11208.         *this += -b;
  11209.         return *this;
  11210.     }
  11211.     base_uint& operator+=(uint64 b64)
  11212.     {
  11213.         base_uint b;
  11214.         b = b64;
  11215.         *this += b;
  11216.         return *this;
  11217.     }
  11218.     base_uint& operator-=(uint64 b64)
  11219.     {
  11220.         base_uint b;
  11221.         b = b64;
  11222.         *this += -b;
  11223.         return *this;
  11224.     }
  11225.     base_uint& operator++()
  11226.     {
  11227.         int i = 0;
  11228.         while (++pn[i] == 0 && i < WIDTH-1)
  11229.             i++;
  11230.         return *this;
  11231.     }
  11232.     const base_uint operator++(int)
  11233.     {
  11234.         const base_uint ret = *this;
  11235.         ++(*this);
  11236.         return ret;
  11237.     }
  11238.     base_uint& operator--()
  11239.     {
  11240.         int i = 0;
  11241.         while (--pn[i] == -1 && i < WIDTH-1)
  11242.             i++;
  11243.         return *this;
  11244.     }
  11245.     const base_uint operator--(int)
  11246.     {
  11247.         const base_uint ret = *this;
  11248.         --(*this);
  11249.         return ret;
  11250.     }
  11251.     friend inline bool operator<(const base_uint& a, const base_uint& b)
  11252.     {
  11253.         for (int i = base_uint::WIDTH-1; i >= 0; i--)
  11254.         {
  11255.             if (a.pn[i] < b.pn[i])
  11256.                 return true;
  11257.             else if (a.pn[i] > b.pn[i])
  11258.                 return false;
  11259.         }
  11260.         return false;
  11261.     }
  11262.     friend inline bool operator<=(const base_uint& a, const base_uint& b)
  11263.     {
  11264.         for (int i = base_uint::WIDTH-1; i >= 0; i--)
  11265.         {
  11266.             if (a.pn[i] < b.pn[i])
  11267.                 return true;
  11268.             else if (a.pn[i] > b.pn[i])
  11269.                 return false;
  11270.         }
  11271.         return true;
  11272.     }
  11273.     friend inline bool operator>(const base_uint& a, const base_uint& b)
  11274.     {
  11275.         for (int i = base_uint::WIDTH-1; i >= 0; i--)
  11276.         {
  11277.             if (a.pn[i] > b.pn[i])
  11278.                 return true;
  11279.             else if (a.pn[i] < b.pn[i])
  11280.                 return false;
  11281.         }
  11282.         return false;
  11283.     }
  11284.     friend inline bool operator>=(const base_uint& a, const base_uint& b)
  11285.     {
  11286.         for (int i = base_uint::WIDTH-1; i >= 0; i--)
  11287.         {
  11288.             if (a.pn[i] > b.pn[i])
  11289.                 return true;
  11290.             else if (a.pn[i] < b.pn[i])
  11291.                 return false;
  11292.         }
  11293.         return true;
  11294.     }
  11295.     friend inline bool operator==(const base_uint& a, const base_uint& b)
  11296.     {
  11297.         for (int i = 0; i < base_uint::WIDTH; i++)
  11298.             if (a.pn[i] != b.pn[i])
  11299.                 return false;
  11300.         return true;
  11301.     }
  11302.     friend inline bool operator==(const base_uint& a, uint64 b)
  11303.     {
  11304.         if (a.pn[0] != (unsigned int)b)
  11305.             return false;
  11306.         if (a.pn[1] != (unsigned int)(b >> 32))
  11307.             return false;
  11308.         for (int i = 2; i < base_uint::WIDTH; i++)
  11309.             if (a.pn[i] != 0)
  11310.                 return false;
  11311.         return true;
  11312.     }
  11313.     friend inline bool operator!=(const base_uint& a, const base_uint& b)
  11314.     {
  11315.         return (!(a == b));
  11316.     }
  11317.     friend inline bool operator!=(const base_uint& a, uint64 b)
  11318.     {
  11319.         return (!(a == b));
  11320.     }
  11321.     std::string GetHex() const
  11322.     {
  11323.         char psz[sizeof(pn)*2 + 1];
  11324.         for (int i = 0; i < sizeof(pn); i++)
  11325.             sprintf(psz + i*2, "%02x", ((unsigned char*)pn)[sizeof(pn) - i - 1]);
  11326.         return string(psz, psz + sizeof(pn)*2);
  11327.     }
  11328.     void SetHex(const std::string& str)
  11329.     {
  11330.         for (int i = 0; i < WIDTH; i++)
  11331.             pn[i] = 0;
  11332.         const char* psz = str.c_str();
  11333.         while (isspace(*psz))
  11334.             psz++;
  11335.         if (psz[0] == '0' && tolower(psz[1]) == 'x')
  11336.             psz += 2;
  11337.         while (isspace(*psz))
  11338.             psz++;
  11339.         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 };
  11340.         const char* pbegin = psz;
  11341.         while (phexdigit[*psz] || *psz == '0')
  11342.             psz++;
  11343.         psz--;
  11344.         unsigned char* p1 = (unsigned char*)pn;
  11345.         unsigned char* pend = p1 + WIDTH * 4;
  11346.         while (psz >= pbegin && p1 < pend)
  11347.         {
  11348.             *p1 = phexdigit[(unsigned char)*psz--];
  11349.             if (psz >= pbegin)
  11350.             {
  11351.                 *p1 |= (phexdigit[(unsigned char)*psz--] << 4);
  11352.                 p1++;
  11353.             }
  11354.         }
  11355.     }
  11356.     std::string ToString() const
  11357.     {
  11358.         return (GetHex());
  11359.     }
  11360.     unsigned char* begin()
  11361.     {
  11362.         return (unsigned char*)&pn[0];
  11363.     }
  11364.     unsigned char* end()
  11365.     {
  11366.         return (unsigned char*)&pn[WIDTH];
  11367.     }
  11368.     unsigned int size()
  11369.     {
  11370.         return sizeof(pn);
  11371.     }
  11372.     unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const
  11373.     {
  11374.         return sizeof(pn);
  11375.     }
  11376.     template<typename Stream>
  11377.     void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const
  11378.     {
  11379.         s.write((char*)pn, sizeof(pn));
  11380.     }
  11381.     template<typename Stream>
  11382.     void Unserialize(Stream& s, int nType=0, int nVersion=VERSION)
  11383.     {
  11384.         s.read((char*)pn, sizeof(pn));
  11385.     }
  11386.     friend class uint160;
  11387.     friend class uint256;
  11388.     friend inline int Testuint256AdHoc(vector<string> vArg);
  11389. };
  11390. typedef base_uint<160> base_uint160;
  11391. typedef base_uint<256> base_uint256;
  11392. class uint160 : public base_uint160
  11393. {
  11394. public:
  11395.     typedef base_uint160 basetype;
  11396.     uint160()
  11397.     {
  11398.     }
  11399.     uint160(const basetype& b)
  11400.     {
  11401.         for (int i = 0; i < WIDTH; i++)
  11402.             pn[i] = b.pn[i];
  11403.     }
  11404.     uint160& operator=(const basetype& b)
  11405.     {
  11406.         for (int i = 0; i < WIDTH; i++)
  11407.             pn[i] = b.pn[i];
  11408.         return *this;
  11409.     }
  11410.     uint160(uint64 b)
  11411.     {
  11412.         pn[0] = (unsigned int)b;
  11413.         pn[1] = (unsigned int)(b >> 32);
  11414.         for (int i = 2; i < WIDTH; i++)
  11415.             pn[i] = 0;
  11416.     }
  11417.     uint160& operator=(uint64 b)
  11418.     {
  11419.         pn[0] = (unsigned int)b;
  11420.         pn[1] = (unsigned int)(b >> 32);
  11421.         for (int i = 2; i < WIDTH; i++)
  11422.             pn[i] = 0;
  11423.         return *this;
  11424.     }
  11425.     explicit uint160(const std::string& str)
  11426.     {
  11427.         SetHex(str);
  11428.     }
  11429.     explicit uint160(const std::vector<unsigned char>& vch)
  11430.     {
  11431.         if (vch.size() == sizeof(pn))
  11432.             memcpy(pn, &vch[0], sizeof(pn));
  11433.         else
  11434.             *this = 0;
  11435.     }
  11436. };
  11437. inline bool operator==(const uint160& a, uint64 b)                           { return (base_uint160)a == b; }
  11438. inline bool operator!=(const uint160& a, uint64 b)                           { return (base_uint160)a != b; }
  11439. inline const uint160 operator<<(const base_uint160& a, unsigned int shift)   { return uint160(a) <<= shift; }
  11440. inline const uint160 operator>>(const base_uint160& a, unsigned int shift)   { return uint160(a) >>= shift; }
  11441. inline const uint160 operator<<(const uint160& a, unsigned int shift)        { return uint160(a) <<= shift; }
  11442. inline const uint160 operator>>(const uint160& a, unsigned int shift)        { return uint160(a) >>= shift; }
  11443. inline const uint160 operator^(const base_uint160& a, const base_uint160& b) { return uint160(a) ^= b; }
  11444. inline const uint160 operator&(const base_uint160& a, const base_uint160& b) { return uint160(a) &= b; }
  11445. inline const uint160 operator|(const base_uint160& a, const base_uint160& b) { return uint160(a) |= b; }
  11446. inline const uint160 operator+(const base_uint160& a, const base_uint160& b) { return uint160(a) += b; }
  11447. inline const uint160 operator-(const base_uint160& a, const base_uint160& b) { return uint160(a) -= b; }
  11448. inline bool operator<(const base_uint160& a, const uint160& b)          { return (base_uint160)a <  (base_uint160)b; }
  11449. inline bool operator<=(const base_uint160& a, const uint160& b)         { return (base_uint160)a <= (base_uint160)b; }
  11450. inline bool operator>(const base_uint160& a, const uint160& b)          { return (base_uint160)a >  (base_uint160)b; }
  11451. inline bool operator>=(const base_uint160& a, const uint160& b)         { return (base_uint160)a >= (base_uint160)b; }
  11452. inline bool operator==(const base_uint160& a, const uint160& b)         { return (base_uint160)a == (base_uint160)b; }
  11453. inline bool operator!=(const base_uint160& a, const uint160& b)         { return (base_uint160)a != (base_uint160)b; }
  11454. inline const uint160 operator^(const base_uint160& a, const uint160& b) { return (base_uint160)a ^  (base_uint160)b; }
  11455. inline const uint160 operator&(const base_uint160& a, const uint160& b) { return (base_uint160)a &  (base_uint160)b; }
  11456. inline const uint160 operator|(const base_uint160& a, const uint160& b) { return (base_uint160)a |  (base_uint160)b; }
  11457. inline const uint160 operator+(const base_uint160& a, const uint160& b) { return (base_uint160)a +  (base_uint160)b; }
  11458. inline const uint160 operator-(const base_uint160& a, const uint160& b) { return (base_uint160)a -  (base_uint160)b; }
  11459. inline bool operator<(const uint160& a, const base_uint160& b)          { return (base_uint160)a <  (base_uint160)b; }
  11460. inline bool operator<=(const uint160& a, const base_uint160& b)         { return (base_uint160)a <= (base_uint160)b; }
  11461. inline bool operator>(const uint160& a, const base_uint160& b)          { return (base_uint160)a >  (base_uint160)b; }
  11462. inline bool operator>=(const uint160& a, const base_uint160& b)         { return (base_uint160)a >= (base_uint160)b; }
  11463. inline bool operator==(const uint160& a, const base_uint160& b)         { return (base_uint160)a == (base_uint160)b; }
  11464. inline bool operator!=(const uint160& a, const base_uint160& b)         { return (base_uint160)a != (base_uint160)b; }
  11465. inline const uint160 operator^(const uint160& a, const base_uint160& b) { return (base_uint160)a ^  (base_uint160)b; }
  11466. inline const uint160 operator&(const uint160& a, const base_uint160& b) { return (base_uint160)a &  (base_uint160)b; }
  11467. inline const uint160 operator|(const uint160& a, const base_uint160& b) { return (base_uint160)a |  (base_uint160)b; }
  11468. inline const uint160 operator+(const uint160& a, const base_uint160& b) { return (base_uint160)a +  (base_uint160)b; }
  11469. inline const uint160 operator-(const uint160& a, const base_uint160& b) { return (base_uint160)a -  (base_uint160)b; }
  11470. inline bool operator<(const uint160& a, const uint160& b)               { return (base_uint160)a <  (base_uint160)b; }
  11471. inline bool operator<=(const uint160& a, const uint160& b)              { return (base_uint160)a <= (base_uint160)b; }
  11472. inline bool operator>(const uint160& a, const uint160& b)               { return (base_uint160)a >  (base_uint160)b; }
  11473. inline bool operator>=(const uint160& a, const uint160& b)              { return (base_uint160)a >= (base_uint160)b; }
  11474. inline bool operator==(const uint160& a, const uint160& b)              { return (base_uint160)a == (base_uint160)b; }
  11475. inline bool operator!=(const uint160& a, const uint160& b)              { return (base_uint160)a != (base_uint160)b; }
  11476. inline const uint160 operator^(const uint160& a, const uint160& b)      { return (base_uint160)a ^  (base_uint160)b; }
  11477. inline const uint160 operator&(const uint160& a, const uint160& b)      { return (base_uint160)a &  (base_uint160)b; }
  11478. inline const uint160 operator|(const uint160& a, const uint160& b)      { return (base_uint160)a |  (base_uint160)b; }
  11479. inline const uint160 operator+(const uint160& a, const uint160& b)      { return (base_uint160)a +  (base_uint160)b; }
  11480. inline const uint160 operator-(const uint160& a, const uint160& b)      { return (base_uint160)a -  (base_uint160)b; }
  11481. class uint256 : public base_uint256
  11482. {
  11483. public:
  11484.     typedef base_uint256 basetype;
  11485.     uint256()
  11486.     {
  11487.     }
  11488.     uint256(const basetype& b)
  11489.     {
  11490.         for (int i = 0; i < WIDTH; i++)
  11491.             pn[i] = b.pn[i];
  11492.     }
  11493.     uint256& operator=(const basetype& b)
  11494.     {
  11495.         for (int i = 0; i < WIDTH; i++)
  11496.             pn[i] = b.pn[i];
  11497.         return *this;
  11498.     }
  11499.     uint256(uint64 b)
  11500.     {
  11501.         pn[0] = (unsigned int)b;
  11502.         pn[1] = (unsigned int)(b >> 32);
  11503.         for (int i = 2; i < WIDTH; i++)
  11504.             pn[i] = 0;
  11505.     }
  11506.     uint256& operator=(uint64 b)
  11507.     {
  11508.         pn[0] = (unsigned int)b;
  11509.         pn[1] = (unsigned int)(b >> 32);
  11510.         for (int i = 2; i < WIDTH; i++)
  11511.             pn[i] = 0;
  11512.         return *this;
  11513.     }
  11514.     explicit uint256(const std::string& str)
  11515.     {
  11516.         SetHex(str);
  11517.     }
  11518.     explicit uint256(const std::vector<unsigned char>& vch)
  11519.     {
  11520.         if (vch.size() == sizeof(pn))
  11521.             memcpy(pn, &vch[0], sizeof(pn));
  11522.         else
  11523.             *this = 0;
  11524.     }
  11525. };
  11526. inline bool operator==(const uint256& a, uint64 b)                           { return (base_uint256)a == b; }
  11527. inline bool operator!=(const uint256& a, uint64 b)                           { return (base_uint256)a != b; }
  11528. inline const uint256 operator<<(const base_uint256& a, unsigned int shift)   { return uint256(a) <<= shift; }
  11529. inline const uint256 operator>>(const base_uint256& a, unsigned int shift)   { return uint256(a) >>= shift; }
  11530. inline const uint256 operator<<(const uint256& a, unsigned int shift)        { return uint256(a) <<= shift; }
  11531. inline const uint256 operator>>(const uint256& a, unsigned int shift)        { return uint256(a) >>= shift; }
  11532. inline const uint256 operator^(const base_uint256& a, const base_uint256& b) { return uint256(a) ^= b; }
  11533. inline const uint256 operator&(const base_uint256& a, const base_uint256& b) { return uint256(a) &= b; }
  11534. inline const uint256 operator|(const base_uint256& a, const base_uint256& b) { return uint256(a) |= b; }
  11535. inline const uint256 operator+(const base_uint256& a, const base_uint256& b) { return uint256(a) += b; }
  11536. inline const uint256 operator-(const base_uint256& a, const base_uint256& b) { return uint256(a) -= b; }
  11537. inline bool operator<(const base_uint256& a, const uint256& b)          { return (base_uint256)a <  (base_uint256)b; }
  11538. inline bool operator<=(const base_uint256& a, const uint256& b)         { return (base_uint256)a <= (base_uint256)b; }
  11539. inline bool operator>(const base_uint256& a, const uint256& b)          { return (base_uint256)a >  (base_uint256)b; }
  11540. inline bool operator>=(const base_uint256& a, const uint256& b)         { return (base_uint256)a >= (base_uint256)b; }
  11541. inline bool operator==(const base_uint256& a, const uint256& b)         { return (base_uint256)a == (base_uint256)b; }
  11542. inline bool operator!=(const base_uint256& a, const uint256& b)         { return (base_uint256)a != (base_uint256)b; }
  11543. inline const uint256 operator^(const base_uint256& a, const uint256& b) { return (base_uint256)a ^  (base_uint256)b; }
  11544. inline const uint256 operator&(const base_uint256& a, const uint256& b) { return (base_uint256)a &  (base_uint256)b; }
  11545. inline const uint256 operator|(const base_uint256& a, const uint256& b) { return (base_uint256)a |  (base_uint256)b; }
  11546. inline const uint256 operator+(const base_uint256& a, const uint256& b) { return (base_uint256)a +  (base_uint256)b; }
  11547. inline const uint256 operator-(const base_uint256& a, const uint256& b) { return (base_uint256)a -  (base_uint256)b; }
  11548. inline bool operator<(const uint256& a, const base_uint256& b)          { return (base_uint256)a <  (base_uint256)b; }
  11549. inline bool operator<=(const uint256& a, const base_uint256& b)         { return (base_uint256)a <= (base_uint256)b; }
  11550. inline bool operator>(const uint256& a, const base_uint256& b)          { return (base_uint256)a >  (base_uint256)b; }
  11551. inline bool operator>=(const uint256& a, const base_uint256& b)         { return (base_uint256)a >= (base_uint256)b; }
  11552. inline bool operator==(const uint256& a, const base_uint256& b)         { return (base_uint256)a == (base_uint256)b; }
  11553. inline bool operator!=(const uint256& a, const base_uint256& b)         { return (base_uint256)a != (base_uint256)b; }
  11554. inline const uint256 operator^(const uint256& a, const base_uint256& b) { return (base_uint256)a ^  (base_uint256)b; }
  11555. inline const uint256 operator&(const uint256& a, const base_uint256& b) { return (base_uint256)a &  (base_uint256)b; }
  11556. inline const uint256 operator|(const uint256& a, const base_uint256& b) { return (base_uint256)a |  (base_uint256)b; }
  11557. inline const uint256 operator+(const uint256& a, const base_uint256& b) { return (base_uint256)a +  (base_uint256)b; }
  11558. inline const uint256 operator-(const uint256& a, const base_uint256& b) { return (base_uint256)a -  (base_uint256)b; }
  11559. inline bool operator<(const uint256& a, const uint256& b)               { return (base_uint256)a <  (base_uint256)b; }
  11560. inline bool operator<=(const uint256& a, const uint256& b)              { return (base_uint256)a <= (base_uint256)b; }
  11561. inline bool operator>(const uint256& a, const uint256& b)               { return (base_uint256)a >  (base_uint256)b; }
  11562. inline bool operator>=(const uint256& a, const uint256& b)              { return (base_uint256)a >= (base_uint256)b; }
  11563. inline bool operator==(const uint256& a, const uint256& b)              { return (base_uint256)a == (base_uint256)b; }
  11564. inline bool operator!=(const uint256& a, const uint256& b)              { return (base_uint256)a != (base_uint256)b; }
  11565. inline const uint256 operator^(const uint256& a, const uint256& b)      { return (base_uint256)a ^  (base_uint256)b; }
  11566. inline const uint256 operator&(const uint256& a, const uint256& b)      { return (base_uint256)a &  (base_uint256)b; }
  11567. inline const uint256 operator|(const uint256& a, const uint256& b)      { return (base_uint256)a |  (base_uint256)b; }
  11568. inline const uint256 operator+(const uint256& a, const uint256& b)      { return (base_uint256)a +  (base_uint256)b; }
  11569. inline const uint256 operator-(const uint256& a, const uint256& b)      { return (base_uint256)a -  (base_uint256)b; }
  11570. inline int Testuint256AdHoc(vector<string> vArg)
  11571. {
  11572.     uint256 g(0);
  11573.     printf("%s\n", g.ToString().c_str());
  11574.     g--;  printf("g--\n");
  11575.     printf("%s\n", g.ToString().c_str());
  11576.     g--;  printf("g--\n");
  11577.     printf("%s\n", g.ToString().c_str());
  11578.     g++;  printf("g++\n");
  11579.     printf("%s\n", g.ToString().c_str());
  11580.     g++;  printf("g++\n");
  11581.     printf("%s\n", g.ToString().c_str());
  11582.     g++;  printf("g++\n");
  11583.     printf("%s\n", g.ToString().c_str());
  11584.     g++;  printf("g++\n");
  11585.     printf("%s\n", g.ToString().c_str());
  11586.     uint256 a(7);
  11587.     printf("a=7\n");
  11588.     printf("%s\n", a.ToString().c_str());
  11589.     uint256 b;
  11590.     printf("b undefined\n");
  11591.     printf("%s\n", b.ToString().c_str());
  11592.     int c = 3;
  11593.     a = c;
  11594.     a.pn[3] = 15;
  11595.     printf("%s\n", a.ToString().c_str());
  11596.     uint256 k(c);
  11597.     a = 5;
  11598.     a.pn[3] = 15;
  11599.     printf("%s\n", a.ToString().c_str());
  11600.     b = 1;
  11601.     b <<= 52;
  11602.     a |= b;
  11603.     a ^= 0x500;
  11604.     printf("a %s\n", a.ToString().c_str());
  11605.     a = a | b | (uint256)0x1000;
  11606.     printf("a %s\n", a.ToString().c_str());
  11607.     printf("b %s\n", b.ToString().c_str());
  11608.     a = 0xfffffffe;
  11609.     a.pn[4] = 9;
  11610.     printf("%s\n", a.ToString().c_str());
  11611.     a++;
  11612.     printf("%s\n", a.ToString().c_str());
  11613.     a++;
  11614.     printf("%s\n", a.ToString().c_str());
  11615.     a++;
  11616.     printf("%s\n", a.ToString().c_str());
  11617.     a++;
  11618.     printf("%s\n", a.ToString().c_str());
  11619.     a--;
  11620.     printf("%s\n", a.ToString().c_str());
  11621.     a--;
  11622.     printf("%s\n", a.ToString().c_str());
  11623.     a--;
  11624.     printf("%s\n", a.ToString().c_str());
  11625.     uint256 d = a--;
  11626.     printf("%s\n", d.ToString().c_str());
  11627.     printf("%s\n", a.ToString().c_str());
  11628.     a--;
  11629.     printf("%s\n", a.ToString().c_str());
  11630.     a--;
  11631.     printf("%s\n", a.ToString().c_str());
  11632.     d = a;
  11633.     printf("%s\n", d.ToString().c_str());
  11634.     for (int i = uint256::WIDTH-1; i >= 0; i--) printf("%08x", d.pn[i]); printf("\n");
  11635.     uint256 neg = d;
  11636.     neg = ~neg;
  11637.     printf("%s\n", neg.ToString().c_str());
  11638.     uint256 e = uint256("0xABCDEF123abcdef12345678909832180000011111111");
  11639.     printf("\n");
  11640.     printf("%s\n", e.ToString().c_str());
  11641.     printf("\n");
  11642.     uint256 x1 = uint256("0xABCDEF123abcdef12345678909832180000011111111");
  11643.     uint256 x2;
  11644.     printf("%s\n", x1.ToString().c_str());
  11645.     for (int i = 0; i < 270; i += 4)
  11646.     {
  11647.         x2 = x1 << i;
  11648.         printf("%s\n", x2.ToString().c_str());
  11649.     }
  11650.     printf("\n");
  11651.     printf("%s\n", x1.ToString().c_str());
  11652.     for (int i = 0; i < 270; i += 4)
  11653.     {
  11654.         x2 = x1;
  11655.         x2 >>= i;
  11656.         printf("%s\n", x2.ToString().c_str());
  11657.     }
  11658.     for (int i = 0; i < 100; i++)
  11659.     {
  11660.         uint256 k = (~uint256(0) >> i);
  11661.         printf("%s\n", k.ToString().c_str());
  11662.     }
  11663.     for (int i = 0; i < 100; i++)
  11664.     {
  11665.         uint256 k = (~uint256(0) << i);
  11666.         printf("%s\n", k.ToString().c_str());
  11667.     }
  11668.     return (0);
  11669. }
  11670. #include "headers.h"
  11671. bool fDebug = false;
  11672. static HANDLE* lock_cs;
  11673. void win32_locking_callback(int mode, int type, const char* file, int line)
  11674. {
  11675.     if (mode & CRYPTO_LOCK)
  11676.         WaitForSingleObject(lock_cs[type], INFINITE);
  11677.     else
  11678.         ReleaseMutex(lock_cs[type]);
  11679. }
  11680. class CInit
  11681. {
  11682. public:
  11683.     CInit()
  11684.     {
  11685.         lock_cs = (HANDLE*)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(HANDLE));
  11686.         for (int i = 0; i < CRYPTO_num_locks(); i++)
  11687.             lock_cs[i] = CreateMutex(NULL,FALSE,NULL);
  11688.         CRYPTO_set_locking_callback(win32_locking_callback);
  11689.         RAND_screen();
  11690.         RandAddSeed(true);
  11691.     }
  11692.     ~CInit()
  11693.     {
  11694.         CRYPTO_set_locking_callback(NULL);
  11695.         for (int i =0 ; i < CRYPTO_num_locks(); i++)
  11696.             CloseHandle(lock_cs[i]);
  11697.         OPENSSL_free(lock_cs);
  11698.     }
  11699. }
  11700. instance_of_cinit;
  11701. void RandAddSeed(bool fPerfmon)
  11702. {
  11703.     LARGE_INTEGER PerformanceCount;
  11704.     QueryPerformanceCounter(&PerformanceCount);
  11705.     RAND_add(&PerformanceCount, sizeof(PerformanceCount), 1.5);
  11706.     memset(&PerformanceCount, 0, sizeof(PerformanceCount));
  11707.     static int64 nLastPerfmon;
  11708.     if (fPerfmon || GetTime() > nLastPerfmon + 5 * 60)
  11709.     {
  11710.         nLastPerfmon = GetTime();
  11711.         unsigned char pdata[250000];
  11712.         memset(pdata, 0, sizeof(pdata));
  11713.         unsigned long nSize = sizeof(pdata);
  11714.         long ret = RegQueryValueEx(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize);
  11715.         RegCloseKey(HKEY_PERFORMANCE_DATA);
  11716.         if (ret == ERROR_SUCCESS)
  11717.         {
  11718.             uint256 hash;
  11719.             SHA256(pdata, nSize, (unsigned char*)&hash);
  11720.             RAND_add(&hash, sizeof(hash), min(nSize/500.0, (double)sizeof(hash)));
  11721.             hash = 0;
  11722.             memset(pdata, 0, nSize);
  11723.             printf("RandAddSeed() got %d bytes of performance data\n", nSize);
  11724.         }
  11725.     }
  11726. }
  11727. int my_snprintf(char* buffer, size_t limit, const char* format, ...)
  11728. {   if (limit == 0)
  11729.         return 0;
  11730.     va_list arg_ptr;
  11731.     va_start(arg_ptr, format);
  11732.     int ret = _vsnprintf(buffer, limit, format, arg_ptr);
  11733.     va_end(arg_ptr);
  11734.     if (ret < 0 || ret >= limit)
  11735.     {
  11736.         ret = limit - 1;
  11737.         buffer[limit-1] = 0;
  11738.     }
  11739.     return ret;
  11740. }
  11741. string strprintf(const char* format, ...)
  11742. {
  11743.     char buffer[50000];
  11744.     char* p = buffer;
  11745.     int limit = sizeof(buffer);
  11746.     int ret;
  11747.     loop
  11748.     {
  11749.         va_list arg_ptr;
  11750.         va_start(arg_ptr, format);
  11751.         ret = _vsnprintf(p, limit, format, arg_ptr);
  11752.         va_end(arg_ptr);
  11753.         if (ret >= 0 && ret < limit)
  11754.             break;
  11755.         if (p != buffer)
  11756.             delete p;
  11757.         limit *= 2;
  11758.         p = new char[limit];
  11759.         if (p == NULL)
  11760.             throw std::bad_alloc();
  11761.     }
  11762. #ifdef _MSC_VER
  11763.     if (p == buffer)
  11764.         return string(p, p+ret);
  11765. #endif
  11766.     string str(p, p+ret);
  11767.     if (p != buffer)
  11768.         delete p;
  11769.     return str;
  11770. }
  11771. bool error(const char* format, ...)
  11772. {
  11773.     char buffer[50000];
  11774.     int limit = sizeof(buffer);
  11775.     va_list arg_ptr;
  11776.     va_start(arg_ptr, format);
  11777.     int ret = _vsnprintf(buffer, limit, format, arg_ptr);
  11778.     va_end(arg_ptr);
  11779.     if (ret < 0 || ret >= limit)
  11780.     {
  11781.         ret = limit - 1;
  11782.         buffer[limit-1] = 0;
  11783.     }
  11784.     printf("ERROR: %s\n", buffer);
  11785.     return false;
  11786. }
  11787. void PrintException(std::exception* pex, const char* pszThread)
  11788. {
  11789.     char pszModule[260];
  11790.     pszModule[0] = '\0';
  11791.     GetModuleFileName(NULL, pszModule, sizeof(pszModule));
  11792.     _strlwr(pszModule);
  11793.     char pszMessage[1000];
  11794.     if (pex)
  11795.         snprintf(pszMessage, sizeof(pszMessage),
  11796.             "EXCEPTION: %s       \n%s       \n%s in %s       \n", typeid(*pex).name(), pex->what(), pszModule, pszThread);
  11797.     else
  11798.         snprintf(pszMessage, sizeof(pszMessage),
  11799.             "UNKNOWN EXCEPTION       \n%s in %s       \n", pszModule, pszThread);
  11800.     printf("\n\n************************\n%s", pszMessage);
  11801.     if (wxTheApp)
  11802.         wxMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR);
  11803.     throw;
  11804. }
  11805. void ParseString(const string& str, char c, vector<string>& v)
  11806. {
  11807.     unsigned int i1 = 0;
  11808.     unsigned int i2;
  11809.     do
  11810.     {
  11811.         i2 = str.find(c, i1);
  11812.         v.push_back(str.substr(i1, i2-i1));
  11813.         i1 = i2+1;
  11814.     }
  11815.     while (i2 != str.npos);
  11816. }
  11817. string FormatMoney(int64 n, bool fPlus)
  11818. {
  11819.     n /= CENT;
  11820.     string str = strprintf("%I64d.%02I64d", (n > 0 ? n : -n)/100, (n > 0 ? n : -n)%100);
  11821.     for (int i = 6; i < str.size(); i += 4)
  11822.         if (isdigit(str[str.size() - i - 1]))
  11823.             str.insert(str.size() - i, 1, ',');
  11824.     if (n < 0)
  11825.         str.insert((unsigned int)0, 1, '-');
  11826.     else if (fPlus && n > 0)
  11827.         str.insert((unsigned int)0, 1, '+');
  11828.     return str;
  11829. }
  11830. bool ParseMoney(const char* pszIn, int64& nRet)
  11831. {
  11832.     string strWhole;
  11833.     int64 nCents = 0;
  11834.     const char* p = pszIn;
  11835.     while (isspace(*p))
  11836.         p++;
  11837.     for (; *p; p++)
  11838.     {
  11839.         if (*p == ',' && p > pszIn && isdigit(p[-1]) && isdigit(p[1]) && isdigit(p[2]) && isdigit(p[3]) && !isdigit(p[4]))
  11840.             continue;
  11841.         if (*p == '.')
  11842.         {
  11843.             p++;
  11844.             if (!isdigit(p[0]) || !isdigit(p[1]))
  11845.                 return false;
  11846.             nCents = atoi64(p);
  11847.             if (nCents < 0 || nCents > 99)
  11848.                 return false;
  11849.             p += 2;
  11850.             break;
  11851.         }
  11852.         if (isspace(*p))
  11853.             break;
  11854.         if (!isdigit(*p))
  11855.             return false;
  11856.         strWhole.insert(strWhole.end(), *p);
  11857.     }
  11858.     for (; *p; p++)
  11859.         if (!isspace(*p))
  11860.             return false;
  11861.     if (strWhole.size() > 17)
  11862.         return false;
  11863.     int64 nWhole = atoi64(strWhole);
  11864.     int64 nValue = nWhole * 100 + nCents;
  11865.     if (nValue / 100 != nWhole)
  11866.         return false;
  11867.     nValue *= CENT;
  11868.     nRet = nValue;
  11869.     return true;
  11870. }
  11871. bool FileExists(const char* psz)
  11872. {
  11873. #ifdef WIN32
  11874.     return GetFileAttributes(psz) != -1;
  11875. #else
  11876.     return access(psz, 0) != -1;
  11877. #endif
  11878. }
  11879. int GetFilesize(FILE* file)
  11880. {
  11881.     int nSavePos = ftell(file);
  11882.     int nFilesize = -1;
  11883.     if (fseek(file, 0, SEEK_END) == 0)
  11884.         nFilesize = ftell(file);
  11885.     fseek(file, nSavePos, SEEK_SET);
  11886.     return nFilesize;
  11887. }
  11888. uint64 GetRand(uint64 nMax)
  11889. {
  11890.     if (nMax == 0)
  11891.         return 0;
  11892.     uint64 nRange = (_UI64_MAX / nMax) * nMax;
  11893.     uint64 nRand = 0;
  11894.     do
  11895.         RAND_bytes((unsigned char*)&nRand, sizeof(nRand));
  11896.     while (nRand >= nRange);
  11897.     return (nRand % nMax);
  11898. }
  11899. int64 GetTime()
  11900. {
  11901.     return time(NULL);
  11902. }
  11903. static int64 nTimeOffset = 0;
  11904. int64 GetAdjustedTime()
  11905. {
  11906.     return GetTime() + nTimeOffset;
  11907. }
  11908.  
  11909. void AddTimeData(unsigned int ip, int64 nTime)
  11910. {
  11911.     int64 nOffsetSample = nTime - GetTime();
  11912.     static set<unsigned int> setKnown;
  11913.     if (!setKnown.insert(ip).second)
  11914.         return;
  11915.     static vector<int64> vTimeOffsets;
  11916.     if (vTimeOffsets.empty())
  11917.         vTimeOffsets.push_back(0);
  11918.     vTimeOffsets.push_back(nOffsetSample);
  11919.     printf("Added time data, samples %d, ip %08x, offset %+I64d (%+I64d minutes)\n", vTimeOffsets.size(), ip, vTimeOffsets.back(), vTimeOffsets.back()/60);
  11920.     if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1)
  11921.     {
  11922.         sort(vTimeOffsets.begin(), vTimeOffsets.end());
  11923.         int64 nMedian = vTimeOffsets[vTimeOffsets.size()/2];
  11924.         nTimeOffset = nMedian;
  11925.         if ((nMedian > 0 ? nMedian : -nMedian) > 5 * 60)
  11926.         {
  11927.         }
  11928.         foreach(int64 n, vTimeOffsets)
  11929.             printf("%+I64d  ", n);
  11930.         printf("|  nTimeOffset = %+I64d  (%+I64d minutes)\n", nTimeOffset, nTimeOffset/60);
  11931.     }
  11932. }
  11933. #if defined(_MSC_VER) || defined(__BORLANDC__)
  11934. typedef __int64  int64;
  11935. typedef unsigned __int64  uint64;
  11936. #else
  11937. typedef long long  int64;
  11938. typedef unsigned long long  uint64;
  11939. #endif
  11940. #if defined(_MSC_VER) && _MSC_VER < 1300
  11941. #define for  if (false) ; else for
  11942. #endif
  11943. #ifndef _MSC_VER
  11944. #define __forceinline  inline
  11945. #endif
  11946. #define foreach             BOOST_FOREACH
  11947. #define loop                for (;;)
  11948. #define BEGIN(a)            ((char*)&(a))
  11949. #define END(a)              ((char*)&((&(a))[1]))
  11950. #define UBEGIN(a)           ((unsigned char*)&(a))
  11951. #define UEND(a)             ((unsigned char*)&((&(a))[1]))
  11952. #define ARRAYLEN(array)     (sizeof(array)/sizeof((array)[0]))
  11953. #ifdef _WINDOWS
  11954. #define printf              OutputDebugStringF
  11955. #endif
  11956. #ifdef snprintf
  11957. #undef snprintf
  11958. #endif
  11959. #define snprintf my_snprintf
  11960. #ifndef PRId64
  11961. #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MSVCRT__)
  11962. #define PRId64  "I64d"
  11963. #define PRIu64  "I64u"
  11964. #define PRIx64  "I64x"
  11965. #else
  11966. #define PRId64  "lld"
  11967. #define PRIu64  "llu"
  11968. #define PRIx64  "llx"
  11969. #endif
  11970. #endif
  11971. #define PAIRTYPE(t1, t2)    pair<t1, t2>
  11972. template<typename T>
  11973. inline T& REF(const T& val)
  11974. {
  11975.     return (T&)val;
  11976. }
  11977. extern bool fDebug;
  11978. void RandAddSeed(bool fPerfmon=false);
  11979. int my_snprintf(char* buffer, size_t limit, const char* format, ...);
  11980. string strprintf(const char* format, ...);
  11981. bool error(const char* format, ...);
  11982. void PrintException(std::exception* pex, const char* pszThread);
  11983. void ParseString(const string& str, char c, vector<string>& v);
  11984. string FormatMoney(int64 n, bool fPlus=false);
  11985. bool ParseMoney(const char* pszIn, int64& nRet);
  11986. bool FileExists(const char* psz);
  11987. int GetFilesize(FILE* file);
  11988. uint64 GetRand(uint64 nMax);
  11989. int64 GetTime();
  11990. int64 GetAdjustedTime();
  11991. void AddTimeData(unsigned int ip, int64 nTime);
  11992. class CCriticalSection
  11993. {
  11994. protected:
  11995.     CRITICAL_SECTION cs;
  11996. public:
  11997.     char* pszFile;
  11998.     int nLine;
  11999.     explicit CCriticalSection() { InitializeCriticalSection(&cs); }
  12000.     ~CCriticalSection() { DeleteCriticalSection(&cs); }
  12001.     void Enter() { EnterCriticalSection(&cs); }
  12002.     void Leave() { LeaveCriticalSection(&cs); }
  12003.     bool TryEnter() { return TryEnterCriticalSection(&cs); }
  12004.     CRITICAL_SECTION* operator&() { return &cs; }
  12005. };
  12006. class CCriticalBlock
  12007. {
  12008. protected:
  12009.     CRITICAL_SECTION* pcs;
  12010. public:
  12011.     CCriticalBlock(CRITICAL_SECTION& csIn) { pcs = &csIn; EnterCriticalSection(pcs); }
  12012.     CCriticalBlock(CCriticalSection& csIn) { pcs = &csIn; EnterCriticalSection(pcs); }
  12013.     ~CCriticalBlock() { LeaveCriticalSection(pcs); }
  12014. };
  12015. #define CRITICAL_BLOCK(cs)     \
  12016.     for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by CRITICAL_BLOCK!", !fcriticalblockonce)), fcriticalblockonce=false)  \
  12017.     for (CCriticalBlock criticalblock(cs); fcriticalblockonce && (cs.pszFile=__FILE__, cs.nLine=__LINE__, true); fcriticalblockonce=false, cs.pszFile=NULL, cs.nLine=0)
  12018. class CTryCriticalBlock
  12019. {
  12020. protected:
  12021.     CRITICAL_SECTION* pcs;
  12022. public:
  12023.     CTryCriticalBlock(CRITICAL_SECTION& csIn) { pcs = (TryEnterCriticalSection(&csIn) ? &csIn : NULL); }
  12024.     CTryCriticalBlock(CCriticalSection& csIn) { pcs = (TryEnterCriticalSection(&csIn) ? &csIn : NULL); }
  12025.     ~CTryCriticalBlock() { if (pcs) LeaveCriticalSection(pcs); }
  12026.     bool Entered() { return pcs != NULL; }
  12027. };
  12028. #define TRY_CRITICAL_BLOCK(cs)     \
  12029.     for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by TRY_CRITICAL_BLOCK!", !fcriticalblockonce)), fcriticalblockonce=false)  \
  12030.     for (CTryCriticalBlock criticalblock(cs); fcriticalblockonce && (fcriticalblockonce = criticalblock.Entered()) && (cs.pszFile=__FILE__, cs.nLine=__LINE__, true); fcriticalblockonce=false, cs.pszFile=NULL, cs.nLine=0)
  12031. inline string i64tostr(int64 n)
  12032. {
  12033.     return strprintf("%"PRId64, n);
  12034. }
  12035. inline string itostr(int n)
  12036. {
  12037.     return strprintf("%d", n);
  12038. }
  12039. inline int64 atoi64(const char* psz)
  12040. {
  12041. #ifdef _MSC_VER
  12042.     return _atoi64(psz);
  12043. #else
  12044.     return strtoll(psz, NULL, 10);
  12045. #endif
  12046. }
  12047. inline int64 atoi64(const string& str)
  12048. {
  12049. #ifdef _MSC_VER
  12050.     return _atoi64(str.c_str());
  12051. #else
  12052.     return strtoll(str.c_str(), NULL, 10);
  12053. #endif
  12054. }
  12055. inline int atoi(const string& str)
  12056. {
  12057.     return atoi(str.c_str());
  12058. }
  12059. inline int roundint(double d)
  12060. {
  12061.     return (int)(d > 0 ? d + 0.5 : d - 0.5);
  12062. }
  12063. template<typename T>
  12064. string HexStr(const T itbegin, const T itend, bool fSpaces=true)
  12065. {
  12066.     const unsigned char* pbegin = (const unsigned char*)&itbegin[0];
  12067.     const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]);
  12068.     string str;
  12069.     for (const unsigned char* p = pbegin; p != pend; p++)
  12070.         str += strprintf((fSpaces && p != pend-1 ? "%02x " : "%02x"), *p);
  12071.     return str;
  12072. }
  12073. template<typename T>
  12074. string HexNumStr(const T itbegin, const T itend, bool f0x=true)
  12075. {
  12076.     const unsigned char* pbegin = (const unsigned char*)&itbegin[0];
  12077.     const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]);
  12078.     string str = (f0x ? "0x" : "");
  12079.     for (const unsigned char* p = pend-1; p >= pbegin; p--)
  12080.         str += strprintf("%02X", *p);
  12081.     return str;
  12082. }
  12083. template<typename T>
  12084. void PrintHex(const T pbegin, const T pend, const char* pszFormat="%s", bool fSpaces=true)
  12085. {
  12086.     printf(pszFormat, HexStr(pbegin, pend, fSpaces).c_str());
  12087. }
  12088. inline int OutputDebugStringF(const char* pszFormat, ...)
  12089. {
  12090. #ifdef __WXDEBUG__
  12091.     FILE* fileout = fopen("debug.log", "a");
  12092.     if (fileout)
  12093.     {
  12094.         va_list arg_ptr;
  12095.         va_start(arg_ptr, pszFormat);
  12096.         vfprintf(fileout, pszFormat, arg_ptr);
  12097.         va_end(arg_ptr);
  12098.         fclose(fileout);
  12099.     }
  12100.     static CCriticalSection cs_OutputDebugStringF;
  12101.     CRITICAL_BLOCK(cs_OutputDebugStringF)
  12102.     {
  12103.         static char pszBuffer[50000];
  12104.         static char* pend;
  12105.         if (pend == NULL)
  12106.             pend = pszBuffer;
  12107.         va_list arg_ptr;
  12108.         va_start(arg_ptr, pszFormat);
  12109.         int limit = END(pszBuffer) - pend - 2;
  12110.         int ret = _vsnprintf(pend, limit, pszFormat, arg_ptr);
  12111.         va_end(arg_ptr);
  12112.         if (ret < 0 || ret >= limit)
  12113.         {
  12114.             pend = END(pszBuffer) - 2;
  12115.             *pend++ = '\n';
  12116.         }
  12117.         else
  12118.             pend += ret;
  12119.         *pend = '\0';
  12120.         char* p1 = pszBuffer;
  12121.         char* p2;
  12122.         while (p2 = strchr(p1, '\n'))
  12123.         {
  12124.             p2++;
  12125.             char c = *p2;
  12126.             *p2 = '\0';
  12127.             OutputDebugString(p1);
  12128.             *p2 = c;
  12129.             p1 = p2;
  12130.         }
  12131.         if (p1 != pszBuffer)
  12132.             memmove(pszBuffer, p1, pend - p1 + 1);
  12133.         pend -= (p1 - pszBuffer);
  12134.         return ret;
  12135.     }
  12136. #endif
  12137.     if (!wxTheApp)
  12138.     {
  12139.         va_list arg_ptr;
  12140.         va_start(arg_ptr, pszFormat);
  12141.         vprintf(pszFormat, arg_ptr);
  12142.         va_end(arg_ptr);
  12143.     }
  12144.     return 0;
  12145. }
  12146. inline void heapchk()
  12147. {
  12148.     if (_heapchk() != _HEAPOK)
  12149.         DebugBreak();
  12150. }
  12151. #define IMPLEMENT_RANDOMIZE_STACK(ThreadFn)                         \
  12152.     {                                                               \
  12153.         static char nLoops;                                         \
  12154.         if (nLoops <= 0)                                            \
  12155.             nLoops = GetRand(50) + 1;                               \
  12156.         if (nLoops-- > 1)                                           \
  12157.         {                                                           \
  12158.             ThreadFn;                                               \
  12159.             return;                                                 \
  12160.         }                                                           \
  12161.     }
  12162. #define CATCH_PRINT_EXCEPTION(pszFn)     \
  12163.     catch (std::exception& e) {          \
  12164.         PrintException(&e, (pszFn));     \
  12165.     } catch (...) {                      \
  12166.         PrintException(NULL, (pszFn));   \
  12167.     }
  12168. template<typename T1>
  12169. inline uint256 Hash(const T1 pbegin, const T1 pend)
  12170. {
  12171.     uint256 hash1;
  12172.     SHA256((unsigned char*)&pbegin[0], (pend - pbegin) * sizeof(pbegin[0]), (unsigned char*)&hash1);
  12173.     uint256 hash2;
  12174.     SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
  12175.     return hash2;
  12176. }
  12177. template<typename T1, typename T2>
  12178. inline uint256 Hash(const T1 p1begin, const T1 p1end,
  12179.                     const T2 p2begin, const T2 p2end)
  12180. {
  12181.     uint256 hash1;
  12182.     SHA256_CTX ctx;
  12183.     SHA256_Init(&ctx);
  12184.     SHA256_Update(&ctx, (unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0]));
  12185.     SHA256_Update(&ctx, (unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0]));
  12186.     SHA256_Final((unsigned char*)&hash1, &ctx);
  12187.     uint256 hash2;
  12188.     SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
  12189.     return hash2;
  12190. }
  12191. template<typename T1, typename T2, typename T3>
  12192. inline uint256 Hash(const T1 p1begin, const T1 p1end,
  12193.                     const T2 p2begin, const T2 p2end,
  12194.                     const T3 p3begin, const T3 p3end)
  12195. {
  12196.     uint256 hash1;
  12197.     SHA256_CTX ctx;
  12198.     SHA256_Init(&ctx);
  12199.     SHA256_Update(&ctx, (unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0]));
  12200.     SHA256_Update(&ctx, (unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0]));
  12201.     SHA256_Update(&ctx, (unsigned char*)&p3begin[0], (p3end - p3begin) * sizeof(p3begin[0]));
  12202.     SHA256_Final((unsigned char*)&hash1, &ctx);
  12203.     uint256 hash2;
  12204.     SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
  12205.     return hash2;
  12206. }
  12207. template<typename T>
  12208. uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=VERSION)
  12209. {
  12210.     CDataStream ss(nType, nVersion);
  12211.     ss.reserve(10000);
  12212.     ss << obj;
  12213.     return Hash(ss.begin(), ss.end());
  12214. }
  12215. inline uint160 Hash160(const vector<unsigned char>& vch)
  12216. {
  12217.     uint256 hash1;
  12218.     SHA256(&vch[0], vch.size(), (unsigned char*)&hash1);
  12219.     uint160 hash2;
  12220.     RIPEMD160((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
  12221.     return hash2;
  12222. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement