begin integration with bitcoin upstream
authorWladimir J. van der Laan <laanwj@gmail.com>
Sat, 14 May 2011 08:31:46 +0000 (10:31 +0200)
committerWladimir J. van der Laan <laanwj@gmail.com>
Sat, 14 May 2011 08:31:46 +0000 (10:31 +0200)
38 files changed:
bitcoin.pro
gui/bitcoin.qrc [moved from bitcoin.qrc with 100% similarity]
gui/forms/aboutdialog.ui [moved from aboutdialog.ui with 97% similarity]
gui/forms/addressbookdialog.ui [moved from addressbookdialog.ui with 100% similarity]
gui/forms/editaddressdialog.ui [moved from editaddressdialog.ui with 100% similarity]
gui/forms/sendcoinsdialog.ui [moved from sendcoinsdialog.ui with 98% similarity]
gui/include/aboutdialog.h [moved from aboutdialog.h with 100% similarity]
gui/include/addressbookdialog.h [moved from addressbookdialog.h with 100% similarity]
gui/include/addresstablemodel.h [moved from addresstablemodel.h with 100% similarity]
gui/include/bitcoinaddressvalidator.h [moved from bitcoinaddressvalidator.h with 94% similarity]
gui/include/bitcoingui.h [moved from bitcoingui.h with 100% similarity]
gui/include/editaddressdialog.h [moved from editaddressdialog.h with 100% similarity]
gui/include/mainoptionspage.h [moved from mainoptionspage.h with 100% similarity]
gui/include/optionsdialog.h [moved from optionsdialog.h with 100% similarity]
gui/include/sendcoinsdialog.h [moved from sendcoinsdialog.h with 100% similarity]
gui/include/transactiontablemodel.h [moved from transactiontablemodel.h with 100% similarity]
gui/res/icons/address-book.png [moved from res/icons/address-book.png with 100% similarity]
gui/res/icons/bitcoin.png [moved from res/icons/bitcoin.png with 100% similarity]
gui/res/icons/quit.png [moved from res/icons/quit.png with 100% similarity]
gui/res/icons/send.png [moved from res/icons/send.png with 100% similarity]
gui/res/icons/toolbar.png [moved from res/icons/toolbar.png with 100% similarity]
gui/res/images/about.png [moved from res/images/about.png with 100% similarity]
gui/src/aboutdialog.cpp [moved from aboutdialog.cpp with 100% similarity]
gui/src/addressbookdialog.cpp [moved from addressbookdialog.cpp with 100% similarity]
gui/src/addresstablemodel.cpp [moved from addresstablemodel.cpp with 100% similarity]
gui/src/bitcoin.cpp [moved from bitcoin.cpp with 100% similarity]
gui/src/bitcoinaddressvalidator.cpp [moved from bitcoinaddressvalidator.cpp with 100% similarity]
gui/src/bitcoingui.cpp [moved from bitcoingui.cpp with 100% similarity]
gui/src/editaddressdialog.cpp [moved from editaddressdialog.cpp with 100% similarity]
gui/src/mainoptionspage.cpp [moved from mainoptionspage.cpp with 100% similarity]
gui/src/optionsdialog.cpp [moved from optionsdialog.cpp with 100% similarity]
gui/src/sendcoinsdialog.cpp [moved from sendcoinsdialog.cpp with 100% similarity]
gui/src/transactiontablemodel.cpp [moved from transactiontablemodel.cpp with 100% similarity]
lib/include/base58.h [new file with mode: 0644]
lib/include/bignum.h [new file with mode: 0644]
lib/include/serialize.h [new file with mode: 0644]
lib/include/uint256.h [new file with mode: 0644]
lib/include/util.h [new file with mode: 0644]

index b34f562..88b92bc 100644 (file)
@@ -1,39 +1,40 @@
-######################################################################
-# Automatically generated by qmake (2.01a) Sat May 7 20:45:42 2011
-######################################################################
-
 TEMPLATE = app
-TARGET = 
+TARGET =
 DEPENDPATH += .
-INCLUDEPATH += .
+INCLUDEPATH += gui/include lib/include
 
 # Input
-HEADERS += bitcoingui.h \
-    transactiontablemodel.h \
-    addresstablemodel.h \
-    optionsdialog.h \
-    mainoptionspage.h \
-    sendcoinsdialog.h \
-    addressbookdialog.h \
-    aboutdialog.h \
-    editaddressdialog.h \
-    bitcoinaddressvalidator.h
-SOURCES += bitcoin.cpp bitcoingui.cpp \
-    transactiontablemodel.cpp \
-    addresstablemodel.cpp \
-    optionsdialog.cpp \
-    mainoptionspage.cpp \
-    sendcoinsdialog.cpp \
-    addressbookdialog.cpp \
-    aboutdialog.cpp \
-    editaddressdialog.cpp \
-    bitcoinaddressvalidator.cpp
+HEADERS += gui/include/bitcoingui.h \
+    gui/include/transactiontablemodel.h \
+    gui/include/addresstablemodel.h \
+    gui/include/optionsdialog.h \
+    gui/include/mainoptionspage.h \
+    gui/include/sendcoinsdialog.h \
+    gui/include/addressbookdialog.h \
+    gui/include/aboutdialog.h \
+    gui/include/editaddressdialog.h \
+    gui/include/bitcoinaddressvalidator.h \
+    lib/include/base58.h \
+    lib/include/bignum.h \
+    lib/include/util.h \
+    lib/include/uint256.h \
+    lib/include/serialize.h
+SOURCES += gui/src/bitcoin.cpp gui/src/bitcoingui.cpp \
+    gui/src/transactiontablemodel.cpp \
+    gui/src/addresstablemodel.cpp \
+    gui/src/optionsdialog.cpp \
+    gui/src/mainoptionspage.cpp \
+    gui/src/sendcoinsdialog.cpp \
+    gui/src/addressbookdialog.cpp \
+    gui/src/aboutdialog.cpp \
+    gui/src/editaddressdialog.cpp \
+    gui/src/bitcoinaddressvalidator.cpp
 
 RESOURCES += \
-    bitcoin.qrc
+    gui/bitcoin.qrc
 
 FORMS += \
-    sendcoinsdialog.ui \
-    addressbookdialog.ui \
-    aboutdialog.ui \
-    editaddressdialog.ui
+    gui/forms/sendcoinsdialog.ui \
+    gui/forms/addressbookdialog.ui \
+    gui/forms/aboutdialog.ui \
+    gui/forms/editaddressdialog.ui
similarity index 100%
rename from bitcoin.qrc
rename to gui/bitcoin.qrc
similarity index 97%
rename from aboutdialog.ui
rename to gui/forms/aboutdialog.ui
index 17a15dd..88668d4 100644 (file)
@@ -26,7 +26,7 @@
       <string/>
      </property>
      <property name="pixmap">
-      <pixmap resource="bitcoin.qrc">:/images/about</pixmap>
+      <pixmap resource="../bitcoin.qrc">:/images/about</pixmap>
      </property>
     </widget>
    </item>
@@ -123,7 +123,7 @@ This product includes software developed by the OpenSSL Project for use in the O
   </layout>
  </widget>
  <resources>
-  <include location="bitcoin.qrc"/>
+  <include location="../bitcoin.qrc"/>
  </resources>
  <connections>
   <connection>
similarity index 98%
rename from sendcoinsdialog.ui
rename to gui/forms/sendcoinsdialog.ui
index f14ec2a..31a0b99 100644 (file)
         <string>&amp;Send</string>
        </property>
        <property name="icon">
-        <iconset resource="bitcoin.qrc">
+        <iconset resource="../bitcoin.qrc">
          <normaloff>:/icons/send</normaloff>:/icons/send</iconset>
        </property>
       </widget>
   </layout>
  </widget>
  <resources>
-  <include location="bitcoin.qrc"/>
+  <include location="../bitcoin.qrc"/>
  </resources>
  <connections>
   <connection>
similarity index 100%
rename from aboutdialog.h
rename to gui/include/aboutdialog.h
similarity index 94%
rename from bitcoinaddressvalidator.h
rename to gui/include/bitcoinaddressvalidator.h
index f6a2ac0..8b57a24 100644 (file)
@@ -3,6 +3,8 @@
 
 #include <QRegExpValidator>
 
+#include <base58.h>
+
 class BitcoinAddressValidator : public QRegExpValidator
 {
     Q_OBJECT
similarity index 100%
rename from bitcoingui.h
rename to gui/include/bitcoingui.h
similarity index 100%
rename from optionsdialog.h
rename to gui/include/optionsdialog.h
similarity index 100%
rename from res/icons/quit.png
rename to gui/res/icons/quit.png
similarity index 100%
rename from res/icons/send.png
rename to gui/res/icons/send.png
similarity index 100%
rename from aboutdialog.cpp
rename to gui/src/aboutdialog.cpp
similarity index 100%
rename from bitcoin.cpp
rename to gui/src/bitcoin.cpp
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..7acdf63ae3773579f5e35c6f400c47ad3413dc08
--- /dev/null
@@ -0,0 +1,208 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Distributed under the MIT/X11 software license, see the accompanying
+// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+
+
+//
+// Why base-58 instead of standard base-64 encoding?
+// - Don't want 0OIl characters that look the same in some fonts and
+//      could be used to create visually identical looking account numbers.
+// - A std::string with non-alphanumeric characters is not as easily accepted as an account number.
+// - E-mail usually won't line-break if there's no punctuation to break at.
+// - Doubleclicking selects the whole number as one word if it's all alphanumeric.
+//
+#ifndef BITCOIN_BASE58_H
+#define BITCOIN_BASE58_H
+
+#include <string>
+#include <vector>
+#include "bignum.h"
+
+static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
+
+
+inline std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend)
+{
+    CAutoBN_CTX pctx;
+    CBigNum bn58 = 58;
+    CBigNum bn0 = 0;
+
+    // Convert big endian data to little endian
+    // Extra zero at the end make sure bignum will interpret as a positive number
+    std::vector<unsigned char> vchTmp(pend-pbegin+1, 0);
+    reverse_copy(pbegin, pend, vchTmp.begin());
+
+    // Convert little endian data to bignum
+    CBigNum bn;
+    bn.setvch(vchTmp);
+
+    // Convert bignum to std::string
+    std::string str;
+    str.reserve((pend - pbegin) * 138 / 100 + 1);
+    CBigNum dv;
+    CBigNum rem;
+    while (bn > bn0)
+    {
+        if (!BN_div(&dv, &rem, &bn, &bn58, pctx))
+            throw bignum_error("EncodeBase58 : BN_div failed");
+        bn = dv;
+        unsigned int c = rem.getulong();
+        str += pszBase58[c];
+    }
+
+    // Leading zeroes encoded as base58 zeros
+    for (const unsigned char* p = pbegin; p < pend && *p == 0; p++)
+        str += pszBase58[0];
+
+    // Convert little endian std::string to big endian
+    reverse(str.begin(), str.end());
+    return str;
+}
+
+inline std::string EncodeBase58(const std::vector<unsigned char>& vch)
+{
+    return EncodeBase58(&vch[0], &vch[0] + vch.size());
+}
+
+inline bool DecodeBase58(const char* psz, std::vector<unsigned char>& vchRet)
+{
+    CAutoBN_CTX pctx;
+    vchRet.clear();
+    CBigNum bn58 = 58;
+    CBigNum bn = 0;
+    CBigNum bnChar;
+    while (isspace(*psz))
+        psz++;
+
+    // Convert big endian std::string to bignum
+    for (const char* p = psz; *p; p++)
+    {
+        const char* p1 = strchr(pszBase58, *p);
+        if (p1 == NULL)
+        {
+            while (isspace(*p))
+                p++;
+            if (*p != '\0')
+                return false;
+            break;
+        }
+        bnChar.setulong(p1 - pszBase58);
+        if (!BN_mul(&bn, &bn, &bn58, pctx))
+            throw bignum_error("DecodeBase58 : BN_mul failed");
+        bn += bnChar;
+    }
+
+    // Get bignum as little endian data
+    std::vector<unsigned char> vchTmp = bn.getvch();
+
+    // Trim off sign byte if present
+    if (vchTmp.size() >= 2 && vchTmp.end()[-1] == 0 && vchTmp.end()[-2] >= 0x80)
+        vchTmp.erase(vchTmp.end()-1);
+
+    // Restore leading zeros
+    int nLeadingZeros = 0;
+    for (const char* p = psz; *p == pszBase58[0]; p++)
+        nLeadingZeros++;
+    vchRet.assign(nLeadingZeros + vchTmp.size(), 0);
+
+    // Convert little endian data to big endian
+    reverse_copy(vchTmp.begin(), vchTmp.end(), vchRet.end() - vchTmp.size());
+    return true;
+}
+
+inline bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet)
+{
+    return DecodeBase58(str.c_str(), vchRet);
+}
+
+
+
+
+
+inline std::string EncodeBase58Check(const std::vector<unsigned char>& vchIn)
+{
+    // add 4-byte hash check to the end
+    std::vector<unsigned char> vch(vchIn);
+    uint256 hash = Hash(vch.begin(), vch.end());
+    vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4);
+    return EncodeBase58(vch);
+}
+
+inline bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet)
+{
+    if (!DecodeBase58(psz, vchRet))
+        return false;
+    if (vchRet.size() < 4)
+    {
+        vchRet.clear();
+        return false;
+    }
+    uint256 hash = Hash(vchRet.begin(), vchRet.end()-4);
+    if (memcmp(&hash, &vchRet.end()[-4], 4) != 0)
+    {
+        vchRet.clear();
+        return false;
+    }
+    vchRet.resize(vchRet.size()-4);
+    return true;
+}
+
+inline bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet)
+{
+    return DecodeBase58Check(str.c_str(), vchRet);
+}
+
+
+
+
+
+
+#define ADDRESSVERSION   ((unsigned char)(fTestNet ? 111 : 0))
+
+inline std::string Hash160ToAddress(uint160 hash160)
+{
+    // add 1-byte version number to the front
+    std::vector<unsigned char> vch(1, ADDRESSVERSION);
+    vch.insert(vch.end(), UBEGIN(hash160), UEND(hash160));
+    return EncodeBase58Check(vch);
+}
+
+inline bool AddressToHash160(const char* psz, uint160& hash160Ret)
+{
+    std::vector<unsigned char> vch;
+    if (!DecodeBase58Check(psz, vch))
+        return false;
+    if (vch.empty())
+        return false;
+    unsigned char nVersion = vch[0];
+    if (vch.size() != sizeof(hash160Ret) + 1)
+        return false;
+    memcpy(&hash160Ret, &vch[1], sizeof(hash160Ret));
+    return (nVersion <= ADDRESSVERSION);
+}
+
+inline bool AddressToHash160(const std::string& str, uint160& hash160Ret)
+{
+    return AddressToHash160(str.c_str(), hash160Ret);
+}
+
+inline bool IsValidBitcoinAddress(const char* psz)
+{
+    uint160 hash160;
+    return AddressToHash160(psz, hash160);
+}
+
+inline bool IsValidBitcoinAddress(const std::string& str)
+{
+    return IsValidBitcoinAddress(str.c_str());
+}
+
+
+
+
+inline std::string PubKeyToAddress(const std::vector<unsigned char>& vchPubKey)
+{
+    return Hash160ToAddress(Hash160(vchPubKey));
+}
+
+#endif
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..e353532963d0ec9a4c8e47b2b43edd4b8c5c802d
--- /dev/null
@@ -0,0 +1,537 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Distributed under the MIT/X11 software license, see the accompanying
+// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+#ifndef BITCOIN_BIGNUM_H
+#define BITCOIN_BIGNUM_H
+
+#include <stdexcept>
+#include <vector>
+#include <openssl/bn.h>
+#include <util.h>
+
+
+
+
+
+class bignum_error : public std::runtime_error
+{
+public:
+    explicit bignum_error(const std::string& str) : std::runtime_error(str) {}
+};
+
+
+
+class CAutoBN_CTX
+{
+protected:
+    BN_CTX* pctx;
+    BN_CTX* operator=(BN_CTX* pnew) { return pctx = pnew; }
+
+public:
+    CAutoBN_CTX()
+    {
+        pctx = BN_CTX_new();
+        if (pctx == NULL)
+            throw bignum_error("CAutoBN_CTX : BN_CTX_new() returned NULL");
+    }
+
+    ~CAutoBN_CTX()
+    {
+        if (pctx != NULL)
+            BN_CTX_free(pctx);
+    }
+
+    operator BN_CTX*() { return pctx; }
+    BN_CTX& operator*() { return *pctx; }
+    BN_CTX** operator&() { return &pctx; }
+    bool operator!() { return (pctx == NULL); }
+};
+
+
+
+class CBigNum : public BIGNUM
+{
+public:
+    CBigNum()
+    {
+        BN_init(this);
+    }
+
+    CBigNum(const CBigNum& b)
+    {
+        BN_init(this);
+        if (!BN_copy(this, &b))
+        {
+            BN_clear_free(this);
+            throw bignum_error("CBigNum::CBigNum(const CBigNum&) : BN_copy failed");
+        }
+    }
+
+    CBigNum& operator=(const CBigNum& b)
+    {
+        if (!BN_copy(this, &b))
+            throw bignum_error("CBigNum::operator= : BN_copy failed");
+        return (*this);
+    }
+
+    ~CBigNum()
+    {
+        BN_clear_free(this);
+    }
+
+    CBigNum(char n)             { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
+    CBigNum(short n)            { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
+    CBigNum(int n)              { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
+    CBigNum(long n)             { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
+    CBigNum(int64 n)            { BN_init(this); setint64(n); }
+    CBigNum(unsigned char n)    { BN_init(this); setulong(n); }
+    CBigNum(unsigned short n)   { BN_init(this); setulong(n); }
+    CBigNum(unsigned int n)     { BN_init(this); setulong(n); }
+    CBigNum(unsigned long n)    { BN_init(this); setulong(n); }
+    CBigNum(uint64 n)           { BN_init(this); setuint64(n); }
+    explicit CBigNum(uint256 n) { BN_init(this); setuint256(n); }
+
+    explicit CBigNum(const std::vector<unsigned char>& vch)
+    {
+        BN_init(this);
+        setvch(vch);
+    }
+
+    void setulong(unsigned long n)
+    {
+        if (!BN_set_word(this, n))
+            throw bignum_error("CBigNum conversion from unsigned long : BN_set_word failed");
+    }
+
+    unsigned long getulong() const
+    {
+        return BN_get_word(this);
+    }
+
+    unsigned int getuint() const
+    {
+        return BN_get_word(this);
+    }
+
+    int getint() const
+    {
+        unsigned long n = BN_get_word(this);
+        if (!BN_is_negative(this))
+            return (n > INT_MAX ? INT_MAX : n);
+        else
+            return (n > INT_MAX ? INT_MIN : -(int)n);
+    }
+
+    void setint64(int64 n)
+    {
+        unsigned char pch[sizeof(n) + 6];
+        unsigned char* p = pch + 4;
+        bool fNegative = false;
+        if (n < (int64)0)
+        {
+            n = -n;
+            fNegative = true;
+        }
+        bool fLeadingZeroes = true;
+        for (int i = 0; i < 8; i++)
+        {
+            unsigned char c = (n >> 56) & 0xff;
+            n <<= 8;
+            if (fLeadingZeroes)
+            {
+                if (c == 0)
+                    continue;
+                if (c & 0x80)
+                    *p++ = (fNegative ? 0x80 : 0);
+                else if (fNegative)
+                    c |= 0x80;
+                fLeadingZeroes = false;
+            }
+            *p++ = c;
+        }
+        unsigned int nSize = p - (pch + 4);
+        pch[0] = (nSize >> 24) & 0xff;
+        pch[1] = (nSize >> 16) & 0xff;
+        pch[2] = (nSize >> 8) & 0xff;
+        pch[3] = (nSize) & 0xff;
+        BN_mpi2bn(pch, p - pch, this);
+    }
+
+    void setuint64(uint64 n)
+    {
+        unsigned char pch[sizeof(n) + 6];
+        unsigned char* p = pch + 4;
+        bool fLeadingZeroes = true;
+        for (int i = 0; i < 8; i++)
+        {
+            unsigned char c = (n >> 56) & 0xff;
+            n <<= 8;
+            if (fLeadingZeroes)
+            {
+                if (c == 0)
+                    continue;
+                if (c & 0x80)
+                    *p++ = 0;
+                fLeadingZeroes = false;
+            }
+            *p++ = c;
+        }
+        unsigned int nSize = p - (pch + 4);
+        pch[0] = (nSize >> 24) & 0xff;
+        pch[1] = (nSize >> 16) & 0xff;
+        pch[2] = (nSize >> 8) & 0xff;
+        pch[3] = (nSize) & 0xff;
+        BN_mpi2bn(pch, p - pch, this);
+    }
+
+    void setuint256(uint256 n)
+    {
+        unsigned char pch[sizeof(n) + 6];
+        unsigned char* p = pch + 4;
+        bool fLeadingZeroes = true;
+        unsigned char* pbegin = (unsigned char*)&n;
+        unsigned char* psrc = pbegin + sizeof(n);
+        while (psrc != pbegin)
+        {
+            unsigned char c = *(--psrc);
+            if (fLeadingZeroes)
+            {
+                if (c == 0)
+                    continue;
+                if (c & 0x80)
+                    *p++ = 0;
+                fLeadingZeroes = false;
+            }
+            *p++ = c;
+        }
+        unsigned int nSize = p - (pch + 4);
+        pch[0] = (nSize >> 24) & 0xff;
+        pch[1] = (nSize >> 16) & 0xff;
+        pch[2] = (nSize >> 8) & 0xff;
+        pch[3] = (nSize >> 0) & 0xff;
+        BN_mpi2bn(pch, p - pch, this);
+    }
+
+    uint256 getuint256()
+    {
+        unsigned int nSize = BN_bn2mpi(this, NULL);
+        if (nSize < 4)
+            return 0;
+        std::vector<unsigned char> vch(nSize);
+        BN_bn2mpi(this, &vch[0]);
+        if (vch.size() > 4)
+            vch[4] &= 0x7f;
+        uint256 n = 0;
+        for (int i = 0, j = vch.size()-1; i < sizeof(n) && j >= 4; i++, j--)
+            ((unsigned char*)&n)[i] = vch[j];
+        return n;
+    }
+
+    void setvch(const std::vector<unsigned char>& vch)
+    {
+        std::vector<unsigned char> vch2(vch.size() + 4);
+        unsigned int nSize = vch.size();
+        vch2[0] = (nSize >> 24) & 0xff;
+        vch2[1] = (nSize >> 16) & 0xff;
+        vch2[2] = (nSize >> 8) & 0xff;
+        vch2[3] = (nSize >> 0) & 0xff;
+        reverse_copy(vch.begin(), vch.end(), vch2.begin() + 4);
+        BN_mpi2bn(&vch2[0], vch2.size(), this);
+    }
+
+    std::vector<unsigned char> getvch() const
+    {
+        unsigned int nSize = BN_bn2mpi(this, NULL);
+        if (nSize < 4)
+            return std::vector<unsigned char>();
+        std::vector<unsigned char> vch(nSize);
+        BN_bn2mpi(this, &vch[0]);
+        vch.erase(vch.begin(), vch.begin() + 4);
+        reverse(vch.begin(), vch.end());
+        return vch;
+    }
+
+    CBigNum& SetCompact(unsigned int nCompact)
+    {
+        unsigned int nSize = nCompact >> 24;
+        std::vector<unsigned char> vch(4 + nSize);
+        vch[3] = nSize;
+        if (nSize >= 1) vch[4] = (nCompact >> 16) & 0xff;
+        if (nSize >= 2) vch[5] = (nCompact >> 8) & 0xff;
+        if (nSize >= 3) vch[6] = (nCompact >> 0) & 0xff;
+        BN_mpi2bn(&vch[0], vch.size(), this);
+        return *this;
+    }
+
+    unsigned int GetCompact() const
+    {
+        unsigned int nSize = BN_bn2mpi(this, NULL);
+        std::vector<unsigned char> vch(nSize);
+        nSize -= 4;
+        BN_bn2mpi(this, &vch[0]);
+        unsigned int nCompact = nSize << 24;
+        if (nSize >= 1) nCompact |= (vch[4] << 16);
+        if (nSize >= 2) nCompact |= (vch[5] << 8);
+        if (nSize >= 3) nCompact |= (vch[6] << 0);
+        return nCompact;
+    }
+
+    void SetHex(const std::string& str)
+    {
+        // skip 0x
+        const char* psz = str.c_str();
+        while (isspace(*psz))
+            psz++;
+        bool fNegative = false;
+        if (*psz == '-')
+        {
+            fNegative = true;
+            psz++;
+        }
+        if (psz[0] == '0' && tolower(psz[1]) == 'x')
+            psz += 2;
+        while (isspace(*psz))
+            psz++;
+
+        // hex string to bignum
+        static char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 };
+        *this = 0;
+        while (isxdigit(*psz))
+        {
+            *this <<= 4;
+            int n = phexdigit[*psz++];
+            *this += n;
+        }
+        if (fNegative)
+            *this = 0 - *this;
+    }
+
+    std::string ToString(int nBase=10) const
+    {
+        CAutoBN_CTX pctx;
+        CBigNum bnBase = nBase;
+        CBigNum bn0 = 0;
+        string str;
+        CBigNum bn = *this;
+        BN_set_negative(&bn, false);
+        CBigNum dv;
+        CBigNum rem;
+        if (BN_cmp(&bn, &bn0) == 0)
+            return "0";
+        while (BN_cmp(&bn, &bn0) > 0)
+        {
+            if (!BN_div(&dv, &rem, &bn, &bnBase, pctx))
+                throw bignum_error("CBigNum::ToString() : BN_div failed");
+            bn = dv;
+            unsigned int c = rem.getulong();
+            str += "0123456789abcdef"[c];
+        }
+        if (BN_is_negative(this))
+            str += "-";
+        reverse(str.begin(), str.end());
+        return str;
+    }
+
+    std::string GetHex() const
+    {
+        return ToString(16);
+    }
+
+    unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const
+    {
+        return ::GetSerializeSize(getvch(), nType, nVersion);
+    }
+
+    template<typename Stream>
+    void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const
+    {
+        ::Serialize(s, getvch(), nType, nVersion);
+    }
+
+    template<typename Stream>
+    void Unserialize(Stream& s, int nType=0, int nVersion=VERSION)
+    {
+        vector<unsigned char> vch;
+        ::Unserialize(s, vch, nType, nVersion);
+        setvch(vch);
+    }
+
+
+    bool operator!() const
+    {
+        return BN_is_zero(this);
+    }
+
+    CBigNum& operator+=(const CBigNum& b)
+    {
+        if (!BN_add(this, this, &b))
+            throw bignum_error("CBigNum::operator+= : BN_add failed");
+        return *this;
+    }
+
+    CBigNum& operator-=(const CBigNum& b)
+    {
+        *this = *this - b;
+        return *this;
+    }
+
+    CBigNum& operator*=(const CBigNum& b)
+    {
+        CAutoBN_CTX pctx;
+        if (!BN_mul(this, this, &b, pctx))
+            throw bignum_error("CBigNum::operator*= : BN_mul failed");
+        return *this;
+    }
+
+    CBigNum& operator/=(const CBigNum& b)
+    {
+        *this = *this / b;
+        return *this;
+    }
+
+    CBigNum& operator%=(const CBigNum& b)
+    {
+        *this = *this % b;
+        return *this;
+    }
+
+    CBigNum& operator<<=(unsigned int shift)
+    {
+        if (!BN_lshift(this, this, shift))
+            throw bignum_error("CBigNum:operator<<= : BN_lshift failed");
+        return *this;
+    }
+
+    CBigNum& operator>>=(unsigned int shift)
+    {
+        // Note: BN_rshift segfaults on 64-bit if 2^shift is greater than the number
+        //   if built on ubuntu 9.04 or 9.10, probably depends on version of openssl
+        CBigNum a = 1;
+        a <<= shift;
+        if (BN_cmp(&a, this) > 0)
+        {
+            *this = 0;
+            return *this;
+        }
+
+        if (!BN_rshift(this, this, shift))
+            throw bignum_error("CBigNum:operator>>= : BN_rshift failed");
+        return *this;
+    }
+
+
+    CBigNum& operator++()
+    {
+        // prefix operator
+        if (!BN_add(this, this, BN_value_one()))
+            throw bignum_error("CBigNum::operator++ : BN_add failed");
+        return *this;
+    }
+
+    const CBigNum operator++(int)
+    {
+        // postfix operator
+        const CBigNum ret = *this;
+        ++(*this);
+        return ret;
+    }
+
+    CBigNum& operator--()
+    {
+        // prefix operator
+        CBigNum r;
+        if (!BN_sub(&r, this, BN_value_one()))
+            throw bignum_error("CBigNum::operator-- : BN_sub failed");
+        *this = r;
+        return *this;
+    }
+
+    const CBigNum operator--(int)
+    {
+        // postfix operator
+        const CBigNum ret = *this;
+        --(*this);
+        return ret;
+    }
+
+
+    friend inline const CBigNum operator-(const CBigNum& a, const CBigNum& b);
+    friend inline const CBigNum operator/(const CBigNum& a, const CBigNum& b);
+    friend inline const CBigNum operator%(const CBigNum& a, const CBigNum& b);
+};
+
+
+
+inline const CBigNum operator+(const CBigNum& a, const CBigNum& b)
+{
+    CBigNum r;
+    if (!BN_add(&r, &a, &b))
+        throw bignum_error("CBigNum::operator+ : BN_add failed");
+    return r;
+}
+
+inline const CBigNum operator-(const CBigNum& a, const CBigNum& b)
+{
+    CBigNum r;
+    if (!BN_sub(&r, &a, &b))
+        throw bignum_error("CBigNum::operator- : BN_sub failed");
+    return r;
+}
+
+inline const CBigNum operator-(const CBigNum& a)
+{
+    CBigNum r(a);
+    BN_set_negative(&r, !BN_is_negative(&r));
+    return r;
+}
+
+inline const CBigNum operator*(const CBigNum& a, const CBigNum& b)
+{
+    CAutoBN_CTX pctx;
+    CBigNum r;
+    if (!BN_mul(&r, &a, &b, pctx))
+        throw bignum_error("CBigNum::operator* : BN_mul failed");
+    return r;
+}
+
+inline const CBigNum operator/(const CBigNum& a, const CBigNum& b)
+{
+    CAutoBN_CTX pctx;
+    CBigNum r;
+    if (!BN_div(&r, NULL, &a, &b, pctx))
+        throw bignum_error("CBigNum::operator/ : BN_div failed");
+    return r;
+}
+
+inline const CBigNum operator%(const CBigNum& a, const CBigNum& b)
+{
+    CAutoBN_CTX pctx;
+    CBigNum r;
+    if (!BN_mod(&r, &a, &b, pctx))
+        throw bignum_error("CBigNum::operator% : BN_div failed");
+    return r;
+}
+
+inline const CBigNum operator<<(const CBigNum& a, unsigned int shift)
+{
+    CBigNum r;
+    if (!BN_lshift(&r, &a, shift))
+        throw bignum_error("CBigNum:operator<< : BN_lshift failed");
+    return r;
+}
+
+inline const CBigNum operator>>(const CBigNum& a, unsigned int shift)
+{
+    CBigNum r = a;
+    r >>= shift;
+    return r;
+}
+
+inline bool operator==(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) == 0); }
+inline bool operator!=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) != 0); }
+inline bool operator<=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) <= 0); }
+inline bool operator>=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) >= 0); }
+inline bool operator<(const CBigNum& a, const CBigNum& b)  { return (BN_cmp(&a, &b) < 0); }
+inline bool operator>(const CBigNum& a, const CBigNum& b)  { return (BN_cmp(&a, &b) > 0); }
+
+#endif
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..f810b339c25c35eed6056bec778e68f9a4e0bb0f
--- /dev/null
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Distributed under the MIT/X11 software license, see the accompanying
+// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+#ifndef BITCOIN_SERIALIZE_H
+#define BITCOIN_SERIALIZE_H
+
+#include <string>
+#include <vector>
+#include <map>
+#include <set>
+#include <cassert>
+
+#include <boost/type_traits/is_fundamental.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/tuple/tuple_comparison.hpp>
+#include <boost/tuple/tuple_io.hpp>
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+typedef __int64  int64;
+typedef unsigned __int64  uint64;
+#else
+typedef long long  int64;
+typedef unsigned long long  uint64;
+#endif
+#if defined(_MSC_VER) && _MSC_VER < 1300
+#define for  if (false) ; else for
+#endif
+class CScript;
+class CDataStream;
+class CAutoFile;
+static const unsigned int MAX_SIZE = 0x02000000;
+
+static const int VERSION = 32200;
+static const char* pszSubVer = "";
+static const bool VERSION_IS_BETA = true;
+
+
+
+
+
+
+/////////////////////////////////////////////////////////////////
+//
+// Templates for serializing to anything that looks like a stream,
+// i.e. anything that supports .read(char*, int) and .write(char*, int)
+//
+
+enum
+{
+    // primary actions
+    SER_NETWORK         = (1 << 0),
+    SER_DISK            = (1 << 1),
+    SER_GETHASH         = (1 << 2),
+
+    // modifiers
+    SER_SKIPSIG         = (1 << 16),
+    SER_BLOCKHEADERONLY = (1 << 17),
+};
+
+#define IMPLEMENT_SERIALIZE(statements)    \
+    unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const  \
+    {                                           \
+        CSerActionGetSerializeSize ser_action;  \
+        const bool fGetSize = true;             \
+        const bool fWrite = false;              \
+        const bool fRead = false;               \
+        unsigned int nSerSize = 0;              \
+        ser_streamplaceholder s;                \
+        s.nType = nType;                        \
+        s.nVersion = nVersion;                  \
+        {statements}                            \
+        return nSerSize;                        \
+    }                                           \
+    template<typename Stream>                   \
+    void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const  \
+    {                                           \
+        CSerActionSerialize ser_action;         \
+        const bool fGetSize = false;            \
+        const bool fWrite = true;               \
+        const bool fRead = false;               \
+        unsigned int nSerSize = 0;              \
+        {statements}                            \
+    }                                           \
+    template<typename Stream>                   \
+    void Unserialize(Stream& s, int nType=0, int nVersion=VERSION)  \
+    {                                           \
+        CSerActionUnserialize ser_action;       \
+        const bool fGetSize = false;            \
+        const bool fWrite = false;              \
+        const bool fRead = true;                \
+        unsigned int nSerSize = 0;              \
+        {statements}                            \
+    }
+
+#define READWRITE(obj)      (nSerSize += ::SerReadWrite(s, (obj), nType, nVersion, ser_action))
+
+
+
+
+
+
+//
+// Basic types
+//
+#define WRITEDATA(s, obj)   s.write((char*)&(obj), sizeof(obj))
+#define READDATA(s, obj)    s.read((char*)&(obj), sizeof(obj))
+
+inline unsigned int GetSerializeSize(char a,           int, int=0) { return sizeof(a); }
+inline unsigned int GetSerializeSize(signed char a,    int, int=0) { return sizeof(a); }
+inline unsigned int GetSerializeSize(unsigned char a,  int, int=0) { return sizeof(a); }
+inline unsigned int GetSerializeSize(signed short a,   int, int=0) { return sizeof(a); }
+inline unsigned int GetSerializeSize(unsigned short a, int, int=0) { return sizeof(a); }
+inline unsigned int GetSerializeSize(signed int a,     int, int=0) { return sizeof(a); }
+inline unsigned int GetSerializeSize(unsigned int a,   int, int=0) { return sizeof(a); }
+inline unsigned int GetSerializeSize(signed long a,    int, int=0) { return sizeof(a); }
+inline unsigned int GetSerializeSize(unsigned long a,  int, int=0) { return sizeof(a); }
+inline unsigned int GetSerializeSize(int64 a,          int, int=0) { return sizeof(a); }
+inline unsigned int GetSerializeSize(uint64 a,         int, int=0) { return sizeof(a); }
+inline unsigned int GetSerializeSize(float a,          int, int=0) { return sizeof(a); }
+inline unsigned int GetSerializeSize(double a,         int, int=0) { return sizeof(a); }
+
+template<typename Stream> inline void Serialize(Stream& s, char a,           int, int=0) { WRITEDATA(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, signed char a,    int, int=0) { WRITEDATA(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, unsigned char a,  int, int=0) { WRITEDATA(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, signed short a,   int, int=0) { WRITEDATA(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, unsigned short a, int, int=0) { WRITEDATA(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, signed int a,     int, int=0) { WRITEDATA(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, unsigned int a,   int, int=0) { WRITEDATA(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, signed long a,    int, int=0) { WRITEDATA(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, unsigned long a,  int, int=0) { WRITEDATA(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, int64 a,          int, int=0) { WRITEDATA(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, uint64 a,         int, int=0) { WRITEDATA(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, float a,          int, int=0) { WRITEDATA(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, double a,         int, int=0) { WRITEDATA(s, a); }
+
+template<typename Stream> inline void Unserialize(Stream& s, char& a,           int, int=0) { READDATA(s, a); }
+template<typename Stream> inline void Unserialize(Stream& s, signed char& a,    int, int=0) { READDATA(s, a); }
+template<typename Stream> inline void Unserialize(Stream& s, unsigned char& a,  int, int=0) { READDATA(s, a); }
+template<typename Stream> inline void Unserialize(Stream& s, signed short& a,   int, int=0) { READDATA(s, a); }
+template<typename Stream> inline void Unserialize(Stream& s, unsigned short& a, int, int=0) { READDATA(s, a); }
+template<typename Stream> inline void Unserialize(Stream& s, signed int& a,     int, int=0) { READDATA(s, a); }
+template<typename Stream> inline void Unserialize(Stream& s, unsigned int& a,   int, int=0) { READDATA(s, a); }
+template<typename Stream> inline void Unserialize(Stream& s, signed long& a,    int, int=0) { READDATA(s, a); }
+template<typename Stream> inline void Unserialize(Stream& s, unsigned long& a,  int, int=0) { READDATA(s, a); }
+template<typename Stream> inline void Unserialize(Stream& s, int64& a,          int, int=0) { READDATA(s, a); }
+template<typename Stream> inline void Unserialize(Stream& s, uint64& a,         int, int=0) { READDATA(s, a); }
+template<typename Stream> inline void Unserialize(Stream& s, float& a,          int, int=0) { READDATA(s, a); }
+template<typename Stream> inline void Unserialize(Stream& s, double& a,         int, int=0) { READDATA(s, a); }
+
+inline unsigned int GetSerializeSize(bool a, int, int=0)                          { return sizeof(char); }
+template<typename Stream> inline void Serialize(Stream& s, bool a, int, int=0)    { char f=a; WRITEDATA(s, f); }
+template<typename Stream> inline void Unserialize(Stream& s, bool& a, int, int=0) { char f; READDATA(s, f); a=f; }
+
+
+
+
+
+
+//
+// Compact size
+//  size <  253        -- 1 byte
+//  size <= USHRT_MAX  -- 3 bytes  (253 + 2 bytes)
+//  size <= UINT_MAX   -- 5 bytes  (254 + 4 bytes)
+//  size >  UINT_MAX   -- 9 bytes  (255 + 8 bytes)
+//
+inline unsigned int GetSizeOfCompactSize(uint64 nSize)
+{
+    if (nSize < 253)             return sizeof(unsigned char);
+    else if (nSize <= USHRT_MAX) return sizeof(unsigned char) + sizeof(unsigned short);
+    else if (nSize <= UINT_MAX)  return sizeof(unsigned char) + sizeof(unsigned int);
+    else                         return sizeof(unsigned char) + sizeof(uint64);
+}
+
+template<typename Stream>
+void WriteCompactSize(Stream& os, uint64 nSize)
+{
+    if (nSize < 253)
+    {
+        unsigned char chSize = nSize;
+        WRITEDATA(os, chSize);
+    }
+    else if (nSize <= USHRT_MAX)
+    {
+        unsigned char chSize = 253;
+        unsigned short xSize = nSize;
+        WRITEDATA(os, chSize);
+        WRITEDATA(os, xSize);
+    }
+    else if (nSize <= UINT_MAX)
+    {
+        unsigned char chSize = 254;
+        unsigned int xSize = nSize;
+        WRITEDATA(os, chSize);
+        WRITEDATA(os, xSize);
+    }
+    else
+    {
+        unsigned char chSize = 255;
+        uint64 xSize = nSize;
+        WRITEDATA(os, chSize);
+        WRITEDATA(os, xSize);
+    }
+    return;
+}
+
+template<typename Stream>
+uint64 ReadCompactSize(Stream& is)
+{
+    unsigned char chSize;
+    READDATA(is, chSize);
+    uint64 nSizeRet = 0;
+    if (chSize < 253)
+    {
+        nSizeRet = chSize;
+    }
+    else if (chSize == 253)
+    {
+        unsigned short xSize;
+        READDATA(is, xSize);
+        nSizeRet = xSize;
+    }
+    else if (chSize == 254)
+    {
+        unsigned int xSize;
+        READDATA(is, xSize);
+        nSizeRet = xSize;
+    }
+    else
+    {
+        uint64 xSize;
+        READDATA(is, xSize);
+        nSizeRet = xSize;
+    }
+    if (nSizeRet > (uint64)MAX_SIZE)
+        throw std::ios_base::failure("ReadCompactSize() : size too large");
+    return nSizeRet;
+}
+
+
+
+//
+// Wrapper for serializing arrays and POD
+// There's a clever template way to make arrays serialize normally, but MSVC6 doesn't support it
+//
+#define FLATDATA(obj)   REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj)))
+class CFlatData
+{
+protected:
+    char* pbegin;
+    char* pend;
+public:
+    CFlatData(void* pbeginIn, void* pendIn) : pbegin((char*)pbeginIn), pend((char*)pendIn) { }
+    char* begin() { return pbegin; }
+    const char* begin() const { return pbegin; }
+    char* end() { return pend; }
+    const char* end() const { return pend; }
+
+    unsigned int GetSerializeSize(int, int=0) const
+    {
+        return pend - pbegin;
+    }
+
+    template<typename Stream>
+    void Serialize(Stream& s, int, int=0) const
+    {
+        s.write(pbegin, pend - pbegin);
+    }
+
+    template<typename Stream>
+    void Unserialize(Stream& s, int, int=0)
+    {
+        s.read(pbegin, pend - pbegin);
+    }
+};
+
+
+
+//
+// string stored as a fixed length field
+//
+template<std::size_t LEN>
+class CFixedFieldString
+{
+protected:
+    const std::string* pcstr;
+    std::string* pstr;
+public:
+    explicit CFixedFieldString(const std::string& str) : pcstr(&str), pstr(NULL) { }
+    explicit CFixedFieldString(std::string& str) : pcstr(&str), pstr(&str) { }
+
+    unsigned int GetSerializeSize(int, int=0) const
+    {
+        return LEN;
+    }
+
+    template<typename Stream>
+    void Serialize(Stream& s, int, int=0) const
+    {
+        char pszBuf[LEN];
+        strncpy(pszBuf, pcstr->c_str(), LEN);
+        s.write(pszBuf, LEN);
+    }
+
+    template<typename Stream>
+    void Unserialize(Stream& s, int, int=0)
+    {
+        if (pstr == NULL)
+            throw std::ios_base::failure("CFixedFieldString::Unserialize : trying to unserialize to const string");
+        char pszBuf[LEN+1];
+        s.read(pszBuf, LEN);
+        pszBuf[LEN] = '\0';
+        *pstr = pszBuf;
+    }
+};
+
+
+
+
+
+//
+// Forward declarations
+//
+
+// string
+template<typename C> unsigned int GetSerializeSize(const std::basic_string<C>& str, int, int=0);
+template<typename Stream, typename C> void Serialize(Stream& os, const std::basic_string<C>& str, int, int=0);
+template<typename Stream, typename C> void Unserialize(Stream& is, std::basic_string<C>& str, int, int=0);
+
+// vector
+template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&);
+template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&);
+template<typename T, typename A> inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion=VERSION);
+template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&);
+template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&);
+template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion=VERSION);
+template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&);
+template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&);
+template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion=VERSION);
+
+// others derived from vector
+extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion=VERSION);
+template<typename Stream> void Serialize(Stream& os, const CScript& v, int nType, int nVersion=VERSION);
+template<typename Stream> void Unserialize(Stream& is, CScript& v, int nType, int nVersion=VERSION);
+
+// pair
+template<typename K, typename T> unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion=VERSION);
+template<typename Stream, typename K, typename T> void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion=VERSION);
+template<typename Stream, typename K, typename T> void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion=VERSION);
+
+// 3 tuple
+template<typename T0, typename T1, typename T2> unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2>& item, int nType, int nVersion=VERSION);
+template<typename Stream, typename T0, typename T1, typename T2> void Serialize(Stream& os, const boost::tuple<T0, T1, T2>& item, int nType, int nVersion=VERSION);
+template<typename Stream, typename T0, typename T1, typename T2> void Unserialize(Stream& is, boost::tuple<T0, T1, T2>& item, int nType, int nVersion=VERSION);
+
+// 4 tuple
+template<typename T0, typename T1, typename T2, typename T3> unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion=VERSION);
+template<typename Stream, typename T0, typename T1, typename T2, typename T3> void Serialize(Stream& os, const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion=VERSION);
+template<typename Stream, typename T0, typename T1, typename T2, typename T3> void Unserialize(Stream& is, boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion=VERSION);
+
+// map
+template<typename K, typename T, typename Pred, typename A> unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion=VERSION);
+template<typename Stream, typename K, typename T, typename Pred, typename A> void Serialize(Stream& os, const std::map<K, T, Pred, A>& m, int nType, int nVersion=VERSION);
+template<typename Stream, typename K, typename T, typename Pred, typename A> void Unserialize(Stream& is, std::map<K, T, Pred, A>& m, int nType, int nVersion=VERSION);
+
+// set
+template<typename K, typename Pred, typename A> unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion=VERSION);
+template<typename Stream, typename K, typename Pred, typename A> void Serialize(Stream& os, const std::set<K, Pred, A>& m, int nType, int nVersion=VERSION);
+template<typename Stream, typename K, typename Pred, typename A> void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion=VERSION);
+
+
+
+
+
+//
+// If none of the specialized versions above matched, default to calling member function.
+// "int nType" is changed to "long nType" to keep from getting an ambiguous overload error.
+// The compiler will only cast int to long if none of the other templates matched.
+// Thanks to Boost serialization for this idea.
+//
+template<typename T>
+inline unsigned int GetSerializeSize(const T& a, long nType, int nVersion=VERSION)
+{
+    return a.GetSerializeSize((int)nType, nVersion);
+}
+
+template<typename Stream, typename T>
+inline void Serialize(Stream& os, const T& a, long nType, int nVersion=VERSION)
+{
+    a.Serialize(os, (int)nType, nVersion);
+}
+
+template<typename Stream, typename T>
+inline void Unserialize(Stream& is, T& a, long nType, int nVersion=VERSION)
+{
+    a.Unserialize(is, (int)nType, nVersion);
+}
+
+
+
+
+
+//
+// string
+//
+template<typename C>
+unsigned int GetSerializeSize(const std::basic_string<C>& str, int, int)
+{
+    return GetSizeOfCompactSize(str.size()) + str.size() * sizeof(str[0]);
+}
+
+template<typename Stream, typename C>
+void Serialize(Stream& os, const std::basic_string<C>& str, int, int)
+{
+    WriteCompactSize(os, str.size());
+    if (!str.empty())
+        os.write((char*)&str[0], str.size() * sizeof(str[0]));
+}
+
+template<typename Stream, typename C>
+void Unserialize(Stream& is, std::basic_string<C>& str, int, int)
+{
+    unsigned int nSize = ReadCompactSize(is);
+    str.resize(nSize);
+    if (nSize != 0)
+        is.read((char*)&str[0], nSize * sizeof(str[0]));
+}
+
+
+
+//
+// vector
+//
+template<typename T, typename A>
+unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&)
+{
+    return (GetSizeOfCompactSize(v.size()) + v.size() * sizeof(T));
+}
+
+template<typename T, typename A>
+unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&)
+{
+    unsigned int nSize = GetSizeOfCompactSize(v.size());
+    for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
+        nSize += GetSerializeSize((*vi), nType, nVersion);
+    return nSize;
+}
+
+template<typename T, typename A>
+inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion)
+{
+    return GetSerializeSize_impl(v, nType, nVersion, boost::is_fundamental<T>());
+}
+
+
+template<typename Stream, typename T, typename A>
+void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&)
+{
+    WriteCompactSize(os, v.size());
+    if (!v.empty())
+        os.write((char*)&v[0], v.size() * sizeof(T));
+}
+
+template<typename Stream, typename T, typename A>
+void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&)
+{
+    WriteCompactSize(os, v.size());
+    for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
+        ::Serialize(os, (*vi), nType, nVersion);
+}
+
+template<typename Stream, typename T, typename A>
+inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion)
+{
+    Serialize_impl(os, v, nType, nVersion, boost::is_fundamental<T>());
+}
+
+
+template<typename Stream, typename T, typename A>
+void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&)
+{
+    //unsigned int nSize = ReadCompactSize(is);
+    //v.resize(nSize);
+    //is.read((char*)&v[0], nSize * sizeof(T));
+
+    // Limit size per read so bogus size value won't cause out of memory
+    v.clear();
+    unsigned int nSize = ReadCompactSize(is);
+    unsigned int i = 0;
+    while (i < nSize)
+    {
+        unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
+        v.resize(i + blk);
+        is.read((char*)&v[i], blk * sizeof(T));
+        i += blk;
+    }
+}
+
+template<typename Stream, typename T, typename A>
+void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&)
+{
+    //unsigned int nSize = ReadCompactSize(is);
+    //v.resize(nSize);
+    //for (std::vector<T, A>::iterator vi = v.begin(); vi != v.end(); ++vi)
+    //    Unserialize(is, (*vi), nType, nVersion);
+
+    v.clear();
+    unsigned int nSize = ReadCompactSize(is);
+    unsigned int i = 0;
+    unsigned int nMid = 0;
+    while (nMid < nSize)
+    {
+        nMid += 5000000 / sizeof(T);
+        if (nMid > nSize)
+            nMid = nSize;
+        v.resize(nMid);
+        for (; i < nMid; i++)
+            Unserialize(is, v[i], nType, nVersion);
+    }
+}
+
+template<typename Stream, typename T, typename A>
+inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion)
+{
+    Unserialize_impl(is, v, nType, nVersion, boost::is_fundamental<T>());
+}
+
+
+
+//
+// others derived from vector
+//
+inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion)
+{
+    return GetSerializeSize((const std::vector<unsigned char>&)v, nType, nVersion);
+}
+
+template<typename Stream>
+void Serialize(Stream& os, const CScript& v, int nType, int nVersion)
+{
+    Serialize(os, (const std::vector<unsigned char>&)v, nType, nVersion);
+}
+
+template<typename Stream>
+void Unserialize(Stream& is, CScript& v, int nType, int nVersion)
+{
+    Unserialize(is, (std::vector<unsigned char>&)v, nType, nVersion);
+}
+
+
+
+//
+// pair
+//
+template<typename K, typename T>
+unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion)
+{
+    return GetSerializeSize(item.first, nType, nVersion) + GetSerializeSize(item.second, nType, nVersion);
+}
+
+template<typename Stream, typename K, typename T>
+void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion)
+{
+    Serialize(os, item.first, nType, nVersion);
+    Serialize(os, item.second, nType, nVersion);
+}
+
+template<typename Stream, typename K, typename T>
+void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion)
+{
+    Unserialize(is, item.first, nType, nVersion);
+    Unserialize(is, item.second, nType, nVersion);
+}
+
+
+
+//
+// 3 tuple
+//
+template<typename T0, typename T1, typename T2>
+unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2>& item, int nType, int nVersion)
+{
+    unsigned int nSize = 0;
+    nSize += GetSerializeSize(boost::get<0>(item), nType, nVersion);
+    nSize += GetSerializeSize(boost::get<1>(item), nType, nVersion);
+    nSize += GetSerializeSize(boost::get<2>(item), nType, nVersion);
+    return nSize;
+}
+
+template<typename Stream, typename T0, typename T1, typename T2>
+void Serialize(Stream& os, const boost::tuple<T0, T1, T2>& item, int nType, int nVersion)
+{
+    Serialize(os, boost::get<0>(item), nType, nVersion);
+    Serialize(os, boost::get<1>(item), nType, nVersion);
+    Serialize(os, boost::get<2>(item), nType, nVersion);
+}
+
+template<typename Stream, typename T0, typename T1, typename T2>
+void Unserialize(Stream& is, boost::tuple<T0, T1, T2>& item, int nType, int nVersion)
+{
+    Unserialize(is, boost::get<0>(item), nType, nVersion);
+    Unserialize(is, boost::get<1>(item), nType, nVersion);
+    Unserialize(is, boost::get<2>(item), nType, nVersion);
+}
+
+
+
+//
+// 4 tuple
+//
+template<typename T0, typename T1, typename T2, typename T3>
+unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion)
+{
+    unsigned int nSize = 0;
+    nSize += GetSerializeSize(boost::get<0>(item), nType, nVersion);
+    nSize += GetSerializeSize(boost::get<1>(item), nType, nVersion);
+    nSize += GetSerializeSize(boost::get<2>(item), nType, nVersion);
+    nSize += GetSerializeSize(boost::get<3>(item), nType, nVersion);
+    return nSize;
+}
+
+template<typename Stream, typename T0, typename T1, typename T2, typename T3>
+void Serialize(Stream& os, const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion)
+{
+    Serialize(os, boost::get<0>(item), nType, nVersion);
+    Serialize(os, boost::get<1>(item), nType, nVersion);
+    Serialize(os, boost::get<2>(item), nType, nVersion);
+    Serialize(os, boost::get<3>(item), nType, nVersion);
+}
+
+template<typename Stream, typename T0, typename T1, typename T2, typename T3>
+void Unserialize(Stream& is, boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion)
+{
+    Unserialize(is, boost::get<0>(item), nType, nVersion);
+    Unserialize(is, boost::get<1>(item), nType, nVersion);
+    Unserialize(is, boost::get<2>(item), nType, nVersion);
+    Unserialize(is, boost::get<3>(item), nType, nVersion);
+}
+
+
+
+//
+// map
+//
+template<typename K, typename T, typename Pred, typename A>
+unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion)
+{
+    unsigned int nSize = GetSizeOfCompactSize(m.size());
+    for (typename std::map<K, T, Pred, A>::const_iterator mi = m.begin(); mi != m.end(); ++mi)
+        nSize += GetSerializeSize((*mi), nType, nVersion);
+    return nSize;
+}
+
+template<typename Stream, typename K, typename T, typename Pred, typename A>
+void Serialize(Stream& os, const std::map<K, T, Pred, A>& m, int nType, int nVersion)
+{
+    WriteCompactSize(os, m.size());
+    for (typename std::map<K, T, Pred, A>::const_iterator mi = m.begin(); mi != m.end(); ++mi)
+        Serialize(os, (*mi), nType, nVersion);
+}
+
+template<typename Stream, typename K, typename T, typename Pred, typename A>
+void Unserialize(Stream& is, std::map<K, T, Pred, A>& m, int nType, int nVersion)
+{
+    m.clear();
+    unsigned int nSize = ReadCompactSize(is);
+    typename std::map<K, T, Pred, A>::iterator mi = m.begin();
+    for (unsigned int i = 0; i < nSize; i++)
+    {
+        std::pair<K, T> item;
+        Unserialize(is, item, nType, nVersion);
+        mi = m.insert(mi, item);
+    }
+}
+
+
+
+//
+// set
+//
+template<typename K, typename Pred, typename A>
+unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion)
+{
+    unsigned int nSize = GetSizeOfCompactSize(m.size());
+    for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it)
+        nSize += GetSerializeSize((*it), nType, nVersion);
+    return nSize;
+}
+
+template<typename Stream, typename K, typename Pred, typename A>
+void Serialize(Stream& os, const std::set<K, Pred, A>& m, int nType, int nVersion)
+{
+    WriteCompactSize(os, m.size());
+    for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it)
+        Serialize(os, (*it), nType, nVersion);
+}
+
+template<typename Stream, typename K, typename Pred, typename A>
+void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion)
+{
+    m.clear();
+    unsigned int nSize = ReadCompactSize(is);
+    typename std::set<K, Pred, A>::iterator it = m.begin();
+    for (unsigned int i = 0; i < nSize; i++)
+    {
+        K key;
+        Unserialize(is, key, nType, nVersion);
+        it = m.insert(it, key);
+    }
+}
+
+
+
+//
+// Support for IMPLEMENT_SERIALIZE and READWRITE macro
+//
+class CSerActionGetSerializeSize { };
+class CSerActionSerialize { };
+class CSerActionUnserialize { };
+
+template<typename Stream, typename T>
+inline unsigned int SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionGetSerializeSize ser_action)
+{
+    return ::GetSerializeSize(obj, nType, nVersion);
+}
+
+template<typename Stream, typename T>
+inline unsigned int SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionSerialize ser_action)
+{
+    ::Serialize(s, obj, nType, nVersion);
+    return 0;
+}
+
+template<typename Stream, typename T>
+inline unsigned int SerReadWrite(Stream& s, T& obj, int nType, int nVersion, CSerActionUnserialize ser_action)
+{
+    ::Unserialize(s, obj, nType, nVersion);
+    return 0;
+}
+
+struct ser_streamplaceholder
+{
+    int nType;
+    int nVersion;
+};
+
+
+
+
+
+
+
+
+
+//
+// Allocator that clears its contents before deletion
+//
+template<typename T>
+struct secure_allocator : public std::allocator<T>
+{
+    // MSVC8 default copy constructor is broken
+    typedef std::allocator<T> base;
+    typedef typename base::size_type size_type;
+    typedef typename base::difference_type  difference_type;
+    typedef typename base::pointer pointer;
+    typedef typename base::const_pointer const_pointer;
+    typedef typename base::reference reference;
+    typedef typename base::const_reference const_reference;
+    typedef typename base::value_type value_type;
+    secure_allocator() throw() {}
+    secure_allocator(const secure_allocator& a) throw() : base(a) {}
+    template <typename U>
+    secure_allocator(const secure_allocator<U>& a) throw() : base(a) {}
+    ~secure_allocator() throw() {}
+    template<typename _Other> struct rebind
+    { typedef secure_allocator<_Other> other; };
+
+    void deallocate(T* p, std::size_t n)
+    {
+        if (p != NULL)
+            memset(p, 0, sizeof(T) * n);
+        std::allocator<T>::deallocate(p, n);
+    }
+};
+
+
+
+//
+// Double ended buffer combining vector and stream-like interfaces.
+// >> and << read and write unformatted data using the above serialization templates.
+// Fills with data in linear time; some stringstream implementations take N^2 time.
+//
+class CDataStream
+{
+protected:
+    typedef std::vector<char, secure_allocator<char> > vector_type;
+    vector_type vch;
+    unsigned int nReadPos;
+    short state;
+    short exceptmask;
+public:
+    int nType;
+    int nVersion;
+
+    typedef vector_type::allocator_type   allocator_type;
+    typedef vector_type::size_type        size_type;
+    typedef vector_type::difference_type  difference_type;
+    typedef vector_type::reference        reference;
+    typedef vector_type::const_reference  const_reference;
+    typedef vector_type::value_type       value_type;
+    typedef vector_type::iterator         iterator;
+    typedef vector_type::const_iterator   const_iterator;
+    typedef vector_type::reverse_iterator reverse_iterator;
+
+    explicit CDataStream(int nTypeIn=SER_NETWORK, int nVersionIn=VERSION)
+    {
+        Init(nTypeIn, nVersionIn);
+    }
+
+    CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch(pbegin, pend)
+    {
+        Init(nTypeIn, nVersionIn);
+    }
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1300
+    CDataStream(const char* pbegin, const char* pend, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch(pbegin, pend)
+    {
+        Init(nTypeIn, nVersionIn);
+    }
+#endif
+
+    CDataStream(const vector_type& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch(vchIn.begin(), vchIn.end())
+    {
+        Init(nTypeIn, nVersionIn);
+    }
+
+    CDataStream(const std::vector<char>& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch(vchIn.begin(), vchIn.end())
+    {
+        Init(nTypeIn, nVersionIn);
+    }
+
+    CDataStream(const std::vector<unsigned char>& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch((char*)&vchIn.begin()[0], (char*)&vchIn.end()[0])
+    {
+        Init(nTypeIn, nVersionIn);
+    }
+
+    void Init(int nTypeIn=SER_NETWORK, int nVersionIn=VERSION)
+    {
+        nReadPos = 0;
+        nType = nTypeIn;
+        nVersion = nVersionIn;
+        state = 0;
+        exceptmask = std::ios::badbit | std::ios::failbit;
+    }
+
+    CDataStream& operator+=(const CDataStream& b)
+    {
+        vch.insert(vch.end(), b.begin(), b.end());
+        return *this;
+    }
+
+    friend CDataStream operator+(const CDataStream& a, const CDataStream& b)
+    {
+        CDataStream ret = a;
+        ret += b;
+        return (ret);
+    }
+
+    std::string str() const
+    {
+        return (std::string(begin(), end()));
+    }
+
+
+    //
+    // Vector subset
+    //
+    const_iterator begin() const                     { return vch.begin() + nReadPos; }
+    iterator begin()                                 { return vch.begin() + nReadPos; }
+    const_iterator end() const                       { return vch.end(); }
+    iterator end()                                   { return vch.end(); }
+    size_type size() const                           { return vch.size() - nReadPos; }
+    bool empty() const                               { return vch.size() == nReadPos; }
+    void resize(size_type n, value_type c=0)         { vch.resize(n + nReadPos, c); }
+    void reserve(size_type n)                        { vch.reserve(n + nReadPos); }
+    const_reference operator[](size_type pos) const  { return vch[pos + nReadPos]; }
+    reference operator[](size_type pos)              { return vch[pos + nReadPos]; }
+    void clear()                                     { vch.clear(); nReadPos = 0; }
+    iterator insert(iterator it, const char& x=char()) { return vch.insert(it, x); }
+    void insert(iterator it, size_type n, const char& x) { vch.insert(it, n, x); }
+
+    void insert(iterator it, const_iterator first, const_iterator last)
+    {
+        if (it == vch.begin() + nReadPos && last - first <= nReadPos)
+        {
+            // special case for inserting at the front when there's room
+            nReadPos -= (last - first);
+            memcpy(&vch[nReadPos], &first[0], last - first);
+        }
+        else
+            vch.insert(it, first, last);
+    }
+
+    void insert(iterator it, std::vector<char>::const_iterator first, std::vector<char>::const_iterator last)
+    {
+        if (it == vch.begin() + nReadPos && last - first <= nReadPos)
+        {
+            // special case for inserting at the front when there's room
+            nReadPos -= (last - first);
+            memcpy(&vch[nReadPos], &first[0], last - first);
+        }
+        else
+            vch.insert(it, first, last);
+    }
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1300
+    void insert(iterator it, const char* first, const char* last)
+    {
+        if (it == vch.begin() + nReadPos && last - first <= nReadPos)
+        {
+            // special case for inserting at the front when there's room
+            nReadPos -= (last - first);
+            memcpy(&vch[nReadPos], &first[0], last - first);
+        }
+        else
+            vch.insert(it, first, last);
+    }
+#endif
+
+    iterator erase(iterator it)
+    {
+        if (it == vch.begin() + nReadPos)
+        {
+            // special case for erasing from the front
+            if (++nReadPos >= vch.size())
+            {
+                // whenever we reach the end, we take the opportunity to clear the buffer
+                nReadPos = 0;
+                return vch.erase(vch.begin(), vch.end());
+            }
+            return vch.begin() + nReadPos;
+        }
+        else
+            return vch.erase(it);
+    }
+
+    iterator erase(iterator first, iterator last)
+    {
+        if (first == vch.begin() + nReadPos)
+        {
+            // special case for erasing from the front
+            if (last == vch.end())
+            {
+                nReadPos = 0;
+                return vch.erase(vch.begin(), vch.end());
+            }
+            else
+            {
+                nReadPos = (last - vch.begin());
+                return last;
+            }
+        }
+        else
+            return vch.erase(first, last);
+    }
+
+    inline void Compact()
+    {
+        vch.erase(vch.begin(), vch.begin() + nReadPos);
+        nReadPos = 0;
+    }
+
+    bool Rewind(size_type n)
+    {
+        // Rewind by n characters if the buffer hasn't been compacted yet
+        if (n > nReadPos)
+            return false;
+        nReadPos -= n;
+        return true;
+    }
+
+
+    //
+    // Stream subset
+    //
+    void setstate(short bits, const char* psz)
+    {
+        state |= bits;
+        if (state & exceptmask)
+            throw std::ios_base::failure(psz);
+    }
+
+    bool eof() const             { return size() == 0; }
+    bool fail() const            { return state & (std::ios::badbit | std::ios::failbit); }
+    bool good() const            { return !eof() && (state == 0); }
+    void clear(short n)          { state = n; }  // name conflict with vector clear()
+    short exceptions()           { return exceptmask; }
+    short exceptions(short mask) { short prev = exceptmask; exceptmask = mask; setstate(0, "CDataStream"); return prev; }
+    CDataStream* rdbuf()         { return this; }
+    int in_avail()               { return size(); }
+
+    void SetType(int n)          { nType = n; }
+    int GetType()                { return nType; }
+    void SetVersion(int n)       { nVersion = n; }
+    int GetVersion()             { return nVersion; }
+    void ReadVersion()           { *this >> nVersion; }
+    void WriteVersion()          { *this << nVersion; }
+
+    CDataStream& read(char* pch, int nSize)
+    {
+        // Read from the beginning of the buffer
+        assert(nSize >= 0);
+        unsigned int nReadPosNext = nReadPos + nSize;
+        if (nReadPosNext >= vch.size())
+        {
+            if (nReadPosNext > vch.size())
+            {
+                setstate(std::ios::failbit, "CDataStream::read() : end of data");
+                memset(pch, 0, nSize);
+                nSize = vch.size() - nReadPos;
+            }
+            memcpy(pch, &vch[nReadPos], nSize);
+            nReadPos = 0;
+            vch.clear();
+            return (*this);
+        }
+        memcpy(pch, &vch[nReadPos], nSize);
+        nReadPos = nReadPosNext;
+        return (*this);
+    }
+
+    CDataStream& ignore(int nSize)
+    {
+        // Ignore from the beginning of the buffer
+        assert(nSize >= 0);
+        unsigned int nReadPosNext = nReadPos + nSize;
+        if (nReadPosNext >= vch.size())
+        {
+            if (nReadPosNext > vch.size())
+            {
+                setstate(std::ios::failbit, "CDataStream::ignore() : end of data");
+                nSize = vch.size() - nReadPos;
+            }
+            nReadPos = 0;
+            vch.clear();
+            return (*this);
+        }
+        nReadPos = nReadPosNext;
+        return (*this);
+    }
+
+    CDataStream& write(const char* pch, int nSize)
+    {
+        // Write to the end of the buffer
+        assert(nSize >= 0);
+        vch.insert(vch.end(), pch, pch + nSize);
+        return (*this);
+    }
+
+    template<typename Stream>
+    void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const
+    {
+        // Special case: stream << stream concatenates like stream += stream
+        if (!vch.empty())
+            s.write((char*)&vch[0], vch.size() * sizeof(vch[0]));
+    }
+
+    template<typename T>
+    unsigned int GetSerializeSize(const T& obj)
+    {
+        // Tells the size of the object if serialized to this stream
+        return ::GetSerializeSize(obj, nType, nVersion);
+    }
+
+    template<typename T>
+    CDataStream& operator<<(const T& obj)
+    {
+        // Serialize to this stream
+        ::Serialize(*this, obj, nType, nVersion);
+        return (*this);
+    }
+
+    template<typename T>
+    CDataStream& operator>>(T& obj)
+    {
+        // Unserialize from this stream
+        ::Unserialize(*this, obj, nType, nVersion);
+        return (*this);
+    }
+};
+
+#ifdef TESTCDATASTREAM
+// VC6sp6
+// CDataStream:
+// n=1000       0 seconds
+// n=2000       0 seconds
+// n=4000       0 seconds
+// n=8000       0 seconds
+// n=16000      0 seconds
+// n=32000      0 seconds
+// n=64000      1 seconds
+// n=128000     1 seconds
+// n=256000     2 seconds
+// n=512000     4 seconds
+// n=1024000    8 seconds
+// n=2048000    16 seconds
+// n=4096000    32 seconds
+// stringstream:
+// n=1000       1 seconds
+// n=2000       1 seconds
+// n=4000       13 seconds
+// n=8000       87 seconds
+// n=16000      400 seconds
+// n=32000      1660 seconds
+// n=64000      6749 seconds
+// n=128000     27241 seconds
+// n=256000     109804 seconds
+#include <iostream>
+int main(int argc, char *argv[])
+{
+    vector<unsigned char> vch(0xcc, 250);
+    printf("CDataStream:\n");
+    for (int n = 1000; n <= 4500000; n *= 2)
+    {
+        CDataStream ss;
+        time_t nStart = time(NULL);
+        for (int i = 0; i < n; i++)
+            ss.write((char*)&vch[0], vch.size());
+        printf("n=%-10d %d seconds\n", n, time(NULL) - nStart);
+    }
+    printf("stringstream:\n");
+    for (int n = 1000; n <= 4500000; n *= 2)
+    {
+        stringstream ss;
+        time_t nStart = time(NULL);
+        for (int i = 0; i < n; i++)
+            ss.write((char*)&vch[0], vch.size());
+        printf("n=%-10d %d seconds\n", n, time(NULL) - nStart);
+    }
+}
+#endif
+
+
+
+
+
+
+
+
+
+
+//
+// Automatic closing wrapper for FILE*
+//  - Will automatically close the file when it goes out of scope if not null.
+//  - If you're returning the file pointer, return file.release().
+//  - If you need to close the file early, use file.fclose() instead of fclose(file).
+//
+class CAutoFile
+{
+protected:
+    FILE* file;
+    short state;
+    short exceptmask;
+public:
+    int nType;
+    int nVersion;
+
+    typedef FILE element_type;
+
+    CAutoFile(FILE* filenew=NULL, int nTypeIn=SER_DISK, int nVersionIn=VERSION)
+    {
+        file = filenew;
+        nType = nTypeIn;
+        nVersion = nVersionIn;
+        state = 0;
+        exceptmask = std::ios::badbit | std::ios::failbit;
+    }
+
+    ~CAutoFile()
+    {
+        fclose();
+    }
+
+    void fclose()
+    {
+        if (file != NULL && file != stdin && file != stdout && file != stderr)
+            ::fclose(file);
+        file = NULL;
+    }
+
+    FILE* release()             { FILE* ret = file; file = NULL; return ret; }
+    operator FILE*()            { return file; }
+    FILE* operator->()          { return file; }
+    FILE& operator*()           { return *file; }
+    FILE** operator&()          { return &file; }
+    FILE* operator=(FILE* pnew) { return file = pnew; }
+    bool operator!()            { return (file == NULL); }
+
+
+    //
+    // Stream subset
+    //
+    void setstate(short bits, const char* psz)
+    {
+        state |= bits;
+        if (state & exceptmask)
+            throw std::ios_base::failure(psz);
+    }
+
+    bool fail() const            { return state & (std::ios::badbit | std::ios::failbit); }
+    bool good() const            { return state == 0; }
+    void clear(short n = 0)      { state = n; }
+    short exceptions()           { return exceptmask; }
+    short exceptions(short mask) { short prev = exceptmask; exceptmask = mask; setstate(0, "CAutoFile"); return prev; }
+
+    void SetType(int n)          { nType = n; }
+    int GetType()                { return nType; }
+    void SetVersion(int n)       { nVersion = n; }
+    int GetVersion()             { return nVersion; }
+    void ReadVersion()           { *this >> nVersion; }
+    void WriteVersion()          { *this << nVersion; }
+
+    CAutoFile& read(char* pch, int nSize)
+    {
+        if (!file)
+            throw std::ios_base::failure("CAutoFile::read : file handle is NULL");
+        if (fread(pch, 1, nSize, file) != nSize)
+            setstate(std::ios::failbit, feof(file) ? "CAutoFile::read : end of file" : "CAutoFile::read : fread failed");
+        return (*this);
+    }
+
+    CAutoFile& write(const char* pch, int nSize)
+    {
+        if (!file)
+            throw std::ios_base::failure("CAutoFile::write : file handle is NULL");
+        if (fwrite(pch, 1, nSize, file) != nSize)
+            setstate(std::ios::failbit, "CAutoFile::write : write failed");
+        return (*this);
+    }
+
+    template<typename T>
+    unsigned int GetSerializeSize(const T& obj)
+    {
+        // Tells the size of the object if serialized to this stream
+        return ::GetSerializeSize(obj, nType, nVersion);
+    }
+
+    template<typename T>
+    CAutoFile& operator<<(const T& obj)
+    {
+        // Serialize to this stream
+        if (!file)
+            throw std::ios_base::failure("CAutoFile::operator<< : file handle is NULL");
+        ::Serialize(*this, obj, nType, nVersion);
+        return (*this);
+    }
+
+    template<typename T>
+    CAutoFile& operator>>(T& obj)
+    {
+        // Unserialize from this stream
+        if (!file)
+            throw std::ios_base::failure("CAutoFile::operator>> : file handle is NULL");
+        ::Unserialize(*this, obj, nType, nVersion);
+        return (*this);
+    }
+};
+
+#endif
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..356b2dc8e9d3d55c937ae3945308a0ec05a40076
--- /dev/null
@@ -0,0 +1,765 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Distributed under the MIT/X11 software license, see the accompanying
+// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+#ifndef BITCOIN_UINT256_H
+#define BITCOIN_UINT256_H
+
+#include "serialize.h"
+
+#include <limits.h>
+#include <string>
+#include <vector>
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+typedef __int64  int64;
+typedef unsigned __int64  uint64;
+#else
+typedef long long  int64;
+typedef unsigned long long  uint64;
+#endif
+#if defined(_MSC_VER) && _MSC_VER < 1300
+#define for  if (false) ; else for
+#endif
+
+
+inline int Testuint256AdHoc(std::vector<std::string> vArg);
+
+
+
+// We have to keep a separate base class without constructors
+// so the compiler will let us use it in a union
+template<unsigned int BITS>
+class base_uint
+{
+protected:
+    enum { WIDTH=BITS/32 };
+    unsigned int pn[WIDTH];
+public:
+
+    bool operator!() const
+    {
+        for (int i = 0; i < WIDTH; i++)
+            if (pn[i] != 0)
+                return false;
+        return true;
+    }
+
+    const base_uint operator~() const
+    {
+        base_uint ret;
+        for (int i = 0; i < WIDTH; i++)
+            ret.pn[i] = ~pn[i];
+        return ret;
+    }
+
+    const base_uint operator-() const
+    {
+        base_uint ret;
+        for (int i = 0; i < WIDTH; i++)
+            ret.pn[i] = ~pn[i];
+        ret++;
+        return ret;
+    }
+
+
+    base_uint& operator=(uint64 b)
+    {
+        pn[0] = (unsigned int)b;
+        pn[1] = (unsigned int)(b >> 32);
+        for (int i = 2; i < WIDTH; i++)
+            pn[i] = 0;
+        return *this;
+    }
+
+    base_uint& operator^=(const base_uint& b)
+    {
+        for (int i = 0; i < WIDTH; i++)
+            pn[i] ^= b.pn[i];
+        return *this;
+    }
+
+    base_uint& operator&=(const base_uint& b)
+    {
+        for (int i = 0; i < WIDTH; i++)
+            pn[i] &= b.pn[i];
+        return *this;
+    }
+
+    base_uint& operator|=(const base_uint& b)
+    {
+        for (int i = 0; i < WIDTH; i++)
+            pn[i] |= b.pn[i];
+        return *this;
+    }
+
+    base_uint& operator^=(uint64 b)
+    {
+        pn[0] ^= (unsigned int)b;
+        pn[1] ^= (unsigned int)(b >> 32);
+        return *this;
+    }
+
+    base_uint& operator&=(uint64 b)
+    {
+        pn[0] &= (unsigned int)b;
+        pn[1] &= (unsigned int)(b >> 32);
+        return *this;
+    }
+
+    base_uint& operator|=(uint64 b)
+    {
+        pn[0] |= (unsigned int)b;
+        pn[1] |= (unsigned int)(b >> 32);
+        return *this;
+    }
+
+    base_uint& operator<<=(unsigned int shift)
+    {
+        base_uint a(*this);
+        for (int i = 0; i < WIDTH; i++)
+            pn[i] = 0;
+        int k = shift / 32;
+        shift = shift % 32;
+        for (int i = 0; i < WIDTH; i++)
+        {
+            if (i+k+1 < WIDTH && shift != 0)
+                pn[i+k+1] |= (a.pn[i] >> (32-shift));
+            if (i+k < WIDTH)
+                pn[i+k] |= (a.pn[i] << shift);
+        }
+        return *this;
+    }
+
+    base_uint& operator>>=(unsigned int shift)
+    {
+        base_uint a(*this);
+        for (int i = 0; i < WIDTH; i++)
+            pn[i] = 0;
+        int k = shift / 32;
+        shift = shift % 32;
+        for (int i = 0; i < WIDTH; i++)
+        {
+            if (i-k-1 >= 0 && shift != 0)
+                pn[i-k-1] |= (a.pn[i] << (32-shift));
+            if (i-k >= 0)
+                pn[i-k] |= (a.pn[i] >> shift);
+        }
+        return *this;
+    }
+
+    base_uint& operator+=(const base_uint& b)
+    {
+        uint64 carry = 0;
+        for (int i = 0; i < WIDTH; i++)
+        {
+            uint64 n = carry + pn[i] + b.pn[i];
+            pn[i] = n & 0xffffffff;
+            carry = n >> 32;
+        }
+        return *this;
+    }
+
+    base_uint& operator-=(const base_uint& b)
+    {
+        *this += -b;
+        return *this;
+    }
+
+    base_uint& operator+=(uint64 b64)
+    {
+        base_uint b;
+        b = b64;
+        *this += b;
+        return *this;
+    }
+
+    base_uint& operator-=(uint64 b64)
+    {
+        base_uint b;
+        b = b64;
+        *this += -b;
+        return *this;
+    }
+
+
+    base_uint& operator++()
+    {
+        // prefix operator
+        int i = 0;
+        while (++pn[i] == 0 && i < WIDTH-1)
+            i++;
+        return *this;
+    }
+
+    const base_uint operator++(int)
+    {
+        // postfix operator
+        const base_uint ret = *this;
+        ++(*this);
+        return ret;
+    }
+
+    base_uint& operator--()
+    {
+        // prefix operator
+        int i = 0;
+        while (--pn[i] == -1 && i < WIDTH-1)
+            i++;
+        return *this;
+    }
+
+    const base_uint operator--(int)
+    {
+        // postfix operator
+        const base_uint ret = *this;
+        --(*this);
+        return ret;
+    }
+
+
+    friend inline bool operator<(const base_uint& a, const base_uint& b)
+    {
+        for (int i = base_uint::WIDTH-1; i >= 0; i--)
+        {
+            if (a.pn[i] < b.pn[i])
+                return true;
+            else if (a.pn[i] > b.pn[i])
+                return false;
+        }
+        return false;
+    }
+
+    friend inline bool operator<=(const base_uint& a, const base_uint& b)
+    {
+        for (int i = base_uint::WIDTH-1; i >= 0; i--)
+        {
+            if (a.pn[i] < b.pn[i])
+                return true;
+            else if (a.pn[i] > b.pn[i])
+                return false;
+        }
+        return true;
+    }
+
+    friend inline bool operator>(const base_uint& a, const base_uint& b)
+    {
+        for (int i = base_uint::WIDTH-1; i >= 0; i--)
+        {
+            if (a.pn[i] > b.pn[i])
+                return true;
+            else if (a.pn[i] < b.pn[i])
+                return false;
+        }
+        return false;
+    }
+
+    friend inline bool operator>=(const base_uint& a, const base_uint& b)
+    {
+        for (int i = base_uint::WIDTH-1; i >= 0; i--)
+        {
+            if (a.pn[i] > b.pn[i])
+                return true;
+            else if (a.pn[i] < b.pn[i])
+                return false;
+        }
+        return true;
+    }
+
+    friend inline bool operator==(const base_uint& a, const base_uint& b)
+    {
+        for (int i = 0; i < base_uint::WIDTH; i++)
+            if (a.pn[i] != b.pn[i])
+                return false;
+        return true;
+    }
+
+    friend inline bool operator==(const base_uint& a, uint64 b)
+    {
+        if (a.pn[0] != (unsigned int)b)
+            return false;
+        if (a.pn[1] != (unsigned int)(b >> 32))
+            return false;
+        for (int i = 2; i < base_uint::WIDTH; i++)
+            if (a.pn[i] != 0)
+                return false;
+        return true;
+    }
+
+    friend inline bool operator!=(const base_uint& a, const base_uint& b)
+    {
+        return (!(a == b));
+    }
+
+    friend inline bool operator!=(const base_uint& a, uint64 b)
+    {
+        return (!(a == b));
+    }
+
+
+
+    std::string GetHex() const
+    {
+        char psz[sizeof(pn)*2 + 1];
+        for (int i = 0; i < sizeof(pn); i++)
+            sprintf(psz + i*2, "%02x", ((unsigned char*)pn)[sizeof(pn) - i - 1]);
+        return string(psz, psz + sizeof(pn)*2);
+    }
+
+    void SetHex(const char* psz)
+    {
+        for (int i = 0; i < WIDTH; i++)
+            pn[i] = 0;
+
+        // skip leading spaces
+        while (isspace(*psz))
+            psz++;
+
+        // skip 0x
+        if (psz[0] == '0' && tolower(psz[1]) == 'x')
+            psz += 2;
+
+        // hex string to uint
+        static char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 };
+        const char* pbegin = psz;
+        while (phexdigit[*psz] || *psz == '0')
+            psz++;
+        psz--;
+        unsigned char* p1 = (unsigned char*)pn;
+        unsigned char* pend = p1 + WIDTH * 4;
+        while (psz >= pbegin && p1 < pend)
+        {
+            *p1 = phexdigit[(unsigned char)*psz--];
+            if (psz >= pbegin)
+            {
+                *p1 |= (phexdigit[(unsigned char)*psz--] << 4);
+                p1++;
+            }
+        }
+    }
+
+    void SetHex(const std::string& str)
+    {
+        SetHex(str.c_str());
+    }
+
+    std::string ToString() const
+    {
+        return (GetHex());
+    }
+
+    unsigned char* begin()
+    {
+        return (unsigned char*)&pn[0];
+    }
+
+    unsigned char* end()
+    {
+        return (unsigned char*)&pn[WIDTH];
+    }
+
+    unsigned int size()
+    {
+        return sizeof(pn);
+    }
+
+
+    unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const
+    {
+        return sizeof(pn);
+    }
+
+    template<typename Stream>
+    void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const
+    {
+        s.write((char*)pn, sizeof(pn));
+    }
+
+    template<typename Stream>
+    void Unserialize(Stream& s, int nType=0, int nVersion=VERSION)
+    {
+        s.read((char*)pn, sizeof(pn));
+    }
+
+
+    friend class uint160;
+    friend class uint256;
+    friend inline int Testuint256AdHoc(std::vector<std::string> vArg);
+};
+
+typedef base_uint<160> base_uint160;
+typedef base_uint<256> base_uint256;
+
+
+
+//
+// uint160 and uint256 could be implemented as templates, but to keep
+// compile errors and debugging cleaner, they're copy and pasted.
+//
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// uint160
+//
+
+class uint160 : public base_uint160
+{
+public:
+    typedef base_uint160 basetype;
+
+    uint160()
+    {
+        for (int i = 0; i < WIDTH; i++)
+            pn[i] = 0;
+    }
+
+    uint160(const basetype& b)
+    {
+        for (int i = 0; i < WIDTH; i++)
+            pn[i] = b.pn[i];
+    }
+
+    uint160& operator=(const basetype& b)
+    {
+        for (int i = 0; i < WIDTH; i++)
+            pn[i] = b.pn[i];
+        return *this;
+    }
+
+    uint160(uint64 b)
+    {
+        pn[0] = (unsigned int)b;
+        pn[1] = (unsigned int)(b >> 32);
+        for (int i = 2; i < WIDTH; i++)
+            pn[i] = 0;
+    }
+
+    uint160& operator=(uint64 b)
+    {
+        pn[0] = (unsigned int)b;
+        pn[1] = (unsigned int)(b >> 32);
+        for (int i = 2; i < WIDTH; i++)
+            pn[i] = 0;
+        return *this;
+    }
+
+    explicit uint160(const std::string& str)
+    {
+        SetHex(str);
+    }
+
+    explicit uint160(const std::vector<unsigned char>& vch)
+    {
+        if (vch.size() == sizeof(pn))
+            memcpy(pn, &vch[0], sizeof(pn));
+        else
+            *this = 0;
+    }
+};
+
+inline bool operator==(const uint160& a, uint64 b)                           { return (base_uint160)a == b; }
+inline bool operator!=(const uint160& a, uint64 b)                           { return (base_uint160)a != b; }
+inline const uint160 operator<<(const base_uint160& a, unsigned int shift)   { return uint160(a) <<= shift; }
+inline const uint160 operator>>(const base_uint160& a, unsigned int shift)   { return uint160(a) >>= shift; }
+inline const uint160 operator<<(const uint160& a, unsigned int shift)        { return uint160(a) <<= shift; }
+inline const uint160 operator>>(const uint160& a, unsigned int shift)        { return uint160(a) >>= shift; }
+
+inline const uint160 operator^(const base_uint160& a, const base_uint160& b) { return uint160(a) ^= b; }
+inline const uint160 operator&(const base_uint160& a, const base_uint160& b) { return uint160(a) &= b; }
+inline const uint160 operator|(const base_uint160& a, const base_uint160& b) { return uint160(a) |= b; }
+inline const uint160 operator+(const base_uint160& a, const base_uint160& b) { return uint160(a) += b; }
+inline const uint160 operator-(const base_uint160& a, const base_uint160& b) { return uint160(a) -= b; }
+
+inline bool operator<(const base_uint160& a, const uint160& b)          { return (base_uint160)a <  (base_uint160)b; }
+inline bool operator<=(const base_uint160& a, const uint160& b)         { return (base_uint160)a <= (base_uint160)b; }
+inline bool operator>(const base_uint160& a, const uint160& b)          { return (base_uint160)a >  (base_uint160)b; }
+inline bool operator>=(const base_uint160& a, const uint160& b)         { return (base_uint160)a >= (base_uint160)b; }
+inline bool operator==(const base_uint160& a, const uint160& b)         { return (base_uint160)a == (base_uint160)b; }
+inline bool operator!=(const base_uint160& a, const uint160& b)         { return (base_uint160)a != (base_uint160)b; }
+inline const uint160 operator^(const base_uint160& a, const uint160& b) { return (base_uint160)a ^  (base_uint160)b; }
+inline const uint160 operator&(const base_uint160& a, const uint160& b) { return (base_uint160)a &  (base_uint160)b; }
+inline const uint160 operator|(const base_uint160& a, const uint160& b) { return (base_uint160)a |  (base_uint160)b; }
+inline const uint160 operator+(const base_uint160& a, const uint160& b) { return (base_uint160)a +  (base_uint160)b; }
+inline const uint160 operator-(const base_uint160& a, const uint160& b) { return (base_uint160)a -  (base_uint160)b; }
+
+inline bool operator<(const uint160& a, const base_uint160& b)          { return (base_uint160)a <  (base_uint160)b; }
+inline bool operator<=(const uint160& a, const base_uint160& b)         { return (base_uint160)a <= (base_uint160)b; }
+inline bool operator>(const uint160& a, const base_uint160& b)          { return (base_uint160)a >  (base_uint160)b; }
+inline bool operator>=(const uint160& a, const base_uint160& b)         { return (base_uint160)a >= (base_uint160)b; }
+inline bool operator==(const uint160& a, const base_uint160& b)         { return (base_uint160)a == (base_uint160)b; }
+inline bool operator!=(const uint160& a, const base_uint160& b)         { return (base_uint160)a != (base_uint160)b; }
+inline const uint160 operator^(const uint160& a, const base_uint160& b) { return (base_uint160)a ^  (base_uint160)b; }
+inline const uint160 operator&(const uint160& a, const base_uint160& b) { return (base_uint160)a &  (base_uint160)b; }
+inline const uint160 operator|(const uint160& a, const base_uint160& b) { return (base_uint160)a |  (base_uint160)b; }
+inline const uint160 operator+(const uint160& a, const base_uint160& b) { return (base_uint160)a +  (base_uint160)b; }
+inline const uint160 operator-(const uint160& a, const base_uint160& b) { return (base_uint160)a -  (base_uint160)b; }
+
+inline bool operator<(const uint160& a, const uint160& b)               { return (base_uint160)a <  (base_uint160)b; }
+inline bool operator<=(const uint160& a, const uint160& b)              { return (base_uint160)a <= (base_uint160)b; }
+inline bool operator>(const uint160& a, const uint160& b)               { return (base_uint160)a >  (base_uint160)b; }
+inline bool operator>=(const uint160& a, const uint160& b)              { return (base_uint160)a >= (base_uint160)b; }
+inline bool operator==(const uint160& a, const uint160& b)              { return (base_uint160)a == (base_uint160)b; }
+inline bool operator!=(const uint160& a, const uint160& b)              { return (base_uint160)a != (base_uint160)b; }
+inline const uint160 operator^(const uint160& a, const uint160& b)      { return (base_uint160)a ^  (base_uint160)b; }
+inline const uint160 operator&(const uint160& a, const uint160& b)      { return (base_uint160)a &  (base_uint160)b; }
+inline const uint160 operator|(const uint160& a, const uint160& b)      { return (base_uint160)a |  (base_uint160)b; }
+inline const uint160 operator+(const uint160& a, const uint160& b)      { return (base_uint160)a +  (base_uint160)b; }
+inline const uint160 operator-(const uint160& a, const uint160& b)      { return (base_uint160)a -  (base_uint160)b; }
+
+
+
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// uint256
+//
+
+class uint256 : public base_uint256
+{
+public:
+    typedef base_uint256 basetype;
+
+    uint256()
+    {
+        for (int i = 0; i < WIDTH; i++)
+            pn[i] = 0;
+    }
+
+    uint256(const basetype& b)
+    {
+        for (int i = 0; i < WIDTH; i++)
+            pn[i] = b.pn[i];
+    }
+
+    uint256& operator=(const basetype& b)
+    {
+        for (int i = 0; i < WIDTH; i++)
+            pn[i] = b.pn[i];
+        return *this;
+    }
+
+    uint256(uint64 b)
+    {
+        pn[0] = (unsigned int)b;
+        pn[1] = (unsigned int)(b >> 32);
+        for (int i = 2; i < WIDTH; i++)
+            pn[i] = 0;
+    }
+
+    uint256& operator=(uint64 b)
+    {
+        pn[0] = (unsigned int)b;
+        pn[1] = (unsigned int)(b >> 32);
+        for (int i = 2; i < WIDTH; i++)
+            pn[i] = 0;
+        return *this;
+    }
+
+    explicit uint256(const std::string& str)
+    {
+        SetHex(str);
+    }
+
+    explicit uint256(const std::vector<unsigned char>& vch)
+    {
+        if (vch.size() == sizeof(pn))
+            memcpy(pn, &vch[0], sizeof(pn));
+        else
+            *this = 0;
+    }
+};
+
+inline bool operator==(const uint256& a, uint64 b)                           { return (base_uint256)a == b; }
+inline bool operator!=(const uint256& a, uint64 b)                           { return (base_uint256)a != b; }
+inline const uint256 operator<<(const base_uint256& a, unsigned int shift)   { return uint256(a) <<= shift; }
+inline const uint256 operator>>(const base_uint256& a, unsigned int shift)   { return uint256(a) >>= shift; }
+inline const uint256 operator<<(const uint256& a, unsigned int shift)        { return uint256(a) <<= shift; }
+inline const uint256 operator>>(const uint256& a, unsigned int shift)        { return uint256(a) >>= shift; }
+
+inline const uint256 operator^(const base_uint256& a, const base_uint256& b) { return uint256(a) ^= b; }
+inline const uint256 operator&(const base_uint256& a, const base_uint256& b) { return uint256(a) &= b; }
+inline const uint256 operator|(const base_uint256& a, const base_uint256& b) { return uint256(a) |= b; }
+inline const uint256 operator+(const base_uint256& a, const base_uint256& b) { return uint256(a) += b; }
+inline const uint256 operator-(const base_uint256& a, const base_uint256& b) { return uint256(a) -= b; }
+
+inline bool operator<(const base_uint256& a, const uint256& b)          { return (base_uint256)a <  (base_uint256)b; }
+inline bool operator<=(const base_uint256& a, const uint256& b)         { return (base_uint256)a <= (base_uint256)b; }
+inline bool operator>(const base_uint256& a, const uint256& b)          { return (base_uint256)a >  (base_uint256)b; }
+inline bool operator>=(const base_uint256& a, const uint256& b)         { return (base_uint256)a >= (base_uint256)b; }
+inline bool operator==(const base_uint256& a, const uint256& b)         { return (base_uint256)a == (base_uint256)b; }
+inline bool operator!=(const base_uint256& a, const uint256& b)         { return (base_uint256)a != (base_uint256)b; }
+inline const uint256 operator^(const base_uint256& a, const uint256& b) { return (base_uint256)a ^  (base_uint256)b; }
+inline const uint256 operator&(const base_uint256& a, const uint256& b) { return (base_uint256)a &  (base_uint256)b; }
+inline const uint256 operator|(const base_uint256& a, const uint256& b) { return (base_uint256)a |  (base_uint256)b; }
+inline const uint256 operator+(const base_uint256& a, const uint256& b) { return (base_uint256)a +  (base_uint256)b; }
+inline const uint256 operator-(const base_uint256& a, const uint256& b) { return (base_uint256)a -  (base_uint256)b; }
+
+inline bool operator<(const uint256& a, const base_uint256& b)          { return (base_uint256)a <  (base_uint256)b; }
+inline bool operator<=(const uint256& a, const base_uint256& b)         { return (base_uint256)a <= (base_uint256)b; }
+inline bool operator>(const uint256& a, const base_uint256& b)          { return (base_uint256)a >  (base_uint256)b; }
+inline bool operator>=(const uint256& a, const base_uint256& b)         { return (base_uint256)a >= (base_uint256)b; }
+inline bool operator==(const uint256& a, const base_uint256& b)         { return (base_uint256)a == (base_uint256)b; }
+inline bool operator!=(const uint256& a, const base_uint256& b)         { return (base_uint256)a != (base_uint256)b; }
+inline const uint256 operator^(const uint256& a, const base_uint256& b) { return (base_uint256)a ^  (base_uint256)b; }
+inline const uint256 operator&(const uint256& a, const base_uint256& b) { return (base_uint256)a &  (base_uint256)b; }
+inline const uint256 operator|(const uint256& a, const base_uint256& b) { return (base_uint256)a |  (base_uint256)b; }
+inline const uint256 operator+(const uint256& a, const base_uint256& b) { return (base_uint256)a +  (base_uint256)b; }
+inline const uint256 operator-(const uint256& a, const base_uint256& b) { return (base_uint256)a -  (base_uint256)b; }
+
+inline bool operator<(const uint256& a, const uint256& b)               { return (base_uint256)a <  (base_uint256)b; }
+inline bool operator<=(const uint256& a, const uint256& b)              { return (base_uint256)a <= (base_uint256)b; }
+inline bool operator>(const uint256& a, const uint256& b)               { return (base_uint256)a >  (base_uint256)b; }
+inline bool operator>=(const uint256& a, const uint256& b)              { return (base_uint256)a >= (base_uint256)b; }
+inline bool operator==(const uint256& a, const uint256& b)              { return (base_uint256)a == (base_uint256)b; }
+inline bool operator!=(const uint256& a, const uint256& b)              { return (base_uint256)a != (base_uint256)b; }
+inline const uint256 operator^(const uint256& a, const uint256& b)      { return (base_uint256)a ^  (base_uint256)b; }
+inline const uint256 operator&(const uint256& a, const uint256& b)      { return (base_uint256)a &  (base_uint256)b; }
+inline const uint256 operator|(const uint256& a, const uint256& b)      { return (base_uint256)a |  (base_uint256)b; }
+inline const uint256 operator+(const uint256& a, const uint256& b)      { return (base_uint256)a +  (base_uint256)b; }
+inline const uint256 operator-(const uint256& a, const uint256& b)      { return (base_uint256)a -  (base_uint256)b; }
+
+
+
+
+
+
+
+
+
+
+
+
+inline int Testuint256AdHoc(vector<string> vArg)
+{
+    uint256 g(0);
+
+
+    printf("%s\n", g.ToString().c_str());
+    g--;  printf("g--\n");
+    printf("%s\n", g.ToString().c_str());
+    g--;  printf("g--\n");
+    printf("%s\n", g.ToString().c_str());
+    g++;  printf("g++\n");
+    printf("%s\n", g.ToString().c_str());
+    g++;  printf("g++\n");
+    printf("%s\n", g.ToString().c_str());
+    g++;  printf("g++\n");
+    printf("%s\n", g.ToString().c_str());
+    g++;  printf("g++\n");
+    printf("%s\n", g.ToString().c_str());
+
+
+
+    uint256 a(7);
+    printf("a=7\n");
+    printf("%s\n", a.ToString().c_str());
+
+    uint256 b;
+    printf("b undefined\n");
+    printf("%s\n", b.ToString().c_str());
+    int c = 3;
+
+    a = c;
+    a.pn[3] = 15;
+    printf("%s\n", a.ToString().c_str());
+    uint256 k(c);
+
+    a = 5;
+    a.pn[3] = 15;
+    printf("%s\n", a.ToString().c_str());
+    b = 1;
+    b <<= 52;
+
+    a |= b;
+
+    a ^= 0x500;
+
+    printf("a %s\n", a.ToString().c_str());
+
+    a = a | b | (uint256)0x1000;
+
+
+    printf("a %s\n", a.ToString().c_str());
+    printf("b %s\n", b.ToString().c_str());
+
+    a = 0xfffffffe;
+    a.pn[4] = 9;
+
+    printf("%s\n", a.ToString().c_str());
+    a++;
+    printf("%s\n", a.ToString().c_str());
+    a++;
+    printf("%s\n", a.ToString().c_str());
+    a++;
+    printf("%s\n", a.ToString().c_str());
+    a++;
+    printf("%s\n", a.ToString().c_str());
+
+    a--;
+    printf("%s\n", a.ToString().c_str());
+    a--;
+    printf("%s\n", a.ToString().c_str());
+    a--;
+    printf("%s\n", a.ToString().c_str());
+    uint256 d = a--;
+    printf("%s\n", d.ToString().c_str());
+    printf("%s\n", a.ToString().c_str());
+    a--;
+    printf("%s\n", a.ToString().c_str());
+    a--;
+    printf("%s\n", a.ToString().c_str());
+
+    d = a;
+
+    printf("%s\n", d.ToString().c_str());
+    for (int i = uint256::WIDTH-1; i >= 0; i--) printf("%08x", d.pn[i]); printf("\n");
+
+    uint256 neg = d;
+    neg = ~neg;
+    printf("%s\n", neg.ToString().c_str());
+
+
+    uint256 e = uint256("0xABCDEF123abcdef12345678909832180000011111111");
+    printf("\n");
+    printf("%s\n", e.ToString().c_str());
+
+
+    printf("\n");
+    uint256 x1 = uint256("0xABCDEF123abcdef12345678909832180000011111111");
+    uint256 x2;
+    printf("%s\n", x1.ToString().c_str());
+    for (int i = 0; i < 270; i += 4)
+    {
+        x2 = x1 << i;
+        printf("%s\n", x2.ToString().c_str());
+    }
+
+    printf("\n");
+    printf("%s\n", x1.ToString().c_str());
+    for (int i = 0; i < 270; i += 4)
+    {
+        x2 = x1;
+        x2 >>= i;
+        printf("%s\n", x2.ToString().c_str());
+    }
+
+
+    for (int i = 0; i < 100; i++)
+    {
+        uint256 k = (~uint256(0) >> i);
+        printf("%s\n", k.ToString().c_str());
+    }
+
+    for (int i = 0; i < 100; i++)
+    {
+        uint256 k = (~uint256(0) << i);
+        printf("%s\n", k.ToString().c_str());
+    }
+
+    return (0);
+}
+
+#endif
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..af8cfcf65947159bbc4d54ed3d3695d6c6d42656
--- /dev/null
@@ -0,0 +1,673 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Distributed under the MIT/X11 software license, see the accompanying
+// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+#ifndef BITCOIN_UTIL_H
+#define BITCOIN_UTIL_H
+
+#include "uint256.h"
+
+#include <sys/types.h>
+#include <map>
+#include <vector>
+#include <string>
+
+#include <boost/thread.hpp>
+#include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
+#include <boost/date_time/gregorian/gregorian_types.hpp>
+#include <boost/date_time/posix_time/posix_time_types.hpp>
+
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+typedef __int64  int64;
+typedef unsigned __int64  uint64;
+#else
+typedef long long  int64;
+typedef unsigned long long  uint64;
+#endif
+#if defined(_MSC_VER) && _MSC_VER < 1300
+#define for  if (false) ; else for
+#endif
+#ifndef _MSC_VER
+#define __forceinline  inline
+#endif
+
+//#define foreach             BOOST_FOREACH
+#define loop                for (;;)
+#define BEGIN(a)            ((char*)&(a))
+#define END(a)              ((char*)&((&(a))[1]))
+#define UBEGIN(a)           ((unsigned char*)&(a))
+#define UEND(a)             ((unsigned char*)&((&(a))[1]))
+#define ARRAYLEN(array)     (sizeof(array)/sizeof((array)[0]))
+#define printf              OutputDebugStringF
+
+#ifdef snprintf
+#undef snprintf
+#endif
+#define snprintf my_snprintf
+
+#ifndef PRI64d
+#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MSVCRT__)
+#define PRI64d  "I64d"
+#define PRI64u  "I64u"
+#define PRI64x  "I64x"
+#else
+#define PRI64d  "lld"
+#define PRI64u  "llu"
+#define PRI64x  "llx"
+#endif
+#endif
+
+// This is needed because the foreach macro can't get over the comma in pair<t1, t2>
+#define PAIRTYPE(t1, t2)    pair<t1, t2>
+
+// Used to bypass the rule against non-const reference to temporary
+// where it makes sense with wrappers such as CFlatData or CTxDB
+template<typename T>
+inline T& REF(const T& val)
+{
+    return (T&)val;
+}
+
+// Align by increasing pointer, must have extra space at end of buffer
+template <size_t nBytes, typename T>
+T* alignup(T* p)
+{
+    union
+    {
+        T* ptr;
+        size_t n;
+    } u;
+    u.ptr = p;
+    u.n = (u.n + (nBytes-1)) & ~(nBytes-1);
+    return u.ptr;
+}
+
+#ifdef __WXMSW__
+#define MSG_NOSIGNAL        0
+#define MSG_DONTWAIT        0
+#ifndef UINT64_MAX
+#define UINT64_MAX          _UI64_MAX
+#define INT64_MAX           _I64_MAX
+#define INT64_MIN           _I64_MIN
+#endif
+#ifndef S_IRUSR
+#define S_IRUSR             0400
+#define S_IWUSR             0200
+#endif
+#define unlink              _unlink
+typedef int socklen_t;
+#else
+#define WSAGetLastError()   errno
+#define WSAEWOULDBLOCK      EWOULDBLOCK
+#define WSAEMSGSIZE         EMSGSIZE
+#define WSAEINTR            EINTR
+#define WSAEINPROGRESS      EINPROGRESS
+#define WSAEADDRINUSE       EADDRINUSE
+#define WSAENOTSOCK         EBADF
+#define INVALID_SOCKET      (SOCKET)(~0)
+#define SOCKET_ERROR        -1
+typedef u_int SOCKET;
+#define _vsnprintf(a,b,c,d) vsnprintf(a,b,c,d)
+#define strlwr(psz)         to_lower(psz)
+#define _strlwr(psz)        to_lower(psz)
+#define MAX_PATH            1024
+#define Beep(n1,n2)         (0)
+inline void Sleep(int64 n)
+{
+    boost::thread::sleep(boost::get_system_time() + boost::posix_time::milliseconds(n));
+}
+#endif
+
+inline int myclosesocket(SOCKET& hSocket)
+{
+    if (hSocket == INVALID_SOCKET)
+        return WSAENOTSOCK;
+#ifdef __WXMSW__
+    int ret = closesocket(hSocket);
+#else
+    int ret = close(hSocket);
+#endif
+    hSocket = INVALID_SOCKET;
+    return ret;
+}
+#define closesocket(s)      myclosesocket(s)
+
+#ifndef GUI
+inline const char* _(const char* psz)
+{
+    return psz;
+}
+#endif
+
+
+
+
+
+
+
+
+
+
+extern std::map<std::string, std::string> mapArgs;
+extern std::map<std::string, std::vector<std::string> > mapMultiArgs;
+extern bool fDebug;
+extern bool fPrintToConsole;
+extern bool fPrintToDebugger;
+extern char pszSetDataDir[MAX_PATH];
+extern bool fRequestShutdown;
+extern bool fShutdown;
+extern bool fDaemon;
+extern bool fServer;
+extern bool fCommandLine;
+extern std::string strMiscWarning;
+extern bool fTestNet;
+extern bool fNoListen;
+extern bool fLogTimestamps;
+
+void RandAddSeed();
+void RandAddSeedPerfmon();
+int OutputDebugStringF(const char* pszFormat, ...);
+int my_snprintf(char* buffer, size_t limit, const char* format, ...);
+std::string strprintf(const char* format, ...);
+bool error(const char* format, ...);
+void LogException(std::exception* pex, const char* pszThread);
+void PrintException(std::exception* pex, const char* pszThread);
+void PrintExceptionContinue(std::exception* pex, const char* pszThread);
+void ParseString(const std::string& str, char c, std::vector<std::string>& v);
+std::string FormatMoney(int64 n, bool fPlus=false);
+bool ParseMoney(const std::string& str, int64& nRet);
+bool ParseMoney(const char* pszIn, int64& nRet);
+std::vector<unsigned char> ParseHex(const char* psz);
+std::vector<unsigned char> ParseHex(const std::string& str);
+void ParseParameters(int argc, char* argv[]);
+const char* wxGetTranslation(const char* psz);
+bool WildcardMatch(const char* psz, const char* mask);
+bool WildcardMatch(const std::string& str, const std::string& mask);
+int GetFilesize(FILE* file);
+void GetDataDir(char* pszDirRet);
+std::string GetConfigFile();
+std::string GetPidFile();
+void CreatePidFile(std::string pidFile, pid_t pid);
+void ReadConfigFile(std::map<std::string, std::string>& mapSettingsRet, std::map<std::string, std::vector<std::string> >& mapMultiSettingsRet);
+#ifdef __WXMSW__
+string MyGetSpecialFolderPath(int nFolder, bool fCreate);
+#endif
+std::string GetDefaultDataDir();
+std::string GetDataDir();
+void ShrinkDebugFile();
+int GetRandInt(int nMax);
+uint64 GetRand(uint64 nMax);
+int64 GetTime();
+int64 GetAdjustedTime();
+void AddTimeData(unsigned int ip, int64 nTime);
+std::string FormatFullVersion();
+
+
+
+
+
+
+
+
+
+
+
+
+
+// Wrapper to automatically initialize critical sections
+class CCriticalSection
+{
+#ifdef __WXMSW__
+protected:
+    CRITICAL_SECTION cs;
+public:
+    explicit CCriticalSection() { InitializeCriticalSection(&cs); }
+    ~CCriticalSection() { DeleteCriticalSection(&cs); }
+    void Enter() { EnterCriticalSection(&cs); }
+    void Leave() { LeaveCriticalSection(&cs); }
+    bool TryEnter() { return TryEnterCriticalSection(&cs); }
+#else
+protected:
+    boost::interprocess::interprocess_recursive_mutex mutex;
+public:
+    explicit CCriticalSection() { }
+    ~CCriticalSection() { }
+    void Enter() { mutex.lock(); }
+    void Leave() { mutex.unlock(); }
+    bool TryEnter() { return mutex.try_lock(); }
+#endif
+public:
+    const char* pszFile;
+    int nLine;
+};
+
+// Automatically leave critical section when leaving block, needed for exception safety
+class CCriticalBlock
+{
+protected:
+    CCriticalSection* pcs;
+public:
+    CCriticalBlock(CCriticalSection& csIn) { pcs = &csIn; pcs->Enter(); }
+    ~CCriticalBlock() { pcs->Leave(); }
+};
+
+// WARNING: This will catch continue and break!
+// break is caught with an assertion, but there's no way to detect continue.
+// I'd rather be careful than suffer the other more error prone syntax.
+// The compiler will optimise away all this loop junk.
+#define CRITICAL_BLOCK(cs)     \
+    for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by CRITICAL_BLOCK!", !fcriticalblockonce)), fcriticalblockonce=false)  \
+    for (CCriticalBlock criticalblock(cs); fcriticalblockonce && (cs.pszFile=__FILE__, cs.nLine=__LINE__, true); fcriticalblockonce=false, cs.pszFile=NULL, cs.nLine=0)
+
+class CTryCriticalBlock
+{
+protected:
+    CCriticalSection* pcs;
+public:
+    CTryCriticalBlock(CCriticalSection& csIn) { pcs = (csIn.TryEnter() ? &csIn : NULL); }
+    ~CTryCriticalBlock() { if (pcs) pcs->Leave(); }
+    bool Entered() { return pcs != NULL; }
+};
+
+#define TRY_CRITICAL_BLOCK(cs)     \
+    for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by TRY_CRITICAL_BLOCK!", !fcriticalblockonce)), fcriticalblockonce=false)  \
+    for (CTryCriticalBlock criticalblock(cs); fcriticalblockonce && (fcriticalblockonce = criticalblock.Entered()) && (cs.pszFile=__FILE__, cs.nLine=__LINE__, true); fcriticalblockonce=false, cs.pszFile=NULL, cs.nLine=0)
+
+
+
+
+
+
+
+
+
+
+inline std::string i64tostr(int64 n)
+{
+    return strprintf("%"PRI64d, n);
+}
+
+inline std::string itostr(int n)
+{
+    return strprintf("%d", n);
+}
+
+inline int64 atoi64(const char* psz)
+{
+#ifdef _MSC_VER
+    return _atoi64(psz);
+#else
+    return strtoll(psz, NULL, 10);
+#endif
+}
+
+inline int64 atoi64(const std::string& str)
+{
+#ifdef _MSC_VER
+    return _atoi64(str.c_str());
+#else
+    return strtoll(str.c_str(), NULL, 10);
+#endif
+}
+
+inline int atoi(const std::string& str)
+{
+    return atoi(str.c_str());
+}
+
+inline int roundint(double d)
+{
+    return (int)(d > 0 ? d + 0.5 : d - 0.5);
+}
+
+inline int64 roundint64(double d)
+{
+    return (int64)(d > 0 ? d + 0.5 : d - 0.5);
+}
+
+inline int64 abs64(int64 n)
+{
+    return (n >= 0 ? n : -n);
+}
+
+template<typename T>
+std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
+{
+    if (itbegin == itend)
+        return "";
+    const unsigned char* pbegin = (const unsigned char*)&itbegin[0];
+    const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]);
+    std::string str;
+    str.reserve((pend-pbegin) * (fSpaces ? 3 : 2));
+    for (const unsigned char* p = pbegin; p != pend; p++)
+        str += strprintf((fSpaces && p != pend-1 ? "%02x " : "%02x"), *p);
+    return str;
+}
+
+inline std::string HexStr(const std::vector<unsigned char>& vch, bool fSpaces=false)
+{
+    return HexStr(vch.begin(), vch.end(), fSpaces);
+}
+
+template<typename T>
+std::string HexNumStr(const T itbegin, const T itend, bool f0x=true)
+{
+    if (itbegin == itend)
+        return "";
+    const unsigned char* pbegin = (const unsigned char*)&itbegin[0];
+    const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]);
+    std::string str = (f0x ? "0x" : "");
+    str.reserve(str.size() + (pend-pbegin) * 2);
+    for (const unsigned char* p = pend-1; p >= pbegin; p--)
+        str += strprintf("%02x", *p);
+    return str;
+}
+
+inline std::string HexNumStr(const std::vector<unsigned char>& vch, bool f0x=true)
+{
+    return HexNumStr(vch.begin(), vch.end(), f0x);
+}
+
+template<typename T>
+void PrintHex(const T pbegin, const T pend, const char* pszFormat="%s", bool fSpaces=true)
+{
+    printf(pszFormat, HexStr(pbegin, pend, fSpaces).c_str());
+}
+
+inline void PrintHex(const std::vector<unsigned char>& vch, const char* pszFormat="%s", bool fSpaces=true)
+{
+    printf(pszFormat, HexStr(vch, fSpaces).c_str());
+}
+
+inline int64 GetPerformanceCounter()
+{
+    int64 nCounter = 0;
+#ifdef __WXMSW__
+    QueryPerformanceCounter((LARGE_INTEGER*)&nCounter);
+#else
+    timeval t;
+    gettimeofday(&t, NULL);
+    nCounter = t.tv_sec * 1000000 + t.tv_usec;
+#endif
+    return nCounter;
+}
+
+inline int64 GetTimeMillis()
+{
+    return (boost::posix_time::ptime(boost::posix_time::microsec_clock::universal_time()) -
+            boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_milliseconds();
+}
+
+inline std::string DateTimeStrFormat(const char* pszFormat, int64 nTime)
+{
+    time_t n = nTime;
+    struct tm* ptmTime = gmtime(&n);
+    char pszTime[200];
+    strftime(pszTime, sizeof(pszTime), pszFormat, ptmTime);
+    return pszTime;
+}
+
+template<typename T>
+void skipspaces(T& it)
+{
+    while (isspace(*it))
+        ++it;
+}
+
+inline bool IsSwitchChar(char c)
+{
+#ifdef __WXMSW__
+    return c == '-' || c == '/';
+#else
+    return c == '-';
+#endif
+}
+
+inline std::string GetArg(const std::string& strArg, const std::string& strDefault)
+{
+    if (mapArgs.count(strArg))
+        return mapArgs[strArg];
+    return strDefault;
+}
+
+inline int64 GetArg(const std::string& strArg, int64 nDefault)
+{
+    if (mapArgs.count(strArg))
+        return atoi64(mapArgs[strArg]);
+    return nDefault;
+}
+
+inline bool GetBoolArg(const std::string& strArg)
+{
+    if (mapArgs.count(strArg))
+    {
+        if (mapArgs[strArg].empty())
+            return true;
+        return (atoi(mapArgs[strArg]) != 0);
+    }
+    return false;
+}
+
+
+
+
+
+
+
+
+
+
+inline void heapchk()
+{
+#ifdef __WXMSW__
+    /// for debugging
+    //if (_heapchk() != _HEAPOK)
+    //    DebugBreak();
+#endif
+}
+
+// Randomize the stack to help protect against buffer overrun exploits
+#define IMPLEMENT_RANDOMIZE_STACK(ThreadFn)     \
+    {                                           \
+        static char nLoops;                     \
+        if (nLoops <= 0)                        \
+            nLoops = GetRand(20) + 1;           \
+        if (nLoops-- > 1)                       \
+        {                                       \
+            ThreadFn;                           \
+            return;                             \
+        }                                       \
+    }
+
+#define CATCH_PRINT_EXCEPTION(pszFn)     \
+    catch (std::exception& e) {          \
+        PrintException(&e, (pszFn));     \
+    } catch (...) {                      \
+        PrintException(NULL, (pszFn));   \
+    }
+
+
+
+
+
+
+
+
+
+
+template<typename T1>
+inline uint256 Hash(const T1 pbegin, const T1 pend)
+{
+    static unsigned char pblank[1];
+    uint256 hash1;
+    SHA256((pbegin == pend ? pblank : (unsigned char*)&pbegin[0]), (pend - pbegin) * sizeof(pbegin[0]), (unsigned char*)&hash1);
+    uint256 hash2;
+    SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
+    return hash2;
+}
+
+template<typename T1, typename T2>
+inline uint256 Hash(const T1 p1begin, const T1 p1end,
+                    const T2 p2begin, const T2 p2end)
+{
+    static unsigned char pblank[1];
+    uint256 hash1;
+    SHA256_CTX ctx;
+    SHA256_Init(&ctx);
+    SHA256_Update(&ctx, (p1begin == p1end ? pblank : (unsigned char*)&p1begin[0]), (p1end - p1begin) * sizeof(p1begin[0]));
+    SHA256_Update(&ctx, (p2begin == p2end ? pblank : (unsigned char*)&p2begin[0]), (p2end - p2begin) * sizeof(p2begin[0]));
+    SHA256_Final((unsigned char*)&hash1, &ctx);
+    uint256 hash2;
+    SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
+    return hash2;
+}
+
+template<typename T1, typename T2, typename T3>
+inline uint256 Hash(const T1 p1begin, const T1 p1end,
+                    const T2 p2begin, const T2 p2end,
+                    const T3 p3begin, const T3 p3end)
+{
+    static unsigned char pblank[1];
+    uint256 hash1;
+    SHA256_CTX ctx;
+    SHA256_Init(&ctx);
+    SHA256_Update(&ctx, (p1begin == p1end ? pblank : (unsigned char*)&p1begin[0]), (p1end - p1begin) * sizeof(p1begin[0]));
+    SHA256_Update(&ctx, (p2begin == p2end ? pblank : (unsigned char*)&p2begin[0]), (p2end - p2begin) * sizeof(p2begin[0]));
+    SHA256_Update(&ctx, (p3begin == p3end ? pblank : (unsigned char*)&p3begin[0]), (p3end - p3begin) * sizeof(p3begin[0]));
+    SHA256_Final((unsigned char*)&hash1, &ctx);
+    uint256 hash2;
+    SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
+    return hash2;
+}
+
+template<typename T>
+uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=VERSION)
+{
+    // Most of the time is spent allocating and deallocating CDataStream's
+    // buffer.  If this ever needs to be optimized further, make a CStaticStream
+    // class with its buffer on the stack.
+    CDataStream ss(nType, nVersion);
+    ss.reserve(10000);
+    ss << obj;
+    return Hash(ss.begin(), ss.end());
+}
+
+inline uint160 Hash160(const vector<unsigned char>& vch)
+{
+    uint256 hash1;
+    SHA256(&vch[0], vch.size(), (unsigned char*)&hash1);
+    uint160 hash2;
+    RIPEMD160((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
+    return hash2;
+}
+
+
+
+
+
+
+
+
+
+
+
+// Note: It turns out we might have been able to use boost::thread
+// by using TerminateThread(boost::thread.native_handle(), 0);
+#ifdef __WXMSW__
+typedef HANDLE pthread_t;
+
+inline pthread_t CreateThread(void(*pfn)(void*), void* parg, bool fWantHandle=false)
+{
+    DWORD nUnused = 0;
+    HANDLE hthread =
+        CreateThread(
+            NULL,                        // default security
+            0,                           // inherit stack size from parent
+            (LPTHREAD_START_ROUTINE)pfn, // function pointer
+            parg,                        // argument
+            0,                           // creation option, start immediately
+            &nUnused);                   // thread identifier
+    if (hthread == NULL)
+    {
+        printf("Error: CreateThread() returned %d\n", GetLastError());
+        return (pthread_t)0;
+    }
+    if (!fWantHandle)
+    {
+        CloseHandle(hthread);
+        return (pthread_t)-1;
+    }
+    return hthread;
+}
+
+inline void SetThreadPriority(int nPriority)
+{
+    SetThreadPriority(GetCurrentThread(), nPriority);
+}
+#else
+inline pthread_t CreateThread(void(*pfn)(void*), void* parg, bool fWantHandle=false)
+{
+    pthread_t hthread = 0;
+    int ret = pthread_create(&hthread, NULL, (void*(*)(void*))pfn, parg);
+    if (ret != 0)
+    {
+        printf("Error: pthread_create() returned %d\n", ret);
+        return (pthread_t)0;
+    }
+    if (!fWantHandle)
+        return (pthread_t)-1;
+    return hthread;
+}
+
+#define THREAD_PRIORITY_LOWEST          PRIO_MAX
+#define THREAD_PRIORITY_BELOW_NORMAL    2
+#define THREAD_PRIORITY_NORMAL          0
+#define THREAD_PRIORITY_ABOVE_NORMAL    0
+
+inline void SetThreadPriority(int nPriority)
+{
+    // It's unclear if it's even possible to change thread priorities on Linux,
+    // but we really and truly need it for the generation threads.
+#ifdef PRIO_THREAD
+    setpriority(PRIO_THREAD, 0, nPriority);
+#else
+    setpriority(PRIO_PROCESS, 0, nPriority);
+#endif
+}
+
+inline bool TerminateThread(pthread_t hthread, unsigned int nExitCode)
+{
+    return (pthread_cancel(hthread) == 0);
+}
+
+inline void ExitThread(unsigned int nExitCode)
+{
+    pthread_exit((void*)nExitCode);
+}
+#endif
+
+
+
+
+
+inline bool AffinityBugWorkaround(void(*pfn)(void*))
+{
+#ifdef __WXMSW__
+    // Sometimes after a few hours affinity gets stuck on one processor
+    DWORD dwProcessAffinityMask = -1;
+    DWORD dwSystemAffinityMask = -1;
+    GetProcessAffinityMask(GetCurrentProcess(), &dwProcessAffinityMask, &dwSystemAffinityMask);
+    DWORD dwPrev1 = SetThreadAffinityMask(GetCurrentThread(), dwProcessAffinityMask);
+    DWORD dwPrev2 = SetThreadAffinityMask(GetCurrentThread(), dwProcessAffinityMask);
+    if (dwPrev2 != dwProcessAffinityMask)
+    {
+        printf("AffinityBugWorkaround() : SetThreadAffinityMask=%d, ProcessAffinityMask=%d, restarting thread\n", dwPrev2, dwProcessAffinityMask);
+        if (!CreateThread(pfn, NULL))
+            printf("Error: CreateThread() failed\n");
+        return true;
+    }
+#endif
+    return false;
+}
+
+#endif
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge