begin integration with bitcoin upstream
This commit is contained in:
1 parent
4d1bb15e31
commit
1f2e0df865
38 files changed
+3489
-35
No files matched your search
+32
-31
@@ -1,39 +1,40 @@
|
|||||||
######################################################################
|
|
||||||
# Automatically generated by qmake (2.01a) Sat May 7 20:45:42 2011
|
|
||||||
######################################################################
|
|
||||||
|
|
||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
TARGET =
|
TARGET =
|
||||||
DEPENDPATH += .
|
DEPENDPATH += .
|
||||||
INCLUDEPATH += .
|
INCLUDEPATH += gui/include lib/include
|
||||||
|
|
||||||
# Input
|
# Input
|
||||||
HEADERS += bitcoingui.h \
|
HEADERS += gui/include/bitcoingui.h \
|
||||||
transactiontablemodel.h \
|
gui/include/transactiontablemodel.h \
|
||||||
addresstablemodel.h \
|
gui/include/addresstablemodel.h \
|
||||||
optionsdialog.h \
|
gui/include/optionsdialog.h \
|
||||||
mainoptionspage.h \
|
gui/include/mainoptionspage.h \
|
||||||
sendcoinsdialog.h \
|
gui/include/sendcoinsdialog.h \
|
||||||
addressbookdialog.h \
|
gui/include/addressbookdialog.h \
|
||||||
aboutdialog.h \
|
gui/include/aboutdialog.h \
|
||||||
editaddressdialog.h \
|
gui/include/editaddressdialog.h \
|
||||||
bitcoinaddressvalidator.h
|
gui/include/bitcoinaddressvalidator.h \
|
||||||
SOURCES += bitcoin.cpp bitcoingui.cpp \
|
lib/include/base58.h \
|
||||||
transactiontablemodel.cpp \
|
lib/include/bignum.h \
|
||||||
addresstablemodel.cpp \
|
lib/include/util.h \
|
||||||
optionsdialog.cpp \
|
lib/include/uint256.h \
|
||||||
mainoptionspage.cpp \
|
lib/include/serialize.h
|
||||||
sendcoinsdialog.cpp \
|
SOURCES += gui/src/bitcoin.cpp gui/src/bitcoingui.cpp \
|
||||||
addressbookdialog.cpp \
|
gui/src/transactiontablemodel.cpp \
|
||||||
aboutdialog.cpp \
|
gui/src/addresstablemodel.cpp \
|
||||||
editaddressdialog.cpp \
|
gui/src/optionsdialog.cpp \
|
||||||
bitcoinaddressvalidator.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 += \
|
RESOURCES += \
|
||||||
bitcoin.qrc
|
gui/bitcoin.qrc
|
||||||
|
|
||||||
FORMS += \
|
FORMS += \
|
||||||
sendcoinsdialog.ui \
|
gui/forms/sendcoinsdialog.ui \
|
||||||
addressbookdialog.ui \
|
gui/forms/addressbookdialog.ui \
|
||||||
aboutdialog.ui \
|
gui/forms/aboutdialog.ui \
|
||||||
editaddressdialog.ui
|
gui/forms/editaddressdialog.ui
|
||||||
File renamed without changes.
@@ -26,7 +26,7 @@
|
|||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="pixmap">
|
<property name="pixmap">
|
||||||
<pixmap resource="bitcoin.qrc">:/images/about</pixmap>
|
<pixmap resource="../bitcoin.qrc">:/images/about</pixmap>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -123,7 +123,7 @@ This product includes software developed by the OpenSSL Project for use in the O
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="bitcoin.qrc"/>
|
<include location="../bitcoin.qrc"/>
|
||||||
</resources>
|
</resources>
|
||||||
<connections>
|
<connections>
|
||||||
<connection>
|
<connection>
|
||||||
File renamed without changes.
File renamed without changes.
@@ -121,7 +121,7 @@
|
|||||||
<string>&Send</string>
|
<string>&Send</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="bitcoin.qrc">
|
<iconset resource="../bitcoin.qrc">
|
||||||
<normaloff>:/icons/send</normaloff>:/icons/send</iconset>
|
<normaloff>:/icons/send</normaloff>:/icons/send</iconset>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
@@ -144,7 +144,7 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="bitcoin.qrc"/>
|
<include location="../bitcoin.qrc"/>
|
||||||
</resources>
|
</resources>
|
||||||
<connections>
|
<connections>
|
||||||
<connection>
|
<connection>
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include <QRegExpValidator>
|
#include <QRegExpValidator>
|
||||||
|
|
||||||
|
#include <base58.h>
|
||||||
|
|
||||||
class BitcoinAddressValidator : public QRegExpValidator
|
class BitcoinAddressValidator : public QRegExpValidator
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -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
|
||||||
@@ -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
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -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
|
||||||
@@ -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
|
||||||
Reference in new issue
Block a user