git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@1 1a98c847-1fd6-4fd8-948a-caf3550aa51b0.8
@ -0,0 +1,201 @@
@@ -0,0 +1,201 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
//
|
||||
// Why base-58 instead of standard base-64 encoding?
|
||||
// - Don't want 0OIl characters that look the same in some fonts and
|
||||
// could be used to create visually identical looking account numbers.
|
||||
// - A string with non-alphanumeric characters is not as easily accepted as an account number.
|
||||
// - E-mail usually won't line-break if there's no punctuation to break at.
|
||||
// - Doubleclicking selects the whole number as one word if it's all alphanumeric.
|
||||
//
|
||||
|
||||
|
||||
static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; |
||||
|
||||
|
||||
inline string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend) |
||||
{ |
||||
CAutoBN_CTX pctx; |
||||
CBigNum bn58 = 58; |
||||
CBigNum bn0 = 0; |
||||
|
||||
// Convert big endian data to little endian
|
||||
// Extra zero at the end make sure bignum will interpret as a positive number
|
||||
vector<unsigned char> vchTmp(pend-pbegin+1, 0); |
||||
reverse_copy(pbegin, pend, vchTmp.begin()); |
||||
|
||||
// Convert little endian data to bignum
|
||||
CBigNum bn; |
||||
bn.setvch(vchTmp); |
||||
|
||||
// Convert bignum to string
|
||||
string str; |
||||
str.reserve((pend - pbegin) * 138 / 100 + 1); |
||||
CBigNum dv; |
||||
CBigNum rem; |
||||
while (bn > bn0) |
||||
{ |
||||
if (!BN_div(&dv, &rem, &bn, &bn58, pctx)) |
||||
throw bignum_error("EncodeBase58 : BN_div failed"); |
||||
bn = dv; |
||||
unsigned int c = rem.getulong(); |
||||
str += pszBase58[c]; |
||||
} |
||||
|
||||
// Leading zeroes encoded as base58 zeros
|
||||
for (const unsigned char* p = pbegin; p < pend && *p == 0; p++) |
||||
str += pszBase58[0]; |
||||
|
||||
// Convert little endian string to big endian
|
||||
reverse(str.begin(), str.end()); |
||||
return str; |
||||
} |
||||
|
||||
inline string EncodeBase58(const vector<unsigned char>& vch) |
||||
{ |
||||
return EncodeBase58(&vch[0], &vch[0] + vch.size()); |
||||
} |
||||
|
||||
inline bool DecodeBase58(const char* psz, vector<unsigned char>& vchRet) |
||||
{ |
||||
CAutoBN_CTX pctx; |
||||
vchRet.clear(); |
||||
CBigNum bn58 = 58; |
||||
CBigNum bn = 0; |
||||
CBigNum bnChar; |
||||
while (isspace(*psz)) |
||||
psz++; |
||||
|
||||
// Convert big endian string to bignum
|
||||
for (const char* p = psz; *p; p++) |
||||
{ |
||||
const char* p1 = strchr(pszBase58, *p); |
||||
if (p1 == NULL) |
||||
{ |
||||
while (isspace(*p)) |
||||
p++; |
||||
if (*p != '\0') |
||||
return false; |
||||
break; |
||||
} |
||||
bnChar.setulong(p1 - pszBase58); |
||||
if (!BN_mul(&bn, &bn, &bn58, pctx)) |
||||
throw bignum_error("DecodeBase58 : BN_mul failed"); |
||||
bn += bnChar; |
||||
} |
||||
|
||||
// Get bignum as little endian data
|
||||
vector<unsigned char> vchTmp = bn.getvch(); |
||||
|
||||
// Trim off sign byte if present
|
||||
if (vchTmp.size() >= 2 && vchTmp.end()[-1] == 0 && vchTmp.end()[-2] >= 0x80) |
||||
vchTmp.erase(vchTmp.end()-1); |
||||
|
||||
// Restore leading zeros
|
||||
int nLeadingZeros = 0; |
||||
for (const char* p = psz; *p == pszBase58[0]; p++) |
||||
nLeadingZeros++; |
||||
vchRet.assign(nLeadingZeros + vchTmp.size(), 0); |
||||
|
||||
// Convert little endian data to big endian
|
||||
reverse_copy(vchTmp.begin(), vchTmp.end(), vchRet.end() - vchTmp.size()); |
||||
return true; |
||||
} |
||||
|
||||
inline bool DecodeBase58(const string& str, vector<unsigned char>& vchRet) |
||||
{ |
||||
return DecodeBase58(str.c_str(), vchRet); |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
inline string EncodeBase58Check(const vector<unsigned char>& vchIn) |
||||
{ |
||||
// add 4-byte hash check to the end
|
||||
vector<unsigned char> vch(vchIn); |
||||
uint256 hash = Hash(vch.begin(), vch.end()); |
||||
vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4); |
||||
return EncodeBase58(vch); |
||||
} |
||||
|
||||
inline bool DecodeBase58Check(const char* psz, vector<unsigned char>& vchRet) |
||||
{ |
||||
if (!DecodeBase58(psz, vchRet)) |
||||
return false; |
||||
if (vchRet.size() < 4) |
||||
{ |
||||
vchRet.clear(); |
||||
return false; |
||||
} |
||||
uint256 hash = Hash(vchRet.begin(), vchRet.end()-4); |
||||
if (memcmp(&hash, &vchRet.end()[-4], 4) != 0) |
||||
{ |
||||
vchRet.clear(); |
||||
return false; |
||||
} |
||||
vchRet.resize(vchRet.size()-4); |
||||
return true; |
||||
} |
||||
|
||||
inline bool DecodeBase58Check(const string& str, vector<unsigned char>& vchRet) |
||||
{ |
||||
return DecodeBase58Check(str.c_str(), vchRet); |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static const unsigned char ADDRESSVERSION = 0; |
||||
|
||||
inline string Hash160ToAddress(uint160 hash160) |
||||
{ |
||||
// add 1-byte version number to the front
|
||||
vector<unsigned char> vch(1, ADDRESSVERSION); |
||||
vch.insert(vch.end(), UBEGIN(hash160), UEND(hash160)); |
||||
return EncodeBase58Check(vch); |
||||
} |
||||
|
||||
inline bool AddressToHash160(const char* psz, uint160& hash160Ret) |
||||
{ |
||||
vector<unsigned char> vch; |
||||
if (!DecodeBase58Check(psz, vch)) |
||||
return false; |
||||
if (vch.empty()) |
||||
return false; |
||||
unsigned char nVersion = vch[0]; |
||||
if (vch.size() != sizeof(hash160Ret) + 1) |
||||
return false; |
||||
memcpy(&hash160Ret, &vch[1], sizeof(hash160Ret)); |
||||
return (nVersion <= ADDRESSVERSION); |
||||
} |
||||
|
||||
inline bool AddressToHash160(const string& str, uint160& hash160Ret) |
||||
{ |
||||
return AddressToHash160(str.c_str(), hash160Ret); |
||||
} |
||||
|
||||
inline bool IsValidBitcoinAddress(const char* psz) |
||||
{ |
||||
uint160 hash160; |
||||
return AddressToHash160(psz, hash160); |
||||
} |
||||
|
||||
inline bool IsValidBitcoinAddress(const string& str) |
||||
{ |
||||
return IsValidBitcoinAddress(str.c_str()); |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
inline string PubKeyToAddress(const vector<unsigned char>& vchPubKey) |
||||
{ |
||||
return Hash160ToAddress(Hash160(vchPubKey)); |
||||
} |
@ -0,0 +1,498 @@
@@ -0,0 +1,498 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <stdexcept> |
||||
#include <vector> |
||||
#include <openssl/bn.h> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class bignum_error : public std::runtime_error |
||||
{ |
||||
public: |
||||
explicit bignum_error(const std::string& str) : std::runtime_error(str) {} |
||||
}; |
||||
|
||||
|
||||
|
||||
class CAutoBN_CTX |
||||
{ |
||||
protected: |
||||
BN_CTX* pctx; |
||||
BN_CTX* operator=(BN_CTX* pnew) { return pctx = pnew; } |
||||
|
||||
public: |
||||
CAutoBN_CTX() |
||||
{ |
||||
pctx = BN_CTX_new(); |
||||
if (pctx == NULL) |
||||
throw bignum_error("CAutoBN_CTX : BN_CTX_new() returned NULL"); |
||||
} |
||||
|
||||
~CAutoBN_CTX() |
||||
{ |
||||
if (pctx != NULL) |
||||
BN_CTX_free(pctx); |
||||
} |
||||
|
||||
operator BN_CTX*() { return pctx; } |
||||
BN_CTX& operator*() { return *pctx; } |
||||
BN_CTX** operator&() { return &pctx; } |
||||
bool operator!() { return (pctx == NULL); } |
||||
}; |
||||
|
||||
|
||||
|
||||
class CBigNum : public BIGNUM |
||||
{ |
||||
public: |
||||
CBigNum() |
||||
{ |
||||
BN_init(this); |
||||
} |
||||
|
||||
CBigNum(const CBigNum& b) |
||||
{ |
||||
BN_init(this); |
||||
if (!BN_copy(this, &b)) |
||||
{ |
||||
BN_clear_free(this); |
||||
throw bignum_error("CBigNum::CBigNum(const CBigNum&) : BN_copy failed"); |
||||
} |
||||
} |
||||
|
||||
explicit CBigNum(const std::string& str) |
||||
{ |
||||
BN_init(this); |
||||
SetHex(str); |
||||
} |
||||
|
||||
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; |
||||
} |
||||
|
||||
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) |
||||
{ |
||||
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; |
||||
if (!BN_rshift(&r, &a, shift)) |
||||
throw bignum_error("CBigNum:operator>> : BN_rshift failed"); |
||||
return r; |
||||
} |
||||
|
||||
inline bool operator==(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) == 0); } |
||||
inline bool operator!=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) != 0); } |
||||
inline bool operator<=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) <= 0); } |
||||
inline bool operator>=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) >= 0); } |
||||
inline bool operator<(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) < 0); } |
||||
inline bool operator>(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) > 0); } |
@ -0,0 +1,614 @@
@@ -0,0 +1,614 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "headers.h" |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// CDB
|
||||
//
|
||||
|
||||
static CCriticalSection cs_db; |
||||
static bool fDbEnvInit = false; |
||||
DbEnv dbenv(0); |
||||
static map<string, int> mapFileUseCount; |
||||
|
||||
class CDBInit |
||||
{ |
||||
public: |
||||
CDBInit() |
||||
{ |
||||
} |
||||
~CDBInit() |
||||
{ |
||||
if (fDbEnvInit) |
||||
{ |
||||
dbenv.close(0); |
||||
fDbEnvInit = false; |
||||
} |
||||
} |
||||
} |
||||
instance_of_cdbinit; |
||||
|
||||
|
||||
CDB::CDB(const char* pszFile, const char* pszMode, bool fTxn) : pdb(NULL) |
||||
{ |
||||
int ret; |
||||
if (pszFile == NULL) |
||||
return; |
||||
|
||||
bool fCreate = strchr(pszMode, 'c'); |
||||
bool fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w')); |
||||
unsigned int nFlags = DB_THREAD; |
||||
if (fCreate) |
||||
nFlags |= DB_CREATE; |
||||
else if (fReadOnly) |
||||
nFlags |= DB_RDONLY; |
||||
if (!fReadOnly || fTxn) |
||||
nFlags |= DB_AUTO_COMMIT; |
||||
|
||||
CRITICAL_BLOCK(cs_db) |
||||
{ |
||||
if (!fDbEnvInit) |
||||
{ |
||||
string strAppDir = GetAppDir(); |
||||
string strLogDir = strAppDir + "\\database"; |
||||
_mkdir(strLogDir.c_str()); |
||||
printf("dbenv.open strAppDir=%s\n", strAppDir.c_str()); |
||||
|
||||
dbenv.set_lg_dir(strLogDir.c_str()); |
||||
dbenv.set_lg_max(10000000); |
||||
dbenv.set_lk_max_locks(10000); |
||||
dbenv.set_lk_max_objects(10000); |
||||
dbenv.set_errfile(fopen("db.log", "a")); /// debug
|
||||
///dbenv.log_set_config(DB_LOG_AUTO_REMOVE, 1); /// causes corruption
|
||||
ret = dbenv.open(strAppDir.c_str(), |
||||
DB_CREATE | |
||||
DB_INIT_LOCK | |
||||
DB_INIT_LOG | |
||||
DB_INIT_MPOOL | |
||||
DB_INIT_TXN | |
||||
DB_THREAD | |
||||
DB_PRIVATE | |
||||
DB_RECOVER, |
||||
0); |
||||
if (ret > 0) |
||||
throw runtime_error(strprintf("CDB() : error %d opening database environment\n", ret)); |
||||
fDbEnvInit = true; |
||||
} |
||||
|
||||
strFile = pszFile; |
||||
++mapFileUseCount[strFile]; |
||||
} |
||||
|
||||
pdb = new Db(&dbenv, 0); |
||||
|
||||
ret = pdb->open(NULL, // Txn pointer
|
||||
pszFile, // Filename
|
||||
"main", // Logical db name
|
||||
DB_BTREE, // Database type
|
||||
nFlags, // Flags
|
||||
0); |
||||
|
||||
if (ret > 0) |
||||
{ |
||||
delete pdb; |
||||
pdb = NULL; |
||||
CRITICAL_BLOCK(cs_db) |
||||
--mapFileUseCount[strFile]; |
||||
strFile = ""; |
||||
throw runtime_error(strprintf("CDB() : can't open database file %s, error %d\n", pszFile, ret)); |
||||
} |
||||
|
||||
if (fCreate && !Exists(string("version"))) |
||||
WriteVersion(VERSION); |
||||
|
||||
RandAddSeed(); |
||||
} |
||||
|
||||
void CDB::Close() |
||||
{ |
||||
if (!pdb) |
||||
return; |
||||
if (!vTxn.empty()) |
||||
vTxn.front()->abort(); |
||||
vTxn.clear(); |
||||
pdb->close(0); |
||||
delete pdb; |
||||
pdb = NULL; |
||||
dbenv.txn_checkpoint(0, 0, 0); |
||||
|
||||
CRITICAL_BLOCK(cs_db) |
||||
--mapFileUseCount[strFile]; |
||||
|
||||
RandAddSeed(); |
||||
} |
||||
|
||||
void DBFlush(bool fShutdown) |
||||
{ |
||||
// Flush log data to the actual data file
|
||||
// on all files that are not in use
|
||||
printf("DBFlush(%s)\n", fShutdown ? "true" : "false"); |
||||
CRITICAL_BLOCK(cs_db) |
||||
{ |
||||
dbenv.txn_checkpoint(0, 0, 0); |
||||
map<string, int>::iterator mi = mapFileUseCount.begin(); |
||||
while (mi != mapFileUseCount.end()) |
||||
{ |
||||
string strFile = (*mi).first; |
||||
int nRefCount = (*mi).second; |
||||
if (nRefCount == 0) |
||||
{ |
||||
dbenv.lsn_reset(strFile.c_str(), 0); |
||||
mapFileUseCount.erase(mi++); |
||||
} |
||||
else |
||||
mi++; |
||||
} |
||||
if (fShutdown) |
||||
{ |
||||
char** listp; |
||||
if (mapFileUseCount.empty()) |
||||
dbenv.log_archive(&listp, DB_ARCH_REMOVE); |
||||
dbenv.close(0); |
||||
fDbEnvInit = false; |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// CTxDB
|
||||
//
|
||||
|
||||
bool CTxDB::ReadTxIndex(uint256 hash, CTxIndex& txindex) |
||||
{ |
||||
assert(!fClient); |
||||
txindex.SetNull(); |
||||
return Read(make_pair(string("tx"), hash), txindex); |
||||
} |
||||
|
||||
bool CTxDB::UpdateTxIndex(uint256 hash, const CTxIndex& txindex) |
||||
{ |
||||
assert(!fClient); |
||||
return Write(make_pair(string("tx"), hash), txindex); |
||||
} |
||||
|
||||
bool CTxDB::AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight) |
||||
{ |
||||
assert(!fClient); |
||||
|
||||
// Add to tx index
|
||||
uint256 hash = tx.GetHash(); |
||||
CTxIndex txindex(pos, tx.vout.size()); |
||||
return Write(make_pair(string("tx"), hash), txindex); |
||||
} |
||||
|
||||
bool CTxDB::EraseTxIndex(const CTransaction& tx) |
||||
{ |
||||
assert(!fClient); |
||||
uint256 hash = tx.GetHash(); |
||||
|
||||
return Erase(make_pair(string("tx"), hash)); |
||||
} |
||||
|
||||
bool CTxDB::ContainsTx(uint256 hash) |
||||
{ |
||||
assert(!fClient); |
||||
return Exists(make_pair(string("tx"), hash)); |
||||
} |
||||
|
||||
bool CTxDB::ReadOwnerTxes(uint160 hash160, int nMinHeight, vector<CTransaction>& vtx) |
||||
{ |
||||
assert(!fClient); |
||||
vtx.clear(); |
||||
|
||||
// Get cursor
|
||||
Dbc* pcursor = GetCursor(); |
||||
if (!pcursor) |
||||
return false; |
||||
|
||||
unsigned int fFlags = DB_SET_RANGE; |
||||
loop |
||||
{ |
||||
// Read next record
|
||||
CDataStream ssKey; |
||||
if (fFlags == DB_SET_RANGE) |
||||
ssKey << string("owner") << hash160 << CDiskTxPos(0, 0, 0); |
||||
CDataStream ssValue; |
||||
int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags); |
||||
fFlags = DB_NEXT; |
||||
if (ret == DB_NOTFOUND) |
||||
break; |
||||
else if (ret != 0) |
||||
return false; |
||||
|
||||
// Unserialize
|
||||
string strType; |
||||
uint160 hashItem; |
||||
CDiskTxPos pos; |
||||
ssKey >> strType >> hashItem >> pos; |
||||
int nItemHeight; |
||||
ssValue >> nItemHeight; |
||||
|
||||
// Read transaction
|
||||
if (strType != "owner" || hashItem != hash160) |
||||
break; |
||||
if (nItemHeight >= nMinHeight) |
||||
{ |
||||
vtx.resize(vtx.size()+1); |
||||
if (!vtx.back().ReadFromDisk(pos)) |
||||
return false; |
||||
} |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
bool CTxDB::ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex) |
||||
{ |
||||
assert(!fClient); |
||||
tx.SetNull(); |
||||
if (!ReadTxIndex(hash, txindex)) |
||||
return false; |
||||
return (tx.ReadFromDisk(txindex.pos)); |
||||
} |
||||
|
||||
bool CTxDB::ReadDiskTx(uint256 hash, CTransaction& tx) |
||||
{ |
||||
CTxIndex txindex; |
||||
return ReadDiskTx(hash, tx, txindex); |
||||
} |
||||
|
||||
bool CTxDB::ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex) |
||||
{ |
||||
return ReadDiskTx(outpoint.hash, tx, txindex); |
||||
} |
||||
|
||||
bool CTxDB::ReadDiskTx(COutPoint outpoint, CTransaction& tx) |
||||
{ |
||||
CTxIndex txindex; |
||||
return ReadDiskTx(outpoint.hash, tx, txindex); |
||||
} |
||||
|
||||
bool CTxDB::WriteBlockIndex(const CDiskBlockIndex& blockindex) |
||||
{ |
||||
return Write(make_pair(string("blockindex"), blockindex.GetBlockHash()), blockindex); |
||||
} |
||||
|
||||
bool CTxDB::EraseBlockIndex(uint256 hash) |
||||
{ |
||||
return Erase(make_pair(string("blockindex"), hash)); |
||||
} |
||||
|
||||
bool CTxDB::ReadHashBestChain(uint256& hashBestChain) |
||||
{ |
||||
return Read(string("hashBestChain"), hashBestChain); |
||||
} |
||||
|
||||
bool CTxDB::WriteHashBestChain(uint256 hashBestChain) |
||||
{ |
||||
return Write(string("hashBestChain"), hashBestChain); |
||||
} |
||||
|
||||
CBlockIndex* InsertBlockIndex(uint256 hash) |
||||
{ |
||||
if (hash == 0) |
||||
return NULL; |
||||
|
||||
// Return existing
|
||||
map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash); |
||||
if (mi != mapBlockIndex.end()) |
||||
return (*mi).second; |
||||
|
||||
// Create new
|
||||
CBlockIndex* pindexNew = new CBlockIndex(); |
||||
if (!pindexNew) |
||||
throw runtime_error("LoadBlockIndex() : new CBlockIndex failed"); |
||||
mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first; |
||||
pindexNew->phashBlock = &((*mi).first); |
||||
|
||||
return pindexNew; |
||||
} |
||||
|
||||
bool CTxDB::LoadBlockIndex() |
||||
{ |
||||
// Get cursor
|
||||
Dbc* pcursor = GetCursor(); |
||||
if (!pcursor) |
||||
return false; |
||||
|
||||
unsigned int fFlags = DB_SET_RANGE; |
||||
loop |
||||
{ |
||||
// Read next record
|
||||
CDataStream ssKey; |
||||
if (fFlags == DB_SET_RANGE) |
||||
ssKey << make_pair(string("blockindex"), uint256(0)); |
||||
CDataStream ssValue; |
||||
int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags); |
||||
fFlags = DB_NEXT; |
||||
if (ret == DB_NOTFOUND) |
||||
break; |
||||
else if (ret != 0) |
||||
return false; |
||||
|
||||
// Unserialize
|
||||
string strType; |
||||
ssKey >> strType; |
||||
if (strType == "blockindex") |
||||
{ |
||||
CDiskBlockIndex diskindex; |
||||
ssValue >> diskindex; |
||||
|
||||
// Construct block index object
|
||||
CBlockIndex* pindexNew = InsertBlockIndex(diskindex.GetBlockHash()); |
||||
pindexNew->pprev = InsertBlockIndex(diskindex.hashPrev); |
||||
pindexNew->pnext = InsertBlockIndex(diskindex.hashNext); |
||||
pindexNew->nFile = diskindex.nFile; |
||||
pindexNew->nBlockPos = diskindex.nBlockPos; |
||||
pindexNew->nHeight = diskindex.nHeight; |
||||
pindexNew->nVersion = diskindex.nVersion; |
||||
pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot; |
||||
pindexNew->nTime = diskindex.nTime; |
||||
pindexNew->nBits = diskindex.nBits; |
||||
pindexNew->nNonce = diskindex.nNonce; |
||||
|
||||
// Watch for genesis block and best block
|
||||
if (pindexGenesisBlock == NULL && diskindex.GetBlockHash() == hashGenesisBlock) |
||||
pindexGenesisBlock = pindexNew; |
||||
} |
||||
else |
||||
{ |
||||
break; |
||||
} |
||||
} |
||||
|
||||
if (!ReadHashBestChain(hashBestChain)) |
||||
{ |
||||
if (pindexGenesisBlock == NULL) |
||||
return true; |
||||
return error("CTxDB::LoadBlockIndex() : hashBestChain not found\n"); |
||||
} |
||||
|
||||
if (!mapBlockIndex.count(hashBestChain)) |
||||
return error("CTxDB::LoadBlockIndex() : blockindex for hashBestChain not found\n"); |
||||
pindexBest = mapBlockIndex[hashBestChain]; |
||||
nBestHeight = pindexBest->nHeight; |
||||
printf("LoadBlockIndex(): hashBestChain=%s height=%d\n", hashBestChain.ToString().substr(0,14).c_str(), nBestHeight); |
||||
|
||||
return true; |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// CAddrDB
|
||||
//
|
||||
|
||||
bool CAddrDB::WriteAddress(const CAddress& addr) |
||||
{ |
||||
return Write(make_pair(string("addr"), addr.GetKey()), addr); |
||||
} |
||||
|
||||
bool CAddrDB::LoadAddresses() |
||||
{ |
||||
CRITICAL_BLOCK(cs_mapIRCAddresses) |
||||
CRITICAL_BLOCK(cs_mapAddresses) |
||||
{ |
||||
// Load user provided addresses
|
||||
CAutoFile filein = fopen("addr.txt", "rt"); |
||||
if (filein) |
||||
{ |
||||
try |
||||
{ |
||||
char psz[1000]; |
||||
while (fgets(psz, sizeof(psz), filein)) |
||||
{ |
||||
CAddress addr(psz, NODE_NETWORK); |
||||
if (addr.ip != 0) |
||||
{ |
||||
AddAddress(*this, addr); |
||||
mapIRCAddresses.insert(make_pair(addr.GetKey(), addr)); |
||||
} |
||||
} |
||||
} |
||||
catch (...) { } |
||||
} |
||||
|
||||
// Get cursor
|
||||
Dbc* pcursor = GetCursor(); |
||||
if (!pcursor) |
||||
return false; |
||||
|
||||
loop |
||||
{ |
||||
// Read next record
|
||||
CDataStream ssKey; |
||||
CDataStream ssValue; |
||||
int ret = ReadAtCursor(pcursor, ssKey, ssValue); |
||||
if (ret == DB_NOTFOUND) |
||||
break; |
||||
else if (ret != 0) |
||||
return false; |
||||
|
||||
// Unserialize
|
||||
string strType; |
||||
ssKey >> strType; |
||||
if (strType == "addr") |
||||
{ |
||||
CAddress addr; |
||||
ssValue >> addr; |
||||
mapAddresses.insert(make_pair(addr.GetKey(), addr)); |
||||
} |
||||
} |
||||
|
||||
//// debug print
|
||||
printf("mapAddresses:\n"); |
||||
foreach(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses) |
||||
item.second.print(); |
||||
printf("-----\n"); |
||||
|
||||
// Fix for possible bug that manifests in mapAddresses.count in irc.cpp,
|
||||
// just need to call count here and it doesn't happen there. The bug was the
|
||||
// pack pragma in irc.cpp and has been fixed, but I'm not in a hurry to delete this.
|
||||
mapAddresses.count(vector<unsigned char>(18)); |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
bool LoadAddresses() |
||||
{ |
||||
return CAddrDB("cr+").LoadAddresses(); |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// CReviewDB
|
||||
//
|
||||
|
||||
bool CReviewDB::ReadReviews(uint256 hash, vector<CReview>& vReviews) |
||||
{ |
||||
vReviews.size(); // msvc workaround, just need to do anything with vReviews
|
||||
return Read(make_pair(string("reviews"), hash), vReviews); |
||||
} |
||||
|
||||
bool CReviewDB::WriteReviews(uint256 hash, const vector<CReview>& vReviews) |
||||
{ |
||||
return Write(make_pair(string("reviews"), hash), vReviews); |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// CWalletDB
|
||||
//
|
||||
|
||||
bool CWalletDB::LoadWallet(vector<unsigned char>& vchDefaultKeyRet) |
||||
{ |
||||
vchDefaultKeyRet.clear(); |
||||
|
||||
//// todo: shouldn't we catch exceptions and try to recover and continue?
|
||||
CRITICAL_BLOCK(cs_mapKeys) |
||||
CRITICAL_BLOCK(cs_mapWallet) |
||||
{ |
||||
// Get cursor
|
||||
Dbc* pcursor = GetCursor(); |
||||
if (!pcursor) |
||||
return false; |
||||
|
||||
loop |
||||
{ |
||||
// Read next record
|
||||
CDataStream ssKey; |
||||
CDataStream ssValue; |
||||
int ret = ReadAtCursor(pcursor, ssKey, ssValue); |
||||
if (ret == DB_NOTFOUND) |
||||
break; |
||||
else if (ret != 0) |
||||
return false; |
||||
|
||||
// Unserialize
|
||||
// Taking advantage of the fact that pair serialization
|
||||
// is just the two items serialized one after the other
|
||||
string strType; |
||||
ssKey >> strType; |
||||
if (strType == "name") |
||||
{ |
||||
string strAddress; |
||||
ssKey >> strAddress; |
||||
ssValue >> mapAddressBook[strAddress]; |
||||
} |
||||
else if (strType == "tx") |
||||
{ |
||||
uint256 hash; |
||||
ssKey >> hash; |
||||
CWalletTx& wtx = mapWallet[hash]; |
||||
ssValue >> wtx; |
||||
|
||||
if (wtx.GetHash() != hash) |
||||
printf("Error in wallet.dat, hash mismatch\n"); |
||||
|
||||
//// debug print
|
||||
//printf("LoadWallet %s\n", wtx.GetHash().ToString().c_str());
|
||||
//printf(" %12I64d %s %s %s\n",
|
||||
// wtx.vout[0].nValue,
|
||||
// DateTimeStr(wtx.nTime).c_str(),
|
||||
// wtx.hashBlock.ToString().substr(0,14).c_str(),
|
||||
// wtx.mapValue["message"].c_str());
|
||||
} |
||||
else if (strType == "key") |
||||
{ |
||||
vector<unsigned char> vchPubKey; |
||||
ssKey >> vchPubKey; |
||||
CPrivKey vchPrivKey; |
||||
ssValue >> vchPrivKey; |
||||
|
||||
mapKeys[vchPubKey] = vchPrivKey; |
||||
mapPubKeys[Hash160(vchPubKey)] = vchPubKey; |
||||
} |
||||
else if (strType == "defaultkey") |
||||
{ |
||||
ssValue >> vchDefaultKeyRet; |
||||
} |
||||
else if (strType == "setting") /// or settings or option or options or config?
|
||||
{ |
||||
string strKey; |
||||
ssKey >> strKey; |
||||
if (strKey == "fGenerateBitcoins") ssValue >> fGenerateBitcoins; |
||||
if (strKey == "nTransactionFee") ssValue >> nTransactionFee; |
||||
if (strKey == "addrIncoming") ssValue >> addrIncoming; |
||||
} |
||||
} |
||||
} |
||||
|
||||
printf("fGenerateBitcoins = %d\n", fGenerateBitcoins); |
||||
printf("nTransactionFee = %I64d\n", nTransactionFee); |
||||
printf("addrIncoming = %s\n", addrIncoming.ToString().c_str()); |
||||
|
||||
return true; |
||||
} |
||||
|
||||
bool LoadWallet() |
||||
{ |
||||
vector<unsigned char> vchDefaultKey; |
||||
if (!CWalletDB("cr").LoadWallet(vchDefaultKey)) |
||||
return false; |
||||
|
||||
if (mapKeys.count(vchDefaultKey)) |
||||
{ |
||||
// Set keyUser
|
||||
keyUser.SetPubKey(vchDefaultKey); |
||||
keyUser.SetPrivKey(mapKeys[vchDefaultKey]); |
||||
} |
||||
else |
||||
{ |
||||
// Create new keyUser and set as default key
|
||||
RandAddSeed(true); |
||||
keyUser.MakeNewKey(); |
||||
if (!AddKey(keyUser)) |
||||
return false; |
||||
if (!SetAddressBookName(PubKeyToAddress(keyUser.GetPubKey()), "Your Address")) |
||||
return false; |
||||
CWalletDB().WriteDefaultKey(keyUser.GetPubKey()); |
||||
} |
||||
|
||||
return true; |
||||
} |
@ -0,0 +1,420 @@
@@ -0,0 +1,420 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <db_cxx.h> |
||||
class CTransaction; |
||||
class CTxIndex; |
||||
class CDiskBlockIndex; |
||||
class CDiskTxPos; |
||||
class COutPoint; |
||||
class CUser; |
||||
class CReview; |
||||
class CAddress; |
||||
class CWalletTx; |
||||
|
||||
extern map<string, string> mapAddressBook; |
||||
extern bool fClient; |
||||
|
||||
|
||||
extern DbEnv dbenv; |
||||
extern void DBFlush(bool fShutdown); |
||||
|
||||
|
||||
|
||||
|
||||
class CDB |
||||
{ |
||||
protected: |
||||
Db* pdb; |
||||
string strFile; |
||||
vector<DbTxn*> vTxn; |
||||
|
||||
explicit CDB(const char* pszFile, const char* pszMode="r+", bool fTxn=false); |
||||
~CDB() { Close(); } |
||||
public: |
||||
void Close(); |
||||
private: |
||||
CDB(const CDB&); |
||||
void operator=(const CDB&); |
||||
|
||||
protected: |
||||
template<typename K, typename T> |
||||
bool Read(const K& key, T& value) |
||||
{ |
||||
if (!pdb) |
||||
return false; |
||||
|
||||
// Key
|
||||
CDataStream ssKey(SER_DISK); |
||||
ssKey.reserve(1000); |
||||
ssKey << key; |
||||
Dbt datKey(&ssKey[0], ssKey.size()); |
||||
|
||||
// Read
|
||||
Dbt datValue; |
||||
datValue.set_flags(DB_DBT_MALLOC); |
||||
int ret = pdb->get(GetTxn(), &datKey, &datValue, 0); |
||||
memset(datKey.get_data(), 0, datKey.get_size()); |
||||
if (datValue.get_data() == NULL) |
||||
return false; |
||||
|
||||
// Unserialize value
|
||||
CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK); |
||||
ssValue >> value; |
||||
|
||||
// Clear and free memory
|
||||
memset(datValue.get_data(), 0, datValue.get_size()); |
||||
free(datValue.get_data()); |
||||
return (ret == 0); |
||||
} |
||||
|
||||
template<typename K, typename T> |
||||
bool Write(const K& key, const T& value, bool fOverwrite=true) |
||||
{ |
||||
if (!pdb) |
||||
return false; |
||||
|
||||
// Key
|
||||
CDataStream ssKey(SER_DISK); |
||||
ssKey.reserve(1000); |
||||
ssKey << key; |
||||
Dbt datKey(&ssKey[0], ssKey.size()); |
||||
|
||||
// Value
|
||||
CDataStream ssValue(SER_DISK); |
||||
ssValue.reserve(10000); |
||||
ssValue << value; |
||||
Dbt datValue(&ssValue[0], ssValue.size()); |
||||
|
||||
// Write
|
||||
int ret = pdb->put(GetTxn(), &datKey, &datValue, (fOverwrite ? 0 : DB_NOOVERWRITE)); |
||||
|
||||
// Clear memory in case it was a private key
|
||||
memset(datKey.get_data(), 0, datKey.get_size()); |
||||
memset(datValue.get_data(), 0, datValue.get_size()); |
||||
return (ret == 0); |
||||
} |
||||
|
||||
template<typename K> |
||||
bool Erase(const K& key) |
||||
{ |
||||
if (!pdb) |
||||
return false; |
||||
|
||||
// Key
|
||||
CDataStream ssKey(SER_DISK); |
||||
ssKey.reserve(1000); |
||||
ssKey << key; |
||||
Dbt datKey(&ssKey[0], ssKey.size()); |
||||
|
||||
// Erase
|
||||
int ret = pdb->del(GetTxn(), &datKey, 0); |
||||
|
||||
// Clear memory
|
||||
memset(datKey.get_data(), 0, datKey.get_size()); |
||||
return (ret == 0 || ret == DB_NOTFOUND); |
||||
} |
||||
|
||||
template<typename K> |
||||
bool Exists(const K& key) |
||||
{ |
||||
if (!pdb) |
||||
return false; |
||||
|
||||
// Key
|
||||
CDataStream ssKey(SER_DISK); |
||||
ssKey.reserve(1000); |
||||
ssKey << key; |
||||
Dbt datKey(&ssKey[0], ssKey.size()); |
||||
|
||||
// Exists
|
||||
int ret = pdb->exists(GetTxn(), &datKey, 0); |
||||
|
||||
// Clear memory
|
||||
memset(datKey.get_data(), 0, datKey.get_size()); |
||||
return (ret == 0); |
||||
} |
||||
|
||||
Dbc* GetCursor() |
||||
{ |
||||
if (!pdb) |
||||
return NULL; |
||||
Dbc* pcursor = NULL; |
||||
int ret = pdb->cursor(NULL, &pcursor, 0); |
||||
if (ret != 0) |
||||
return NULL; |
||||
return pcursor; |
||||
} |
||||
|
||||
int ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue, unsigned int fFlags=DB_NEXT) |
||||
{ |
||||
// Read at cursor
|
||||
Dbt datKey; |
||||
if (fFlags == DB_SET || fFlags == DB_SET_RANGE || fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE) |
||||
{ |
||||
datKey.set_data(&ssKey[0]); |
||||
datKey.set_size(ssKey.size()); |
||||
} |
||||
Dbt datValue; |
||||
if (fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE) |
||||
{ |
||||
datValue.set_data(&ssValue[0]); |
||||
datValue.set_size(ssValue.size()); |
||||
} |
||||
datKey.set_flags(DB_DBT_MALLOC); |
||||
datValue.set_flags(DB_DBT_MALLOC); |
||||
int ret = pcursor->get(&datKey, &datValue, fFlags); |
||||
if (ret != 0) |
||||
return ret; |
||||
else if (datKey.get_data() == NULL || datValue.get_data() == NULL) |
||||
return 99999; |
||||
|
||||
// Convert to streams
|
||||
ssKey.SetType(SER_DISK); |
||||
ssKey.clear(); |
||||
ssKey.write((char*)datKey.get_data(), datKey.get_size()); |
||||
ssValue.SetType(SER_DISK); |
||||
ssValue.clear(); |
||||
ssValue.write((char*)datValue.get_data(), datValue.get_size()); |
||||
|
||||
// Clear and free memory
|
||||
memset(datKey.get_data(), 0, datKey.get_size()); |
||||
memset(datValue.get_data(), 0, datValue.get_size()); |
||||
free(datKey.get_data()); |
||||
free(datValue.get_data()); |
||||
return 0; |
||||
} |
||||
|
||||
DbTxn* GetTxn() |
||||
{ |
||||
if (!vTxn.empty()) |
||||
return vTxn.back(); |
||||
else |
||||
return NULL; |
||||
} |
||||
|
||||
public: |
||||
bool TxnBegin() |
||||
{ |
||||
if (!pdb) |
||||
return false; |
||||
DbTxn* ptxn = NULL; |
||||
int ret = dbenv.txn_begin(GetTxn(), &ptxn, 0); |
||||
if (!ptxn || ret != 0) |
||||
return false; |
||||
vTxn.push_back(ptxn); |
||||
return true; |
||||
} |
||||
|
||||
bool TxnCommit() |
||||
{ |
||||
if (!pdb) |
||||
return false; |
||||
if (vTxn.empty()) |
||||
return false; |
||||
int ret = vTxn.back()->commit(0); |
||||
vTxn.pop_back(); |
||||
return (ret == 0); |
||||
} |
||||
|
||||
bool TxnAbort() |
||||
{ |
||||
if (!pdb) |
||||
return false; |
||||
if (vTxn.empty()) |
||||
return false; |
||||
int ret = vTxn.back()->abort(); |
||||
vTxn.pop_back(); |
||||
return (ret == 0); |
||||
} |
||||
|
||||
bool ReadVersion(int& nVersion) |
||||
{ |
||||
nVersion = 0; |
||||
return Read(string("version"), nVersion); |
||||
} |
||||
|
||||
bool WriteVersion(int nVersion) |
||||
{ |
||||
return Write(string("version"), nVersion); |
||||
} |
||||
}; |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class CTxDB : public CDB |
||||
{ |
||||
public: |
||||
CTxDB(const char* pszMode="r+", bool fTxn=false) : CDB(!fClient ? "blkindex.dat" : NULL, pszMode, fTxn) { } |
||||
private: |
||||
CTxDB(const CTxDB&); |
||||
void operator=(const CTxDB&); |
||||
public: |
||||
bool ReadTxIndex(uint256 hash, CTxIndex& txindex); |
||||
bool UpdateTxIndex(uint256 hash, const CTxIndex& txindex); |
||||
bool AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight); |
||||
bool EraseTxIndex(const CTransaction& tx); |
||||
bool ContainsTx(uint256 hash); |
||||
bool ReadOwnerTxes(uint160 hash160, int nHeight, vector<CTransaction>& vtx); |
||||
bool ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex); |
||||
bool ReadDiskTx(uint256 hash, CTransaction& tx); |
||||
bool ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex); |
||||
bool ReadDiskTx(COutPoint outpoint, CTransaction& tx); |
||||
bool WriteBlockIndex(const CDiskBlockIndex& blockindex); |
||||
bool EraseBlockIndex(uint256 hash); |
||||
bool ReadHashBestChain(uint256& hashBestChain); |
||||
bool WriteHashBestChain(uint256 hashBestChain); |
||||
bool LoadBlockIndex(); |
||||
}; |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class CReviewDB : public CDB |
||||
{ |
||||
public: |
||||
CReviewDB(const char* pszMode="r+", bool fTxn=false) : CDB("reviews.dat", pszMode, fTxn) { } |
||||
private: |
||||
CReviewDB(const CReviewDB&); |
||||
void operator=(const CReviewDB&); |
||||
public: |
||||
bool ReadUser(uint256 hash, CUser& user) |
||||
{ |
||||
return Read(make_pair(string("user"), hash), user); |
||||
} |
||||
|
||||
bool WriteUser(uint256 hash, const CUser& user) |
||||
{ |
||||
return Write(make_pair(string("user"), hash), user); |
||||
} |
||||
|
||||
bool ReadReviews(uint256 hash, vector<CReview>& vReviews); |
||||
bool WriteReviews(uint256 hash, const vector<CReview>& vReviews); |
||||
}; |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class CMarketDB : public CDB |
||||
{ |
||||
public: |
||||
CMarketDB(const char* pszMode="r+", bool fTxn=false) : CDB("market.dat", pszMode, fTxn) { } |
||||
private: |
||||
CMarketDB(const CMarketDB&); |
||||
void operator=(const CMarketDB&); |
||||
}; |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class CAddrDB : public CDB |
||||
{ |
||||
public: |
||||
CAddrDB(const char* pszMode="r+", bool fTxn=false) : CDB("addr.dat", pszMode, fTxn) { } |
||||
private: |
||||
CAddrDB(const CAddrDB&); |
||||
void operator=(const CAddrDB&); |
||||
public: |
||||
bool WriteAddress(const CAddress& addr); |
||||
bool LoadAddresses(); |
||||
}; |
||||
|
||||
bool LoadAddresses(); |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class CWalletDB : public CDB |
||||
{ |
||||
public: |
||||
CWalletDB(const char* pszMode="r+", bool fTxn=false) : CDB("wallet.dat", pszMode, fTxn) { } |
||||
private: |
||||
CWalletDB(const CWalletDB&); |
||||
void operator=(const CWalletDB&); |
||||
public: |
||||
bool ReadName(const string& strAddress, string& strName) |
||||
{ |
||||
strName = ""; |
||||
return Read(make_pair(string("name"), strAddress), strName); |
||||
} |
||||
|
||||
bool WriteName(const string& strAddress, const string& strName) |
||||
{ |
||||
mapAddressBook[strAddress] = strName; |
||||
return Write(make_pair(string("name"), strAddress), strName); |
||||
} |
||||
|
||||
bool EraseName(const string& strAddress) |
||||
{ |
||||
mapAddressBook.erase(strAddress); |
||||
return Erase(make_pair(string("name"), strAddress)); |
||||
} |
||||
|
||||
bool ReadTx(uint256 hash, CWalletTx& wtx) |
||||
{ |
||||
return Read(make_pair(string("tx"), hash), wtx); |
||||
} |
||||
|
||||
bool WriteTx(uint256 hash, const CWalletTx& wtx) |
||||
{ |
||||
return Write(make_pair(string("tx"), hash), wtx); |
||||
} |
||||
|
||||
bool EraseTx(uint256 hash) |
||||
{ |
||||
return Erase(make_pair(string("tx"), hash)); |
||||
} |
||||
|
||||
bool ReadKey(const vector<unsigned char>& vchPubKey, CPrivKey& vchPrivKey) |
||||
{ |
||||
vchPrivKey.clear(); |
||||
return Read(make_pair(string("key"), vchPubKey), vchPrivKey); |
||||
} |
||||
|
||||
bool WriteKey(const vector<unsigned char>& vchPubKey, const CPrivKey& vchPrivKey) |
||||
{ |
||||
return Write(make_pair(string("key"), vchPubKey), vchPrivKey, false); |
||||
} |
||||
|
||||
bool ReadDefaultKey(vector<unsigned char>& vchPubKey) |
||||
{ |
||||
vchPubKey.clear(); |
||||
return Read(string("defaultkey"), vchPubKey); |
||||
} |
||||
|
||||
bool WriteDefaultKey(const vector<unsigned char>& vchPubKey) |
||||
{ |
||||
return Write(string("defaultkey"), vchPubKey); |
||||
} |
||||
|
||||
template<typename T> |
||||
bool ReadSetting(const string& strKey, T& value) |
||||
{ |
||||
return Read(make_pair(string("setting"), strKey), value); |
||||
} |
||||
|
||||
template<typename T> |
||||
bool WriteSetting(const string& strKey, const T& value) |
||||
{ |
||||
return Write(make_pair(string("setting"), strKey), value); |
||||
} |
||||
|
||||
bool LoadWallet(vector<unsigned char>& vchDefaultKeyRet); |
||||
}; |
||||
|
||||
bool LoadWallet(); |
||||
|
||||
inline bool SetAddressBookName(const string& strAddress, const string& strName) |
||||
{ |
||||
return CWalletDB().WriteName(strAddress, strName); |
||||
} |
@ -0,0 +1,71 @@
@@ -0,0 +1,71 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifdef _MSC_VER |
||||
#pragma warning(disable:4786) |
||||
#pragma warning(disable:4804) |
||||
#pragma warning(disable:4717) |
||||
#endif |
||||
#ifdef _WIN32_WINNT |
||||
#undef _WIN32_WINNT |
||||
#endif |
||||
#define _WIN32_WINNT 0x0400 |
||||
#define WIN32_LEAN_AND_MEAN 1 |
||||
#include <wx/wx.h> |
||||
#include <wx/clipbrd.h> |
||||
#include <wx/snglinst.h> |
||||
#include <openssl/ecdsa.h> |
||||
#include <openssl/evp.h> |
||||
#include <openssl/rand.h> |
||||
#include <openssl/sha.h> |
||||
#include <openssl/ripemd.h> |
||||
#include <windows.h> |
||||
#include <winsock2.h> |
||||
#include <mswsock.h> |
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <io.h> |
||||
#include <math.h> |
||||
#include <limits.h> |
||||
#include <float.h> |
||||
#include <assert.h> |
||||
#include <process.h> |
||||
#include <malloc.h> |
||||
#include <memory> |
||||
#define BOUNDSCHECK 1 |
||||
#include <sstream> |
||||
#include <string> |
||||
#include <vector> |
||||
#include <list> |
||||
#include <deque> |
||||
#include <map> |
||||
#include <set> |
||||
#include <algorithm> |
||||
#include <numeric> |
||||
#include <boost/foreach.hpp> |
||||
#include <boost/lexical_cast.hpp> |
||||
#include <boost/tuple/tuple.hpp> |
||||
#include <boost/tuple/tuple_comparison.hpp> |
||||
#include <boost/tuple/tuple_io.hpp> |
||||
#include <boost/array.hpp> |
||||
#pragma hdrstop |
||||
using namespace std; |
||||
using namespace boost; |
||||
|
||||
|
||||
|
||||
#include "serialize.h" |
||||
#include "uint256.h" |
||||
#include "util.h" |
||||
#include "key.h" |
||||
#include "bignum.h" |
||||
#include "base58.h" |
||||
#include "script.h" |
||||
#include "db.h" |
||||
#include "net.h" |
||||
#include "irc.h" |
||||
#include "main.h" |
||||
#include "market.h" |
||||
#include "uibase.h" |
||||
#include "ui.h" |
@ -0,0 +1,314 @@
@@ -0,0 +1,314 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "headers.h" |
||||
|
||||
|
||||
map<vector<unsigned char>, CAddress> mapIRCAddresses; |
||||
CCriticalSection cs_mapIRCAddresses; |
||||
|
||||
|
||||
|
||||
|
||||
#pragma pack(push, 1) |
||||
struct ircaddr |
||||
{ |
||||
int ip; |
||||
short port; |
||||
}; |
||||
#pragma pack(pop) |
||||
|
||||
string EncodeAddress(const CAddress& addr) |
||||
{ |
||||
struct ircaddr tmp; |
||||
tmp.ip = addr.ip; |
||||
tmp.port = addr.port; |
||||
|
||||
vector<unsigned char> vch(UBEGIN(tmp), UEND(tmp)); |
||||
return string("u") + EncodeBase58Check(vch); |
||||
} |
||||
|
||||
bool DecodeAddress(string str, CAddress& addr) |
||||
{ |
||||
vector<unsigned char> vch; |
||||
if (!DecodeBase58Check(str.substr(1), vch)) |
||||
return false; |
||||
|
||||
struct ircaddr tmp; |
||||
if (vch.size() != sizeof(tmp)) |
||||
return false; |
||||
memcpy(&tmp, &vch[0], sizeof(tmp)); |
||||
|
||||
addr = CAddress(tmp.ip, tmp.port); |
||||
return true; |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static bool Send(SOCKET hSocket, const char* pszSend) |
||||
{ |
||||
if (strstr(pszSend, "PONG") != pszSend) |
||||
printf("SENDING: %s\n", pszSend); |
||||
const char* psz = pszSend; |
||||
const char* pszEnd = psz + strlen(psz); |
||||
while (psz < pszEnd) |
||||
{ |
||||
int ret = send(hSocket, psz, pszEnd - psz, 0); |
||||
if (ret < 0) |
||||
return false; |
||||
psz += ret; |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
bool RecvLine(SOCKET hSocket, string& strLine) |
||||
{ |
||||
strLine = ""; |
||||
loop |
||||
{ |
||||
char c; |
||||
int nBytes = recv(hSocket, &c, 1, 0); |
||||
if (nBytes > 0) |
||||
{ |
||||
if (c == '\n') |
||||
continue; |
||||
if (c == '\r') |
||||
return true; |
||||
strLine += c; |
||||
} |
||||
else if (nBytes <= 0) |
||||
{ |
||||
if (!strLine.empty()) |
||||
return true; |
||||
// socket closed
|
||||
printf("IRC socket closed\n"); |
||||
return false; |
||||
} |
||||
else |
||||
{ |
||||
// socket error
|
||||
int nErr = WSAGetLastError(); |
||||
if (nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS) |
||||
{ |
||||
printf("IRC recv failed: %d\n", nErr); |
||||
return false; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
bool RecvLineIRC(SOCKET hSocket, string& strLine) |
||||
{ |
||||
loop |
||||
{ |
||||
bool fRet = RecvLine(hSocket, strLine); |
||||
if (fRet) |
||||
{ |
||||
if (fShutdown) |
||||
return false; |
||||
vector<string> vWords; |
||||
ParseString(strLine, ' ', vWords); |
||||
if (vWords[0] == "PING") |
||||
{ |
||||
strLine[1] = 'O'; |
||||
strLine += '\r'; |
||||
Send(hSocket, strLine.c_str()); |
||||
continue; |
||||
} |
||||
} |
||||
return fRet; |
||||
} |
||||
} |
||||
|
||||
bool RecvUntil(SOCKET hSocket, const char* psz1, const char* psz2=NULL, const char* psz3=NULL) |
||||
{ |
||||
loop |
||||
{ |
||||
string strLine; |
||||
if (!RecvLineIRC(hSocket, strLine)) |
||||
return false; |
||||
printf("IRC %s\n", strLine.c_str()); |
||||
if (psz1 && strLine.find(psz1) != -1) |
||||
return true; |
||||
if (psz2 && strLine.find(psz2) != -1) |
||||
return true; |
||||
if (psz3 && strLine.find(psz3) != -1) |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
bool Wait(int nSeconds) |
||||
{ |
||||
if (fShutdown) |
||||
return false; |
||||
printf("Waiting %d seconds to reconnect to IRC\n", nSeconds); |
||||
for (int i = 0; i < nSeconds; i++) |
||||
{ |
||||
if (fShutdown) |
||||
return false; |
||||
Sleep(1000); |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
|
||||
|
||||
void ThreadIRCSeed(void* parg) |
||||
{ |
||||
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL); |
||||
int nErrorWait = 10; |
||||
int nRetryWait = 10; |
||||
|
||||
while (!fShutdown) |
||||
{ |
||||
CAddress addrConnect("216.155.130.130:6667"); |
||||
struct hostent* phostent = gethostbyname("chat.freenode.net"); |
||||
if (phostent && phostent->h_addr_list && phostent->h_addr_list[0]) |
||||
addrConnect = CAddress(*(u_long*)phostent->h_addr_list[0], htons(6667)); |
||||
|
||||
SOCKET hSocket; |
||||
if (!ConnectSocket(addrConnect, hSocket)) |
||||
{ |
||||
printf("IRC connect failed\n"); |
||||
nErrorWait = nErrorWait * 11 / 10; |
||||
if (Wait(nErrorWait += 60)) |
||||
continue; |
||||
else |
||||
return; |
||||
} |
||||
|
||||
if (!RecvUntil(hSocket, "Found your hostname", "using your IP address instead", "Couldn't look up your hostname")) |
||||
{ |
||||
closesocket(hSocket); |
||||
nErrorWait = nErrorWait * 11 / 10; |
||||
if (Wait(nErrorWait += 60)) |
||||
continue; |
||||
else |
||||
return; |
||||
} |
||||
|
||||
string strMyName = EncodeAddress(addrLocalHost); |
||||
|
||||
if (!addrLocalHost.IsRoutable()) |
||||
strMyName = strprintf("x%u", GetRand(1000000000)); |
||||
|
||||
|
||||
Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str()); |
||||
Send(hSocket, strprintf("USER %s 8 * : %s\r", strMyName.c_str(), strMyName.c_str()).c_str()); |
||||
|
||||
if (!RecvUntil(hSocket, " 004 ")) |
||||
{ |
||||
closesocket(hSocket); |
||||
nErrorWait = nErrorWait * 11 / 10; |
||||
if (Wait(nErrorWait += 60)) |
||||
continue; |
||||
else |
||||
return; |
||||
} |
||||
Sleep(500); |
||||
|
||||
Send(hSocket, "JOIN #bitcoin\r"); |
||||
Send(hSocket, "WHO #bitcoin\r"); |
||||
|
||||
int64 nStart = GetTime(); |
||||
string strLine; |
||||
while (!fShutdown && RecvLineIRC(hSocket, strLine)) |
||||
{ |
||||
if (strLine.empty() || strLine.size() > 900 || strLine[0] != ':') |
||||
continue; |
||||
printf("IRC %s\n", strLine.c_str()); |
||||
|
||||
vector<string> vWords; |
||||
ParseString(strLine, ' ', vWords); |
||||
if (vWords.size() < 2) |
||||
continue; |
||||
|
||||
char pszName[10000]; |
||||
pszName[0] = '\0'; |
||||
|
||||
if (vWords[1] == "352" && vWords.size() >= 8) |
||||
{ |
||||
// index 7 is limited to 16 characters
|
||||
// could get full length name at index 10, but would be different from join messages
|
||||
strcpy(pszName, vWords[7].c_str()); |
||||
printf("GOT WHO: [%s] ", pszName); |
||||
} |
||||
|
||||
if (vWords[1] == "JOIN" && vWords[0].size() > 1) |
||||
{ |
||||
// :username!username@50000007.F000000B.90000002.IP JOIN :#channelname
|
||||
strcpy(pszName, vWords[0].c_str() + 1); |
||||
if (strchr(pszName, '!')) |
||||
*strchr(pszName, '!') = '\0'; |
||||
printf("GOT JOIN: [%s] ", pszName); |
||||
} |
||||
|
||||
if (pszName[0] == 'u') |
||||
{ |
||||
CAddress addr; |
||||
if (DecodeAddress(pszName, addr)) |
||||
{ |
||||
CAddrDB addrdb; |
||||
if (AddAddress(addrdb, addr)) |
||||
printf("new "); |
||||
else |
||||
{ |
||||
// make it try connecting again
|
||||
CRITICAL_BLOCK(cs_mapAddresses) |
||||
if (mapAddresses.count(addr.GetKey())) |
||||
mapAddresses[addr.GetKey()].nLastFailed = 0; |
||||
} |
||||
addr.print(); |
||||
|
||||
CRITICAL_BLOCK(cs_mapIRCAddresses) |
||||
mapIRCAddresses.insert(make_pair(addr.GetKey(), addr)); |
||||
} |
||||
else |
||||
{ |
||||
printf("decode failed\n"); |
||||
} |
||||
} |
||||
} |
||||
closesocket(hSocket); |
||||
|
||||
if (GetTime() - nStart > 20 * 60) |
||||
{ |
||||
nErrorWait /= 3; |
||||
nRetryWait /= 3; |
||||
} |
||||
|
||||
nRetryWait = nRetryWait * 11 / 10; |
||||
if (!Wait(nRetryWait += 60)) |
||||
return; |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef TEST |
||||
int main(int argc, char *argv[]) |
||||
{ |
||||
WSADATA wsadata; |
||||
if (WSAStartup(MAKEWORD(2,2), &wsadata) != NO_ERROR) |
||||
{ |
||||
printf("Error at WSAStartup()\n"); |
||||
return false; |
||||
} |
||||
|
||||
ThreadIRCSeed(NULL); |
||||
|
||||
WSACleanup(); |
||||
return 0; |
||||
} |
||||
#endif |
@ -0,0 +1,10 @@
@@ -0,0 +1,10 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
extern bool RecvLine(SOCKET hSocket, string& strLine); |
||||
extern void ThreadIRCSeed(void* parg); |
||||
extern bool fRestartIRCSeed; |
||||
|
||||
extern map<vector<unsigned char>, CAddress> mapIRCAddresses; |
||||
extern CCriticalSection cs_mapIRCAddresses; |
@ -0,0 +1,156 @@
@@ -0,0 +1,156 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
// secp160k1
|
||||
// const unsigned int PRIVATE_KEY_SIZE = 192;
|
||||
// const unsigned int PUBLIC_KEY_SIZE = 41;
|
||||
// const unsigned int SIGNATURE_SIZE = 48;
|
||||
//
|
||||
// secp192k1
|
||||
// const unsigned int PRIVATE_KEY_SIZE = 222;
|
||||
// const unsigned int PUBLIC_KEY_SIZE = 49;
|
||||
// const unsigned int SIGNATURE_SIZE = 57;
|
||||
//
|
||||
// secp224k1
|
||||
// const unsigned int PRIVATE_KEY_SIZE = 250;
|
||||
// const unsigned int PUBLIC_KEY_SIZE = 57;
|
||||
// const unsigned int SIGNATURE_SIZE = 66;
|
||||
//
|
||||
// secp256k1:
|
||||
// const unsigned int PRIVATE_KEY_SIZE = 279;
|
||||
// const unsigned int PUBLIC_KEY_SIZE = 65;
|
||||
// const unsigned int SIGNATURE_SIZE = 72;
|
||||
//
|
||||
// see www.keylength.com
|
||||
// script supports up to 75 for single byte push
|
||||
|
||||
|
||||
|
||||
class key_error : public std::runtime_error |
||||
{ |
||||
public: |
||||
explicit key_error(const std::string& str) : std::runtime_error(str) {} |
||||
}; |
||||
|
||||
|
||||
// secure_allocator is defined is serialize.h
|
||||
typedef vector<unsigned char, secure_allocator<unsigned char> > CPrivKey; |
||||
|
||||
|
||||
|
||||
class CKey |
||||
{ |
||||
protected: |
||||
EC_KEY* pkey; |
||||
|
||||
public: |
||||
CKey() |
||||
{ |
||||
pkey = EC_KEY_new_by_curve_name(NID_secp256k1); |
||||
if (pkey == NULL) |
||||
throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed"); |
||||
} |
||||
|
||||
CKey(const CKey& b) |
||||
{ |
||||
pkey = EC_KEY_dup(b.pkey); |
||||
if (pkey == NULL) |
||||
throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed"); |
||||
} |
||||
|
||||
CKey& operator=(const CKey& b) |
||||
{ |
||||
if (!EC_KEY_copy(pkey, b.pkey)) |
||||
throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed"); |
||||
return (*this); |
||||
} |
||||
|
||||
~CKey() |
||||
{ |
||||
EC_KEY_free(pkey); |
||||
} |
||||
|
||||
void MakeNewKey() |
||||
{ |
||||
if (!EC_KEY_generate_key(pkey)) |
||||
throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed"); |
||||
} |
||||
|
||||
bool SetPrivKey(const CPrivKey& vchPrivKey) |
||||
{ |
||||
const unsigned char* pbegin = &vchPrivKey[0]; |
||||
if (!d2i_ECPrivateKey(&pkey, &pbegin, vchPrivKey.size())) |
||||
return false; |
||||
return true; |
||||
} |
||||
|
||||
CPrivKey GetPrivKey() const |
||||
{ |
||||
unsigned int nSize = i2d_ECPrivateKey(pkey, NULL); |
||||
if (!nSize) |
||||
throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey failed"); |
||||
CPrivKey vchPrivKey(nSize, 0); |
||||
unsigned char* pbegin = &vchPrivKey[0]; |
||||
if (i2d_ECPrivateKey(pkey, &pbegin) != nSize) |
||||
throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey returned unexpected size"); |
||||
return vchPrivKey; |
||||
} |
||||
|
||||
bool SetPubKey(const vector<unsigned char>& vchPubKey) |
||||
{ |
||||
const unsigned char* pbegin = &vchPubKey[0]; |
||||
if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size())) |
||||
return false; |
||||
return true; |
||||
} |
||||
|
||||
vector<unsigned char> GetPubKey() const |
||||
{ |
||||
unsigned int nSize = i2o_ECPublicKey(pkey, NULL); |
||||
if (!nSize) |
||||
throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed"); |
||||
vector<unsigned char> vchPubKey(nSize, 0); |
||||
unsigned char* pbegin = &vchPubKey[0]; |
||||
if (i2o_ECPublicKey(pkey, &pbegin) != nSize) |
||||
throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size"); |
||||
return vchPubKey; |
||||
} |
||||
|
||||
bool Sign(uint256 hash, vector<unsigned char>& vchSig) |
||||
{ |
||||
vchSig.clear(); |
||||
unsigned char pchSig[10000]; |
||||
unsigned int nSize = 0; |
||||
if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), pchSig, &nSize, pkey)) |
||||
return false; |
||||
vchSig.resize(nSize); |
||||
memcpy(&vchSig[0], pchSig, nSize); |
||||
return true; |
||||
} |
||||
|
||||
bool Verify(uint256 hash, const vector<unsigned char>& vchSig) |
||||
{ |
||||
// -1 = error, 0 = bad sig, 1 = good
|
||||
if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1) |
||||
return false; |
||||
return true; |
||||
} |
||||
|
||||
static bool Sign(const CPrivKey& vchPrivKey, uint256 hash, vector<unsigned char>& vchSig) |
||||
{ |
||||
CKey key; |
||||
if (!key.SetPrivKey(vchPrivKey)) |
||||
return false; |
||||
return key.Sign(hash, vchSig); |
||||
} |
||||
|
||||
static bool Verify(const vector<unsigned char>& vchPubKey, uint256 hash, const vector<unsigned char>& vchSig) |
||||
{ |
||||
CKey key; |
||||
if (!key.SetPubKey(vchPubKey)) |
||||
return false; |
||||
return key.Verify(hash, vchSig); |
||||
} |
||||
}; |
@ -0,0 +1,19 @@
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2009 Satoshi Nakamoto |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
of this software and associated documentation files (the "Software"), to deal |
||||
in the Software without restriction, including without limitation the rights |
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
copies of the Software, and to permit persons to whom the Software is |
||||
furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included in |
||||
all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||
THE SOFTWARE. |
@ -0,0 +1,83 @@
@@ -0,0 +1,83 @@
|
||||
# Copyright (c) 2009 Satoshi Nakamoto
|
||||
# Distributed under the MIT/X11 software license, see the accompanying
|
||||
# file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
ifneq "$(BUILD)" "debug" |
||||
ifneq "$(BUILD)" "release" |
||||
BUILD=debug |
||||
endif |
||||
endif |
||||
ifeq "$(BUILD)" "debug" |
||||
D=d |
||||
# note: gcc 3.x profile doesn't work
|
||||
#DEBUGFLAGS=-O0 -g -pg -D__WXDEBUG__
|
||||
DEBUGFLAGS=-g -D__WXDEBUG__ |
||||
endif |
||||
|
||||
|
||||
|
||||
INCLUDEPATHS=-I"/boost" -I"/DB/build_unix" -I"/OpenSSL/include" -I"/wxWidgets/lib/vc_lib/mswd" -I"/wxWidgets/include" |
||||
LIBPATHS=-L"/DB/build_unix" -L"/OpenSSL/out" -L"/wxWidgets/lib/gcc_lib" |
||||
LIBS= \
|
||||
-l db_cxx \
|
||||
-l eay32 \
|
||||
-l wxmsw28$(D)_richtext -l wxmsw28$(D)_html -l wxmsw28$(D)_core -l wxbase28$(D) -l wxtiff$(D) -l wxjpeg$(D) -l wxpng$(D) -l wxzlib$(D) -l wxregex$(D) -l wxexpat$(D) \
|
||||
-l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32 |
||||
WXDEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH |
||||
CFLAGS=-mthreads -O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) |
||||
HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h |
||||
|
||||
|
||||
|
||||
all: bitcoin.exe |
||||
|
||||
|
||||
headers.h.gch: headers.h $(HEADERS) net.h irc.h market.h uibase.h ui.h |
||||
g++ -c $(CFLAGS) -o $@ $< |
||||
|
||||
obj/util.o: util.cpp $(HEADERS) |
||||
g++ -c $(CFLAGS) -o $@ $< |
||||
|
||||
obj/script.o: script.cpp $(HEADERS) |
||||
g++ -c $(CFLAGS) -o $@ $< |
||||
|
||||
obj/db.o: db.cpp $(HEADERS) market.h |
||||
g++ -c $(CFLAGS) -o $@ $< |
||||
|
||||
obj/net.o: net.cpp $(HEADERS) net.h |
||||
g++ -c $(CFLAGS) -o $@ $< |
||||
|
||||
obj/main.o: main.cpp $(HEADERS) net.h market.h sha.h |
||||
g++ -c $(CFLAGS) -o $@ $< |
||||
|
||||
obj/market.o: market.cpp $(HEADERS) market.h |
||||
g++ -c $(CFLAGS) -o $@ $< |
||||
|
||||
obj/ui.o: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h |
||||
g++ -c $(CFLAGS) -o $@ $< |
||||
|
||||
obj/uibase.o: uibase.cpp uibase.h |
||||
g++ -c $(CFLAGS) -o $@ $< |
||||
|
||||
obj/sha.o: sha.cpp sha.h |
||||
g++ -c $(CFLAGS) -O3 -o $@ $< |
||||
|
||||
obj/irc.o: irc.cpp $(HEADERS) |
||||
g++ -c $(CFLAGS) -o $@ $< |
||||
|
||||
obj/ui_res.o: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp |
||||
windres $(WXDEFS) $(INCLUDEPATHS) -o $@ -i $< |
||||
|
||||
|
||||
|
||||
OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \
|
||||
obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/ui_res.o |
||||
|
||||
bitcoin.exe: headers.h.gch $(OBJS) |
||||
-kill /f bitcoin.exe |
||||
g++ $(CFLAGS) -mwindows -Wl,--subsystem,windows -o $@ $(LIBPATHS) $(OBJS) $(LIBS) |
||||
|
||||
clean: |
||||
-del /Q obj\* |
||||
-del /Q headers.h.gch |
@ -0,0 +1,77 @@
@@ -0,0 +1,77 @@
|
||||
# Copyright (c) 2009 Satoshi Nakamoto |
||||
# Distributed under the MIT/X11 software license, see the accompanying |
||||
# file license.txt or http://www.opensource.org/licenses/mit-license.php. |
||||
|
||||
|
||||
!IF "$(BUILD)" != "debug" && "$(BUILD)" != "release" |
||||
BUILD=debug |
||||
!ENDIF |
||||
!IF "$(BUILD)" == "debug" |
||||
D=d |
||||
DEBUGFLAGS=/Zi /Od /D__WXDEBUG__ |
||||
!ENDIF |
||||
|
||||
|
||||
|
||||
INCLUDEPATHS=/I"/boost" /I"/DB/build_windows" /I"/OpenSSL/include" /I"/wxWidgets/lib/vc_lib/mswd" /I"/wxWidgets/include" |
||||
LIBPATHS=/LIBPATH:"/DB/build_windows/$(BUILD)" /LIBPATH:"/OpenSSL/out" /LIBPATH:"/wxWidgets/lib/vc_lib" |
||||
LIBS= \ |
||||
libdb47s$(D).lib \ |
||||
libeay32.lib \ |
||||
wxmsw28$(D)_richtext.lib wxmsw28$(D)_html.lib wxmsw28$(D)_core.lib wxbase28$(D).lib wxtiff$(D).lib wxjpeg$(D).lib wxpng$(D).lib wxzlib$(D).lib wxregex$(D).lib wxexpat$(D).lib \ |
||||
kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib ws2_32.lib |
||||
WXDEFS=/DWIN32 /D__WXMSW__ /D_WINDOWS /DNOPCH |
||||
CFLAGS=/c /nologo /Ob0 /MD$(D) /EHsc /GR /Zm300 /YX /Fpobj/headers.pch $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) |
||||
HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h |
||||
|
||||
|
||||
|
||||
all: bitcoin.exe |
||||
|
||||
|
||||
obj\util.obj: util.cpp $(HEADERS) |
||||
cl $(CFLAGS) /Fo$@ %s |
||||
|
||||
obj\script.obj: script.cpp $(HEADERS) |
||||
cl $(CFLAGS) /Fo$@ %s |
||||
|
||||
obj\db.obj: db.cpp $(HEADERS) market.h |
||||
cl $(CFLAGS) /Fo$@ %s |
||||
|
||||
obj\net.obj: net.cpp $(HEADERS) net.h |
||||
cl $(CFLAGS) /Fo$@ %s |
||||
|
||||
obj\main.obj: main.cpp $(HEADERS) net.h market.h |
||||
cl $(CFLAGS) /Fo$@ %s |
||||
|
||||
obj\market.obj: market.cpp $(HEADERS) market.h |
||||
cl $(CFLAGS) /Fo$@ %s |
||||
|
||||
obj\ui.obj: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h |
||||
cl $(CFLAGS) /Fo$@ %s |
||||
|
||||
obj\uibase.obj: uibase.cpp uibase.h |
||||
cl $(CFLAGS) /Fo$@ %s |
||||
|
||||
obj\sha.obj: sha.cpp sha.h |
||||
cl $(CFLAGS) /O2 /Fo$@ %s |
||||
|
||||
obj\irc.obj: irc.cpp $(HEADERS) |
||||
cl $(CFLAGS) /Fo$@ %s |
||||
|
||||
obj\ui.res: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp |
||||
rc $(INCLUDEPATHS) $(WXDEFS) /Fo$@ %s |
||||
|
||||
|
||||
|
||||
OBJS=obj\util.obj obj\script.obj obj\db.obj obj\net.obj obj\main.obj obj\market.obj \ |
||||
obj\ui.obj obj\uibase.obj obj\sha.obj obj\irc.obj obj\ui.res |
||||
|
||||
bitcoin.exe: $(OBJS) |
||||
-kill /f bitcoin.exe & sleep 1 |
||||
link /nologo /DEBUG /SUBSYSTEM:WINDOWS /OUT:$@ $(LIBPATHS) $** $(LIBS) |
||||
|
||||
clean: |
||||
-del /Q obj\* |
||||
-del *.ilk |
||||
-del *.pdb |
@ -0,0 +1,264 @@
@@ -0,0 +1,264 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "headers.h" |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Global state variables
|
||||
//
|
||||
|
||||
//// later figure out how these are persisted
|
||||
map<uint256, CProduct> mapMyProducts; |
||||
|
||||
|
||||
|
||||
|
||||
map<uint256, CProduct> mapProducts; |
||||
CCriticalSection cs_mapProducts; |
||||
|
||||
bool AdvertInsert(const CProduct& product) |
||||
{ |
||||
uint256 hash = product.GetHash(); |
||||
bool fNew = false; |
||||
bool fUpdated = false; |
||||
|
||||
CRITICAL_BLOCK(cs_mapProducts) |
||||
{ |
||||
// Insert or find existing product
|
||||
pair<map<uint256, CProduct>::iterator, bool> item = mapProducts.insert(make_pair(hash, product)); |
||||
CProduct* pproduct = &(*(item.first)).second; |
||||
fNew = item.second; |
||||
|
||||
// Update if newer
|
||||
if (product.nSequence > pproduct->nSequence) |
||||
{ |
||||
*pproduct = product; |
||||
fUpdated = true; |
||||
} |
||||
} |
||||
|
||||
//if (fNew)
|
||||
// NotifyProductAdded(hash);
|
||||
//else if (fUpdated)
|
||||
// NotifyProductUpdated(hash);
|
||||
|
||||
return (fNew || fUpdated); |
||||
} |
||||
|
||||
void AdvertErase(const CProduct& product) |
||||
{ |
||||
uint256 hash = product.GetHash(); |
||||
CRITICAL_BLOCK(cs_mapProducts) |
||||
mapProducts.erase(hash); |
||||
//NotifyProductDeleted(hash);
|
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template<typename T> |
||||
unsigned int Union(T& v1, T& v2) |
||||
{ |
||||
// v1 = v1 union v2
|
||||
// v1 and v2 must be sorted
|
||||
// returns the number of elements added to v1
|
||||
|
||||
///// need to check that this is equivalent, then delete this comment
|
||||
//vector<unsigned short> vUnion(v1.size() + v2.size());
|
||||
//vUnion.erase(set_union(v1.begin(), v1.end(),
|
||||
// v2.begin(), v2.end(),
|
||||
// vUnion.begin()),
|
||||
// vUnion.end());
|
||||
|
||||
T vUnion; |
||||
vUnion.reserve(v1.size() + v2.size()); |
||||
set_union(v1.begin(), v1.end(), |
||||
v2.begin(), v2.end(), |
||||
back_inserter(vUnion)); |
||||
unsigned int nAdded = vUnion.size() - v1.size(); |
||||
if (nAdded > 0) |
||||
v1 = vUnion; |
||||
return nAdded; |
||||
} |
||||
|
||||
void CUser::AddAtom(unsigned short nAtom, bool fOrigin) |
||||
{ |
||||
// Ignore duplicates
|
||||
if (binary_search(vAtomsIn.begin(), vAtomsIn.end(), nAtom) || |
||||
find(vAtomsNew.begin(), vAtomsNew.end(), nAtom) != vAtomsNew.end()) |
||||
return; |
||||
|
||||
//// instead of zero atom, should change to free atom that propagates,
|
||||
//// limited to lower than a certain value like 5 so conflicts quickly
|
||||
// The zero atom never propagates,
|
||||
// new atoms always propagate through the user that created them
|
||||
if (nAtom == 0 || fOrigin) |
||||
{ |
||||
vector<unsigned short> vTmp(1, nAtom); |
||||
Union(vAtomsIn, vTmp); |
||||
if (fOrigin) |
||||
vAtomsOut.push_back(nAtom); |
||||
return; |
||||
} |
||||
|
||||
vAtomsNew.push_back(nAtom); |
||||
|
||||
if (vAtomsNew.size() >= nFlowthroughRate || vAtomsOut.empty()) |
||||
{ |
||||
// Select atom to flow through to vAtomsOut
|
||||
vAtomsOut.push_back(vAtomsNew[GetRand(vAtomsNew.size())]); |
||||
|
||||
// Merge vAtomsNew into vAtomsIn
|
||||
sort(vAtomsNew.begin(), vAtomsNew.end()); |
||||
Union(vAtomsIn, vAtomsNew); |
||||
vAtomsNew.clear(); |
||||
} |
||||
} |
||||
|
||||
bool AddAtomsAndPropagate(uint256 hashUserStart, const vector<unsigned short>& vAtoms, bool fOrigin) |
||||
{ |
||||
CReviewDB reviewdb; |
||||
map<uint256, vector<unsigned short> > pmapPropagate[2]; |
||||
pmapPropagate[0][hashUserStart] = vAtoms; |
||||
|
||||
for (int side = 0; !pmapPropagate[side].empty(); side = 1 - side) |
||||
{ |
||||
map<uint256, vector<unsigned short> >& mapFrom = pmapPropagate[side]; |
||||
map<uint256, vector<unsigned short> >& mapTo = pmapPropagate[1 - side]; |
||||
|
||||
for (map<uint256, vector<unsigned short> >::iterator mi = mapFrom.begin(); mi != mapFrom.end(); ++mi) |
||||
{ |
||||
const uint256& hashUser = (*mi).first; |
||||
const vector<unsigned short>& vReceived = (*mi).second; |
||||
|
||||
///// this would be a lot easier on the database if it put the new atom at the beginning of the list,
|
||||
///// so the change would be right next to the vector size.
|
||||
|
||||
// Read user
|
||||
CUser user; |
||||
reviewdb.ReadUser(hashUser, user); |
||||
unsigned int nIn = user.vAtomsIn.size(); |
||||
unsigned int nNew = user.vAtomsNew.size(); |
||||
unsigned int nOut = user.vAtomsOut.size(); |
||||
|
||||
// Add atoms received
|
||||
foreach(unsigned short nAtom, vReceived) |
||||
user.AddAtom(nAtom, fOrigin); |
||||
fOrigin = false; |
||||
|
||||
// Don't bother writing to disk if no changes
|
||||
if (user.vAtomsIn.size() == nIn && user.vAtomsNew.size() == nNew) |
||||
continue; |
||||
|
||||
// Propagate
|
||||
if (user.vAtomsOut.size() > nOut) |
||||
foreach(const uint256& hash, user.vLinksOut) |
||||
mapTo[hash].insert(mapTo[hash].end(), user.vAtomsOut.begin() + nOut, user.vAtomsOut.end()); |
||||
|
||||
// Write back
|
||||
if (!reviewdb.WriteUser(hashUser, user)) |
||||
return false; |
||||
} |
||||
mapFrom.clear(); |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool CReview::AcceptReview() |
||||
{ |
||||
// Timestamp
|
||||
nTime = GetTime(); |
||||
|
||||
// Check signature
|
||||
if (!CKey::Verify(vchPubKeyFrom, GetSigHash(), vchSig)) |
||||
return false; |
||||
|
||||
CReviewDB reviewdb; |
||||
|
||||
// Add review text to recipient
|
||||
vector<CReview> vReviews; |
||||
reviewdb.ReadReviews(hashTo, vReviews); |
||||
vReviews.push_back(*this); |
||||
if (!reviewdb.WriteReviews(hashTo, vReviews)) |
||||
return false; |
||||
|
||||
// Add link from sender
|
||||
CUser user; |
||||
uint256 hashFrom = Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end()); |
||||
reviewdb.ReadUser(hashFrom, user); |
||||
user.vLinksOut.push_back(hashTo); |
||||
if (!reviewdb.WriteUser(hashFrom, user)) |
||||
return false; |
||||
|
||||
reviewdb.Close(); |
||||
|
||||
// Propagate atoms to recipient
|
||||
vector<unsigned short> vZeroAtom(1, 0); |
||||
if (!AddAtomsAndPropagate(hashTo, user.vAtomsOut.size() ? user.vAtomsOut : vZeroAtom, false)) |
||||
return false; |
||||
|
||||
return true; |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool CProduct::CheckSignature() |
||||
{ |
||||
return (CKey::Verify(vchPubKeyFrom, GetSigHash(), vchSig)); |
||||
} |
||||
|
||||
bool CProduct::CheckProduct() |
||||
{ |
||||
if (!CheckSignature()) |
||||
return false; |
||||
|
||||
// Make sure it's a summary product
|
||||
if (!mapDetails.empty() || !vOrderForm.empty()) |
||||
return false; |
||||
|
||||
// Look up seller's atom count
|
||||
CReviewDB reviewdb("r"); |
||||
CUser user; |
||||
reviewdb.ReadUser(GetUserHash(), user); |
||||
nAtoms = user.GetAtomCount(); |
||||
reviewdb.Close(); |
||||
|
||||
////// delme, this is now done by AdvertInsert
|
||||
//// Store to memory
|
||||
//CRITICAL_BLOCK(cs_mapProducts)
|
||||
// mapProducts[GetHash()] = *this;
|
||||
|
||||
return true; |
||||
} |
@ -0,0 +1,182 @@
@@ -0,0 +1,182 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
class CUser; |
||||
class CReview; |
||||
class CProduct; |
||||
|
||||
static const unsigned int nFlowthroughRate = 2; |
||||
|
||||
|
||||
|
||||
|
||||
bool AdvertInsert(const CProduct& product); |
||||
void AdvertErase(const CProduct& product); |
||||
bool AddAtomsAndPropagate(uint256 hashUserStart, const vector<unsigned short>& vAtoms, bool fOrigin); |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class CUser |
||||
{ |
||||
public: |
||||
vector<unsigned short> vAtomsIn; |
||||
vector<unsigned short> vAtomsNew; |
||||
vector<unsigned short> vAtomsOut; |
||||
vector<uint256> vLinksOut; |
||||
|
||||
CUser() |
||||
{ |
||||
} |
||||
|
||||
IMPLEMENT_SERIALIZE |
||||
( |
||||
if (!(nType & SER_GETHASH)) |
||||
READWRITE(nVersion); |
||||
READWRITE(vAtomsIn); |
||||
READWRITE(vAtomsNew); |
||||
READWRITE(vAtomsOut); |
||||
READWRITE(vLinksOut); |
||||
) |
||||
|
||||
void SetNull() |
||||
{ |
||||
vAtomsIn.clear(); |
||||
vAtomsNew.clear(); |
||||
vAtomsOut.clear(); |
||||
vLinksOut.clear(); |
||||
} |
||||
|
||||
uint256 GetHash() const { return SerializeHash(*this); } |
||||
|
||||
|
||||
int GetAtomCount() const |
||||
{ |
||||
return (vAtomsIn.size() + vAtomsNew.size()); |
||||
} |
||||
|
||||
void AddAtom(unsigned short nAtom, bool fOrigin); |
||||
}; |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class CReview |
||||
{ |
||||
public: |
||||
int nVersion; |
||||
uint256 hashTo; |
||||
map<string, string> mapValue; |
||||
vector<unsigned char> vchPubKeyFrom; |
||||
vector<unsigned char> vchSig; |
||||
|
||||
// memory only
|
||||
unsigned int nTime; |
||||
int nAtoms; |
||||
|
||||
|
||||
CReview() |
||||
{ |
||||
nVersion = 1; |
||||
hashTo = 0; |
||||
nTime = 0; |
||||
nAtoms = 0; |
||||
} |
||||
|
||||
IMPLEMENT_SERIALIZE |
||||
( |
||||
READWRITE(this->nVersion); |
||||
nVersion = this->nVersion; |
||||
if (!(nType & SER_DISK)) |
||||
READWRITE(hashTo); |
||||
READWRITE(mapValue); |
||||
READWRITE(vchPubKeyFrom); |
||||
if (!(nType & SER_GETHASH)) |
||||
READWRITE(vchSig); |
||||
) |
||||
|
||||
uint256 GetHash() const { return SerializeHash(*this); } |
||||
uint256 GetSigHash() const { return SerializeHash(*this, SER_GETHASH|SER_SKIPSIG); } |
||||
uint256 GetUserHash() const { return Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end()); } |
||||
|
||||
|
||||
bool AcceptReview(); |
||||
}; |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class CProduct |
||||
{ |
||||
public: |
||||
int nVersion; |
||||
CAddress addr; |
||||
map<string, string> mapValue; |
||||
map<string, string> mapDetails; |
||||
vector<pair<string, string> > vOrderForm; |
||||
unsigned int nSequence; |
||||
vector<unsigned char> vchPubKeyFrom; |
||||
vector<unsigned char> vchSig; |
||||
|
||||
// disk only
|
||||
int nAtoms; |
||||
|
||||
// memory only
|
||||
set<unsigned int> setSources; |
||||
|
||||
CProduct() |
||||
{ |
||||
nVersion = 1; |
||||
nAtoms = 0; |
||||
nSequence = 0; |
||||
} |
||||
|
||||
IMPLEMENT_SERIALIZE |
||||
( |
||||
READWRITE(this->nVersion); |
||||
nVersion = this->nVersion; |
||||
READWRITE(addr); |
||||
READWRITE(mapValue); |
||||
if (!(nType & SER_GETHASH)) |
||||
{ |
||||
READWRITE(mapDetails); |
||||
READWRITE(vOrderForm); |
||||
READWRITE(nSequence); |
||||
} |
||||
READWRITE(vchPubKeyFrom); |
||||
if (!(nType & SER_GETHASH)) |
||||
READWRITE(vchSig); |
||||
if (nType & SER_DISK) |
||||
READWRITE(nAtoms); |
||||
) |
||||
|
||||
uint256 GetHash() const { return SerializeHash(*this); } |
||||
uint256 GetSigHash() const { return SerializeHash(*this, SER_GETHASH|SER_SKIPSIG); } |
||||
uint256 GetUserHash() const { return Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end()); } |
||||
|
||||
|
||||
bool CheckSignature(); |
||||
bool CheckProduct(); |
||||
}; |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
extern map<uint256, CProduct> mapProducts; |
||||
extern CCriticalSection cs_mapProducts; |
||||
extern map<uint256, CProduct> mapMyProducts; |
@ -0,0 +1,856 @@
@@ -0,0 +1,856 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
class CMessageHeader; |
||||
class CAddress; |
||||
class CInv; |
||||
class CRequestTracker; |
||||
class CNode; |
||||
|
||||
|
||||
|
||||
static const unsigned short DEFAULT_PORT = htons(8333); |
||||
static const unsigned int PUBLISH_HOPS = 5; |
||||
enum |
||||
{ |
||||
NODE_NETWORK = (1 << 0), |
||||
}; |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet); |
||||
bool GetMyExternalIP(unsigned int& ipRet); |
||||
bool AddAddress(CAddrDB& addrdb, const CAddress& addr); |
||||
CNode* FindNode(unsigned int ip); |
||||
CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0); |
||||
void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1); |
||||
bool AnySubscribed(unsigned int nChannel); |
||||
void ThreadBitcoinMiner(void* parg); |
||||
bool StartNode(string& strError=REF(string())); |
||||
bool StopNode(); |
||||
void CheckForShutdown(int n); |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Message header
|
||||
// (4) message start
|
||||
// (12) command
|
||||
// (4) size
|
||||
|
||||
// The message start string is designed to be unlikely to occur in normal data.
|
||||
// The characters are rarely used upper ascii, not valid as UTF-8, and produce
|
||||
// a large 4-byte int at any alignment.
|
||||
static const char pchMessageStart[4] = { 0xf9, 0xbe, 0xb4, 0xd9 }; |
||||
|
||||
class CMessageHeader |
||||
{ |
||||
public: |
||||
enum { COMMAND_SIZE=12 }; |
||||
char pchMessageStart[sizeof(::pchMessageStart)]; |
||||
char pchCommand[COMMAND_SIZE]; |
||||
unsigned int nMessageSize; |
||||
|
||||
CMessageHeader() |
||||
{ |
||||
memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)); |
||||
memset(pchCommand, 0, sizeof(pchCommand)); |
||||
pchCommand[1] = 1; |
||||
nMessageSize = -1; |
||||
} |
||||
|
||||
CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn) |
||||
{ |
||||
memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)); |
||||
strncpy(pchCommand, pszCommand, COMMAND_SIZE); |
||||
nMessageSize = nMessageSizeIn; |
||||
} |
||||
|
||||
IMPLEMENT_SERIALIZE |
||||
( |
||||
READWRITE(FLATDATA(pchMessageStart)); |
||||
READWRITE(FLATDATA(pchCommand)); |
||||
READWRITE(nMessageSize); |
||||
) |
||||
|
||||
string GetCommand() |
||||
{ |
||||
if (pchCommand[COMMAND_SIZE-1] == 0) |
||||
return string(pchCommand, pchCommand + strlen(pchCommand)); |
||||
else |
||||
return string(pchCommand, pchCommand + COMMAND_SIZE); |
||||
} |
||||
|
||||
bool IsValid() |
||||
{ |
||||
// Check start string
|
||||
if (memcmp(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)) != 0) |
||||
return false; |
||||
|
||||
// Check the command string for errors
|
||||
for (char* p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; p1++) |
||||
{ |
||||
if (*p1 == 0) |
||||
{ |
||||
// Must be all zeros after the first zero
|
||||
for (; p1 < pchCommand + COMMAND_SIZE; p1++) |
||||
if (*p1 != 0) |
||||
return false; |
||||
} |
||||
else if (*p1 < ' ' || *p1 > 0x7E) |
||||
return false; |
||||
} |
||||
|
||||
// Message size
|
||||
if (nMessageSize > 0x10000000) |
||||
{ |
||||
printf("CMessageHeader::IsValid() : nMessageSize too large %u\n", nMessageSize); |
||||
return false; |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
}; |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }; |
||||
|
||||
class CAddress |
||||
{ |
||||
public: |
||||
uint64 nServices; |
||||
unsigned char pchReserved[12]; |
||||
unsigned int ip; |
||||
unsigned short port; |
||||
|
||||
// disk only
|
||||
unsigned int nTime; |
||||
|
||||
// memory only
|
||||
unsigned int nLastFailed; |
||||
|
||||
CAddress() |
||||
{ |
||||
nServices = 0; |
||||
memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); |
||||
ip = 0; |
||||
port = DEFAULT_PORT; |
||||
nTime = GetAdjustedTime(); |
||||
nLastFailed = 0; |
||||
} |
||||
|
||||
CAddress(unsigned int ipIn, unsigned short portIn=DEFAULT_PORT, uint64 nServicesIn=0) |
||||
{ |
||||
nServices = nServicesIn; |
||||
memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); |
||||
ip = ipIn; |
||||
port = portIn; |
||||
nTime = GetAdjustedTime(); |
||||
nLastFailed = 0; |
||||
} |
||||
|
||||
explicit CAddress(const struct sockaddr_in& sockaddr, uint64 nServicesIn=0) |
||||
{ |
||||
nServices = nServicesIn; |
||||
memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); |
||||
ip = sockaddr.sin_addr.s_addr; |
||||
port = sockaddr.sin_port; |
||||
nTime = GetAdjustedTime(); |
||||
nLastFailed = 0; |
||||
} |
||||
|
||||
explicit CAddress(const char* pszIn, uint64 nServicesIn=0) |
||||
{ |
||||
nServices = nServicesIn; |
||||
memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); |
||||
ip = 0; |
||||
port = DEFAULT_PORT; |
||||
nTime = GetAdjustedTime(); |
||||
nLastFailed = 0; |
||||
|
||||
char psz[100]; |
||||
if (strlen(pszIn) > ARRAYLEN(psz)-1) |
||||
return; |
||||
strcpy(psz, pszIn); |
||||
unsigned int a, b, c, d, e; |
||||
if (sscanf(psz, "%u.%u.%u.%u:%u", &a, &b, &c, &d, &e) < 4) |
||||
return; |
||||
char* pszPort = strchr(psz, ':'); |
||||
if (pszPort) |
||||
{ |
||||
*pszPort++ = '\0'; |
||||
port = htons(atoi(pszPort)); |
||||
} |
||||
ip = inet_addr(psz); |
||||
} |
||||
|
||||
IMPLEMENT_SERIALIZE |
||||
( |
||||
if (nType & SER_DISK) |
||||
{ |
||||
READWRITE(nVersion); |
||||
READWRITE(nTime); |
||||
} |
||||
READWRITE(nServices); |
||||
READWRITE(FLATDATA(pchReserved)); |
||||
READWRITE(ip); |
||||
READWRITE(port); |
||||
) |
||||
|
||||
friend inline bool operator==(const CAddress& a, const CAddress& b) |
||||
{ |
||||
return (memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved)) == 0 && |
||||
a.ip == b.ip && |
||||
a.port == b.port); |
||||
} |
||||
|
||||
friend inline bool operator<(const CAddress& a, const CAddress& b) |
||||
{ |
||||
int ret = memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved)); |
||||
if (ret < 0) |
||||
return true; |
||||
else if (ret == 0) |
||||
{ |
||||
if (ntohl(a.ip) < ntohl(b.ip)) |
||||
return true; |
||||
else if (a.ip == b.ip) |
||||
return ntohs(a.port) < ntohs(b.port); |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
vector<unsigned char> GetKey() const |
||||
{ |
||||
CDataStream ss; |
||||
ss.reserve(18); |
||||
ss << FLATDATA(pchReserved) << ip << port; |
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1300 |
||||
return vector<unsigned char>((unsigned char*)&ss.begin()[0], (unsigned char*)&ss.end()[0]); |
||||
#else |
||||
return vector<unsigned char>(ss.begin(), ss.end()); |
||||
#endif |
||||
} |
||||
|
||||
struct sockaddr_in GetSockAddr() const |
||||
{ |
||||
struct sockaddr_in sockaddr; |
||||
sockaddr.sin_family = AF_INET; |
||||
sockaddr.sin_addr.s_addr = ip; |
||||
sockaddr.sin_port = port; |
||||
return sockaddr; |
||||
} |
||||
|
||||
bool IsIPv4() const |
||||
{ |
||||
return (memcmp(pchReserved, pchIPv4, sizeof(pchIPv4)) == 0); |
||||
} |
||||
|
||||
bool IsRoutable() const |
||||
{ |
||||
return !(GetByte(3) == 10 || (GetByte(3) == 192 && GetByte(2) == 168) || GetByte(3) == 127 || GetByte(3) == 0); |
||||
} |
||||
|
||||
unsigned char GetByte(int n) const |
||||
{ |
||||
return ((unsigned char*)&ip)[3-n]; |
||||
} |
||||
|
||||
string ToStringIPPort() const |
||||
{ |
||||
return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port)); |
||||
} |
||||
|
||||
string ToStringIP() const |
||||
{ |
||||
return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0)); |
||||
} |
||||
|
||||
string ToString() const |
||||
{ |
||||
return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port)); |
||||
//return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0));
|
||||
} |
||||
|
||||
void print() const |
||||
{ |
||||
printf("CAddress(%s)\n", ToString().c_str()); |
||||
} |
||||
}; |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
enum |
||||
{ |
||||
MSG_TX = 1, |
||||
MSG_BLOCK, |
||||
MSG_REVIEW, |
||||
MSG_PRODUCT, |
||||
MSG_TABLE, |
||||
}; |
||||
|
||||
static const char* ppszTypeName[] = |
||||
{ |
||||
"ERROR", |
||||
"tx", |
||||
"block", |
||||
"review", |
||||
"product", |
||||
"table", |
||||
}; |
||||
|
||||
class CInv |
||||
{ |
||||
public: |
||||
int type; |
||||
uint256 hash; |
||||
|
||||
CInv() |
||||
{ |
||||
type = 0; |
||||
hash = 0; |
||||
} |
||||
|
||||
CInv(int typeIn, const uint256& hashIn) |
||||
{ |
||||
type = typeIn; |
||||
hash = hashIn; |
||||
} |
||||
|
||||
CInv(const string& strType, const uint256& hashIn) |
||||
{ |
||||
int i; |
||||
for (i = 1; i < ARRAYLEN(ppszTypeName); i++) |
||||
{ |
||||
if (strType == ppszTypeName[i]) |
||||
{ |
||||
type = i; |
||||
break; |
||||
} |
||||
} |
||||
if (i == ARRAYLEN(ppszTypeName)) |
||||
throw std::out_of_range(strprintf("CInv::CInv(string, uint256) : unknown type '%s'", strType.c_str())); |
||||
hash = hashIn; |
||||
} |
||||
|
||||
IMPLEMENT_SERIALIZE |
||||
( |
||||
READWRITE(type); |
||||
READWRITE(hash); |
||||
) |
||||
|
||||
friend inline bool operator<(const CInv& a, const CInv& b) |
||||
{ |
||||
return (a.type < b.type || (a.type == b.type && a.hash < b.hash)); |
||||
} |
||||
|
||||
bool IsKnownType() const |
||||
{ |
||||
return (type >= 1 && type < ARRAYLEN(ppszTypeName)); |
||||
} |
||||
|
||||
const char* GetCommand() const |
||||
{ |
||||
if (!IsKnownType()) |
||||
throw std::out_of_range(strprintf("CInv::GetCommand() : type=% unknown type", type)); |
||||
return ppszTypeName[type]; |
||||
} |
||||
|
||||
string ToString() const |
||||
{ |
||||
return strprintf("%s %s", GetCommand(), hash.ToString().substr(0,14).c_str()); |
||||
} |
||||
|
||||
void print() const |
||||
{ |
||||
printf("CInv(%s)\n", ToString().c_str()); |
||||
} |
||||
}; |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class CRequestTracker |
||||
{ |
||||
public: |
||||
void (*fn)(void*, CDataStream&); |
||||
void* param1; |
||||
|
||||
explicit CRequestTracker(void (*fnIn)(void*, CDataStream&)=NULL, void* param1In=NULL) |
||||
{ |
||||
fn = fnIn; |
||||
param1 = param1In; |
||||
} |
||||
|
||||
bool IsNull() |
||||
{ |
||||
return fn == NULL; |
||||
} |
||||
}; |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
extern bool fClient; |
||||
extern uint64 nLocalServices; |
||||
extern CAddress addrLocalHost; |
||||
extern CNode* pnodeLocalHost; |
||||
extern bool fShutdown; |
||||
extern array<bool, 10> vfThreadRunning; |
||||
extern vector<CNode*> vNodes; |
||||
extern CCriticalSection cs_vNodes; |
||||
extern map<vector<unsigned char>, CAddress> mapAddresses; |
||||
extern CCriticalSection cs_mapAddresses; |
||||
extern map<CInv, CDataStream> mapRelay; |
||||
extern deque<pair<int64, CInv> > vRelayExpiration; |
||||
extern CCriticalSection cs_mapRelay; |
||||
extern map<CInv, int64> mapAlreadyAskedFor; |
||||
extern CAddress addrProxy; |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class CNode |
||||
{ |
||||
public: |
||||
// socket
|
||||
uint64 nServices; |
||||
SOCKET hSocket; |
||||
CDataStream vSend; |
||||
CDataStream vRecv; |
||||
CCriticalSection cs_vSend; |
||||
CCriticalSection cs_vRecv; |
||||
unsigned int nPushPos; |
||||
CAddress addr; |
||||
int nVersion; |
||||
bool fClient; |
||||
bool fInbound; |
||||
bool fNetworkNode; |
||||
bool fDisconnect; |
||||
protected: |
||||
int nRefCount; |
||||
public: |
||||
int64 nReleaseTime; |
||||
map<uint256, CRequestTracker> mapRequests; |
||||
CCriticalSection cs_mapRequests; |
||||
|
||||
// flood
|
||||
vector<CAddress> vAddrToSend; |
||||
set<CAddress> setAddrKnown; |
||||
|
||||
// inventory based relay
|
||||
set<CInv> setInventoryKnown; |
||||
set<CInv> setInventoryKnown2; |
||||
vector<CInv> vInventoryToSend; |
||||
CCriticalSection cs_inventory; |
||||
multimap<int64, CInv> mapAskFor; |
||||
|
||||
// publish and subscription
|
||||
vector<char> vfSubscribe; |
||||
|
||||
|
||||
CNode(SOCKET hSocketIn, CAddress addrIn, bool fInboundIn=false) |
||||
{ |
||||
nServices = 0; |
||||
hSocket = hSocketIn; |
||||
vSend.SetType(SER_NETWORK); |
||||
vRecv.SetType(SER_NETWORK); |
||||
nPushPos = -1; |
||||
addr = addrIn; |
||||
nVersion = 0; |
||||
fClient = false; // set by version message
|
||||
fInbound = fInboundIn; |
||||
fNetworkNode = false; |
||||
fDisconnect = false; |
||||
nRefCount = 0; |
||||
nReleaseTime = 0; |
||||
vfSubscribe.assign(256, false); |
||||
|
||||
// Push a version message
|
||||
/// when NTP implemented, change to just nTime = GetAdjustedTime()
|
||||
int64 nTime = (fInbound ? GetAdjustedTime() : GetTime()); |
||||
PushMessage("version", VERSION, nLocalServices, nTime, addr); |
||||
} |
||||
|
||||
~CNode() |
||||
{ |
||||
if (hSocket != INVALID_SOCKET) |
||||
closesocket(hSocket); |
||||
} |
||||
|
||||
private: |
||||
CNode(const CNode&); |
||||
void operator=(const CNode&); |
||||
public: |
||||
|
||||
|
||||
bool ReadyToDisconnect() |
||||
{ |
||||
return fDisconnect || GetRefCount() <= 0; |
||||
} |
||||
|
||||
int GetRefCount() |
||||
{ |
||||
return max(nRefCount, 0) + (GetTime() < nReleaseTime ? 1 : 0); |
||||
} |
||||
|
||||
void AddRef(int64 nTimeout=0) |
||||
{ |
||||
if (nTimeout != 0) |
||||
nReleaseTime = max(nReleaseTime, GetTime() + nTimeout); |
||||
else |
||||
nRefCount++; |
||||
} |
||||
|
||||
void Release() |
||||
{ |
||||
nRefCount--; |
||||
} |
||||
|
||||
|
||||
|
||||
void AddInventoryKnown(const CInv& inv) |
||||
{ |
||||
CRITICAL_BLOCK(cs_inventory) |
||||
setInventoryKnown.insert(inv); |
||||
} |
||||
|
||||
void PushInventory(const CInv& inv) |
||||
{ |
||||
CRITICAL_BLOCK(cs_inventory) |
||||
if (!setInventoryKnown.count(inv)) |
||||
vInventoryToSend.push_back(inv); |
||||
} |
||||
|
||||
void AskFor(const CInv& inv) |
||||
{ |
||||
// We're using mapAskFor as a priority queue,
|
||||
// the key is the earliest time the request can be sent
|
||||
int64& nRequestTime = mapAlreadyAskedFor[inv]; |
||||
printf("askfor %s %I64d\n", inv.ToString().c_str(), nRequestTime); |
||||
|
||||
// Make sure not to reuse time indexes to keep things in the same order
|
||||
int64 nNow = (GetTime() - 1) * 1000000; |
||||
static int64 nLastTime; |
||||
nLastTime = nNow = max(nNow, ++nLastTime); |
||||
|
||||
// Each retry is 2 minutes after the last
|
||||
nRequestTime = max(nRequestTime + 2 * 60 * 1000000, nNow); |
||||
mapAskFor.insert(make_pair(nRequestTime, inv)); |
||||
} |
||||
|
||||
|
||||
|
||||
void BeginMessage(const char* pszCommand) |
||||
{ |
||||
EnterCriticalSection(&cs_vSend); |
||||
if (nPushPos != -1) |
||||
AbortMessage(); |
||||
nPushPos = vSend.size(); |
||||
vSend << CMessageHeader(pszCommand, 0); |
||||
printf("sending: %-12s ", pszCommand); |
||||
} |
||||
|
||||
void AbortMessage() |
||||
{ |
||||
if (nPushPos == -1) |
||||
return; |
||||
vSend.resize(nPushPos); |
||||
nPushPos = -1; |
||||
LeaveCriticalSection(&cs_vSend); |
||||
printf("(aborted)\n"); |
||||
} |
||||
|
||||
void EndMessage() |
||||
{ |
||||
extern int nDropMessagesTest; |
||||
if (nDropMessagesTest > 0 && GetRand(nDropMessagesTest) == 0) |
||||
{ |
||||
printf("dropmessages DROPPING SEND MESSAGE\n"); |
||||
AbortMessage(); |
||||
return; |
||||
} |
||||
|
||||
if (nPushPos == -1) |
||||
return; |
||||
|
||||
// Patch in the size
|
||||
unsigned int nSize = vSend.size() - nPushPos - sizeof(CMessageHeader); |
||||
memcpy((char*)&vSend[nPushPos] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize)); |
||||
|
||||
printf("(%d bytes) ", nSize); |
||||
//for (int i = nPushPos+sizeof(CMessageHeader); i < min(vSend.size(), nPushPos+sizeof(CMessageHeader)+20U); i++)
|
||||
// printf("%02x ", vSend[i] & 0xff);
|
||||
printf("\n"); |
||||
|
||||
nPushPos = -1; |
||||
LeaveCriticalSection(&cs_vSend); |
||||
} |
||||
|
||||
void EndMessageAbortIfEmpty() |
||||
{ |
||||
if (nPushPos == -1) |
||||
return; |
||||
int nSize = vSend.size() - nPushPos - sizeof(CMessageHeader); |
||||
if (nSize > 0) |
||||
EndMessage(); |
||||
else |
||||
AbortMessage(); |
||||
} |
||||
|
||||
const char* GetMessageCommand() const |
||||
{ |
||||
if (nPushPos == -1) |
||||
return ""; |
||||
return &vSend[nPushPos] + offsetof(CMessageHeader, pchCommand); |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
void PushMessage(const char* pszCommand) |
||||
{ |
||||
try |
||||
{ |
||||
BeginMessage(pszCommand); |
||||
EndMessage(); |
||||
} |
||||
catch (...) |
||||
{ |
||||
AbortMessage(); |
||||
throw; |
||||
} |
||||
} |
||||
|
||||
template<typename T1> |
||||
void PushMessage(const char* pszCommand, const T1& a1) |
||||
{ |
||||
try |
||||
{ |
||||
BeginMessage(pszCommand); |
||||
vSend << a1; |
||||
EndMessage(); |
||||
} |
||||
catch (...) |
||||
{ |
||||
AbortMessage(); |
||||
throw; |
||||
} |
||||
} |
||||
|
||||
template<typename T1, typename T2> |
||||
void PushMessage(const char* pszCommand, const T1& a1, const T2& a2) |
||||
{ |
||||
try |
||||
{ |
||||
BeginMessage(pszCommand); |
||||
vSend << a1 << a2; |
||||
EndMessage(); |
||||
} |
||||
catch (...) |
||||
{ |
||||
AbortMessage(); |
||||
throw; |
||||
} |
||||
} |
||||
|
||||
template<typename T1, typename T2, typename T3> |
||||
void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3) |
||||
{ |
||||
try |
||||
{ |
||||
BeginMessage(pszCommand); |
||||
vSend << a1 << a2 << a3; |
||||
EndMessage(); |
||||
} |
||||
catch (...) |
||||
{ |
||||
AbortMessage(); |
||||
throw; |
||||
} |
||||
} |
||||
|
||||
template<typename T1, typename T2, typename T3, typename T4> |
||||
void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4) |
||||
{ |
||||
try |
||||
{ |
||||
BeginMessage(pszCommand); |
||||
vSend << a1 << a2 << a3 << a4; |
||||
EndMessage(); |
||||
} |
||||
catch (...) |
||||
{ |
||||
AbortMessage(); |
||||
throw; |
||||
} |
||||
} |
||||
|
||||
|
||||
void PushRequest(const char* pszCommand, |
||||
void (*fn)(void*, CDataStream&), void* param1) |
||||
{ |
||||
uint256 hashReply; |
||||
RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply)); |
||||
|
||||
CRITICAL_BLOCK(cs_mapRequests) |
||||
mapRequests[hashReply] = CRequestTracker(fn, param1); |
||||
|
||||
PushMessage(pszCommand, hashReply); |
||||
} |
||||
|
||||
template<typename T1> |
||||
void PushRequest(const char* pszCommand, const T1& a1, |
||||
void (*fn)(void*, CDataStream&), void* param1) |
||||
{ |
||||
uint256 hashReply; |
||||
RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply)); |
||||
|
||||
CRITICAL_BLOCK(cs_mapRequests) |
||||
mapRequests[hashReply] = CRequestTracker(fn, param1); |
||||
|
||||
PushMessage(pszCommand, hashReply, a1); |
||||
} |
||||
|
||||
template<typename T1, typename T2> |
||||
void PushRequest(const char* pszCommand, const T1& a1, const T2& a2, |
||||
void (*fn)(void*, CDataStream&), void* param1) |
||||
{ |
||||
uint256 hashReply; |
||||
RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply)); |
||||
|
||||
CRITICAL_BLOCK(cs_mapRequests) |
||||
mapRequests[hashReply] = CRequestTracker(fn, param1); |
||||
|
||||
PushMessage(pszCommand, hashReply, a1, a2); |
||||
} |
||||
|
||||
|
||||
|
||||
bool IsSubscribed(unsigned int nChannel); |
||||
void Subscribe(unsigned int nChannel, unsigned int nHops=0); |
||||
void CancelSubscribe(unsigned int nChannel); |
||||
void Disconnect(); |
||||
}; |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
inline void RelayInventory(const CInv& inv) |
||||
{ |
||||
// Put on lists to offer to the other nodes
|
||||
CRITICAL_BLOCK(cs_vNodes) |
||||
foreach(CNode* pnode, vNodes) |
||||
pnode->PushInventory(inv); |
||||
} |
||||
|
||||
template<typename T> |
||||
void RelayMessage(const CInv& inv, const T& a) |
||||
{ |
||||
CDataStream ss(SER_NETWORK); |
||||
ss.reserve(10000); |
||||
ss << a; |
||||
RelayMessage(inv, ss); |
||||
} |
||||
|
||||
template<> |
||||
inline void RelayMessage<>(const CInv& inv, const CDataStream& ss) |
||||
{ |
||||
CRITICAL_BLOCK(cs_mapRelay) |
||||
{ |
||||
// Expire old relay messages
|
||||
while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime()) |
||||
{ |
||||
mapRelay.erase(vRelayExpiration.front().second); |
||||
vRelayExpiration.pop_front(); |
||||
} |
||||
|
||||
// Save original serialized message so newer versions are preserved
|
||||
mapRelay[inv] = ss; |
||||
vRelayExpiration.push_back(make_pair(GetTime() + 15 * 60, inv)); |
||||
} |
||||
|
||||
RelayInventory(inv); |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Templates for the publish and subscription system.
|
||||
// The object being published as T& obj needs to have:
|
||||
// a set<unsigned int> setSources member
|
||||
// specializations of AdvertInsert and AdvertErase
|
||||
// Currently implemented for CTable and CProduct.
|
||||
//
|
||||
|
||||
template<typename T> |
||||
void AdvertStartPublish(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj) |
||||
{ |
||||
// Add to sources
|
||||
obj.setSources.insert(pfrom->addr.ip); |
||||
|
||||
if (!AdvertInsert(obj)) |
||||
return; |
||||
|
||||
// Relay
|
||||
CRITICAL_BLOCK(cs_vNodes) |
||||
foreach(CNode* pnode, vNodes) |
||||
if (pnode != pfrom && (nHops < PUBLISH_HOPS || pnode->IsSubscribed(nChannel))) |
||||
pnode->PushMessage("publish", nChannel, nHops, obj); |
||||
} |
||||
|
||||
template<typename T> |
||||
void AdvertStopPublish(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj) |
||||
{ |
||||
uint256 hash = obj.GetHash(); |
||||
|
||||
CRITICAL_BLOCK(cs_vNodes) |
||||
foreach(CNode* pnode, vNodes) |
||||
if (pnode != pfrom && (nHops < PUBLISH_HOPS || pnode->IsSubscribed(nChannel))) |
||||
pnode->PushMessage("pub-cancel", nChannel, nHops, hash); |
||||
|
||||
AdvertErase(obj); |
||||
} |
||||
|
||||
template<typename T> |
||||
void AdvertRemoveSource(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj) |
||||
{ |
||||
// Remove a source
|
||||
obj.setSources.erase(pfrom->addr.ip); |
||||
|
||||
// If no longer supported by any sources, cancel it
|
||||
if (obj.setSources.empty()) |
||||
AdvertStopPublish(pfrom, nChannel, nHops, obj); |
||||
} |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 126 B |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 142 B |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 766 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 126 B |
After Width: | Height: | Size: 126 B |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 142 B |
@ -0,0 +1,76 @@
@@ -0,0 +1,76 @@
|
||||
BitCoin v0.1.5 ALPHA |
||||
|
||||
Copyright (c) 2009 Satoshi Nakamoto |
||||
Distributed under the MIT/X11 software license, see the accompanying |
||||
file license.txt or http://www.opensource.org/licenses/mit-license.php. |
||||
This product includes software developed by the OpenSSL Project for use in |
||||
the OpenSSL Toolkit (http://www.openssl.org/). This product includes |
||||
cryptographic software written by Eric Young (eay@cryptsoft.com). |
||||
|
||||
|
||||
Compilers Supported |
||||
------------------- |
||||
MinGW GCC (v3.4.5) |
||||
Microsoft Visual C++ 6.0 SP6 |
||||
|
||||
|
||||
Dependencies |
||||
------------ |
||||
Libraries you need to obtain separately to build: |
||||
|
||||
default path download |
||||
wxWidgets \wxWidgets http://www.wxwidgets.org/downloads/ |
||||
OpenSSL \OpenSSL http://www.openssl.org/source/ |
||||
Berkeley DB \DB http://www.oracle.com/technology/software/products/berkeley-db/index.html |
||||
Boost \Boost http://www.boost.org/users/download/ |
||||
|
||||
Their licenses: |
||||
wxWidgets LGPL 2.1 with very liberal exceptions |
||||
OpenSSL Old BSD license with the problematic advertising requirement |
||||
Berkeley DB New BSD license with additional requirement that linked software must be free open source |
||||
Boost MIT-like license |
||||
|
||||
|
||||
OpenSSL |
||||
------- |
||||
Bitcoin does not use any encryption. If you want to do a no-everything |
||||
build of OpenSSL to exclude encryption routines, a few patches are required. |
||||
(OpenSSL v0.9.8h) |
||||
|
||||
Edit engines\e_gmp.c and put this #ifndef around #include <openssl/rsa.h> |
||||
#ifndef OPENSSL_NO_RSA |
||||
#include <openssl/rsa.h> |
||||
#endif |
||||
|
||||
Add this to crypto\err\err_all.c before the ERR_load_crypto_strings line: |
||||
void ERR_load_RSA_strings(void) { } |
||||
|
||||
Edit ms\mingw32.bat and replace the Configure line's parameters with this |
||||
no-everything list. You have to put this in the batch file because batch |
||||
files can't handle more than 9 parameters. |
||||
perl Configure mingw threads no-rc2 no-rc4 no-rc5 no-idea no-des no-bf no-cast no-aes no-camellia no-seed no-rsa no-dh |
||||
|
||||
Also REM out the following line in ms\mingw32.bat. The build fails after it's |
||||
already finished building libeay32, which is all we care about, but the |
||||
failure aborts the script before it runs dllwrap to generate libeay32.dll. |
||||
REM if errorlevel 1 goto end |
||||
|
||||
Build |
||||
ms\mingw32.bat |
||||
|
||||
If you want to use it with MSVC, generate the .lib file |
||||
lib /machine:i386 /def:ms\libeay32.def /out:out\libeay32.lib |
||||
|
||||
|
||||
Berkeley DB |
||||
----------- |
||||
MinGW with MSYS: |
||||
cd \DB\build_unix |
||||
sh ../dist/configure --enable-mingw --enable-cxx |
||||
make |
||||
|
||||
|
||||
Boost |
||||
----- |
||||
You may need Boost version 1.35 to build with MSVC 6.0. I couldn't get |
||||
version 1.37 to compile with MSVC 6.0. |
@ -0,0 +1,597 @@
@@ -0,0 +1,597 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
class CTransaction; |
||||
|
||||
enum |
||||
{ |
||||
SIGHASH_ALL = 1, |
||||
SIGHASH_NONE = 2, |
||||
SIGHASH_SINGLE = 3, |
||||
SIGHASH_ANYONECANPAY = 0x80, |
||||
}; |
||||
|
||||
|
||||
|
||||
enum opcodetype |
||||
{ |
||||
// push value
|
||||
OP_0=0, |
||||
OP_FALSE=OP_0, |
||||
OP_PUSHDATA1=76, |
||||
OP_PUSHDATA2, |
||||
OP_PUSHDATA4, |
||||
OP_1NEGATE, |
||||
OP_RESERVED, |
||||
OP_1, |
||||
OP_TRUE=OP_1, |
||||
OP_2, |
||||
OP_3, |
||||
OP_4, |
||||
OP_5, |
||||
OP_6, |
||||
OP_7, |
||||
OP_8, |
||||
OP_9, |
||||
OP_10, |
||||
OP_11, |
||||
OP_12, |
||||
OP_13, |
||||
OP_14, |
||||
OP_15, |
||||
OP_16, |
||||
|
||||
// control
|
||||
OP_NOP, |
||||
OP_VER, |
||||
OP_IF, |
||||
OP_NOTIF, |
||||
OP_VERIF, |
||||
OP_VERNOTIF, |
||||
OP_ELSE, |
||||
OP_ENDIF, |
||||
OP_VERIFY, |
||||
OP_RETURN, |
||||
|
||||
// stack ops
|
||||
OP_TOALTSTACK, |
||||
OP_FROMALTSTACK, |
||||
OP_2DROP, |
||||
OP_2DUP, |
||||
OP_3DUP, |
||||
OP_2OVER, |
||||
OP_2ROT, |
||||
OP_2SWAP, |
||||
OP_IFDUP, |
||||
OP_DEPTH, |
||||
OP_DROP, |
||||
OP_DUP, |
||||
OP_NIP, |
||||
OP_OVER, |
||||
OP_PICK, |
||||
OP_ROLL, |
||||
OP_ROT, |
||||
OP_SWAP, |
||||
OP_TUCK, |
||||
|
||||
// splice ops
|
||||
OP_CAT, |
||||
OP_SUBSTR, |
||||
OP_LEFT, |
||||
OP_RIGHT, |
||||
OP_SIZE, |
||||
|
||||
// bit logic
|
||||
OP_INVERT, |
||||
OP_AND, |
||||
OP_OR, |
||||
OP_XOR, |
||||
OP_EQUAL, |
||||
OP_EQUALVERIFY, |
||||
OP_RESERVED1, |
||||
OP_RESERVED2, |
||||
|
||||
// numeric
|
||||
OP_1ADD, |
||||
OP_1SUB, |
||||
OP_2MUL, |
||||
OP_2DIV, |
||||
OP_NEGATE, |
||||
OP_ABS, |
||||
OP_NOT, |
||||
OP_0NOTEQUAL, |
||||
|
||||
OP_ADD, |
||||
OP_SUB, |
||||
OP_MUL, |
||||
OP_DIV, |
||||
OP_MOD, |
||||
OP_LSHIFT, |
||||
OP_RSHIFT, |
||||
|
||||
OP_BOOLAND, |
||||
OP_BOOLOR, |
||||
OP_NUMEQUAL, |
||||
OP_NUMEQUALVERIFY, |
||||
OP_NUMNOTEQUAL, |
||||
OP_LESSTHAN, |
||||
OP_GREATERTHAN, |
||||
OP_LESSTHANOREQUAL, |
||||
OP_GREATERTHANOREQUAL, |
||||
OP_MIN, |
||||
OP_MAX, |
||||
|
||||
OP_WITHIN, |
||||
|
||||
// crypto
|
||||
OP_RIPEMD160, |
||||
OP_SHA1, |
||||
OP_SHA256, |
||||
OP_HASH160, |
||||
OP_HASH256, |
||||
OP_CODESEPARATOR, |
||||
OP_CHECKSIG, |
||||
OP_CHECKSIGVERIFY, |
||||
OP_CHECKMULTISIG, |
||||
OP_CHECKMULTISIGVERIFY, |
||||
|
||||
|
||||
// multi-byte opcodes
|
||||
OP_SINGLEBYTE_END = 0xF0, |
||||
OP_DOUBLEBYTE_BEGIN = 0xF000, |
||||
|
||||
// template matching params
|
||||
OP_PUBKEY, |
||||
OP_PUBKEYHASH, |
||||
|
||||
|
||||
|
||||
OP_INVALIDOPCODE = 0xFFFF, |
||||
}; |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
inline const char* GetOpName(opcodetype opcode) |
||||
{ |
||||
switch (opcode) |
||||
{ |
||||
// push value
|
||||
case OP_0 : return "0"; |
||||
case OP_PUSHDATA1 : return "OP_PUSHDATA1"; |
||||
case OP_PUSHDATA2 : return "OP_PUSHDATA2"; |
||||
case OP_PUSHDATA4 : return "OP_PUSHDATA4"; |
||||
case OP_1NEGATE : return "-1"; |
||||
case OP_RESERVED : return "OP_RESERVED"; |
||||
case OP_1 : return "1"; |
||||
case OP_2 : return "2"; |
||||
case OP_3 : return "3"; |
||||
case OP_4 : return "4"; |
||||
case OP_5 : return "5"; |
||||
case OP_6 : return "6"; |
||||
case OP_7 : return "7"; |
||||
case OP_8 : return "8"; |
||||
case OP_9 : return "9"; |
||||
case OP_10 : return "10"; |
||||
case OP_11 : return "11"; |
||||
case OP_12 : return "12"; |
||||
case OP_13 : return "13"; |
||||
case OP_14 : return "14"; |
||||
case OP_15 : return "15"; |
||||
case OP_16 : return "16"; |
||||
|
||||
// control
|
||||
case OP_NOP : return "OP_NOP"; |
||||
case OP_VER : return "OP_VER"; |
||||
case OP_IF : return "OP_IF"; |
||||
case OP_NOTIF : return "OP_NOTIF"; |
||||
case OP_VERIF : return "OP_VERIF"; |
||||
case OP_VERNOTIF : return "OP_VERNOTIF"; |
||||
case OP_ELSE : return "OP_ELSE"; |
||||
case OP_ENDIF : return "OP_ENDIF"; |
||||
case OP_VERIFY : return "OP_VERIFY"; |
||||
case OP_RETURN : return "OP_RETURN"; |
||||
|
||||
// stack ops
|
||||
case OP_TOALTSTACK : return "OP_TOALTSTACK"; |
||||
case OP_FROMALTSTACK : return "OP_FROMALTSTACK"; |
||||
case OP_2DROP : return "OP_2DROP"; |
||||
case OP_2DUP : return "OP_2DUP"; |
||||
case OP_3DUP : return "OP_3DUP"; |
||||
case OP_2OVER : return "OP_2OVER"; |
||||
case OP_2ROT : return "OP_2ROT"; |
||||
case OP_2SWAP : return "OP_2SWAP"; |
||||
case OP_IFDUP : return "OP_IFDUP"; |
||||
case OP_DEPTH : return "OP_DEPTH"; |
||||
case OP_DROP : return "OP_DROP"; |
||||
case OP_DUP : return "OP_DUP"; |
||||
case OP_NIP : return "OP_NIP"; |
||||
case OP_OVER : return "OP_OVER"; |
||||
case OP_PICK : return "OP_PICK"; |
||||
case OP_ROLL : return "OP_ROLL"; |
||||
case OP_ROT : return "OP_ROT"; |
||||
case OP_SWAP : return "OP_SWAP"; |
||||
case OP_TUCK : return "OP_TUCK"; |
||||
|
||||
// splice ops
|
||||
case OP_CAT : return "OP_CAT"; |
||||
case OP_SUBSTR : return "OP_SUBSTR"; |
||||
case OP_LEFT : return "OP_LEFT"; |
||||
case OP_RIGHT : return "OP_RIGHT"; |
||||
case OP_SIZE : return "OP_SIZE"; |
||||
|
||||
// bit logic
|
||||
case OP_INVERT : return "OP_INVERT"; |
||||
case OP_AND : return "OP_AND"; |
||||
case OP_OR : return "OP_OR"; |
||||
case OP_XOR : return "OP_XOR"; |
||||
case OP_EQUAL : return "OP_EQUAL"; |
||||
case OP_EQUALVERIFY : return "OP_EQUALVERIFY"; |
||||
case OP_RESERVED1 : return "OP_RESERVED1"; |
||||
case OP_RESERVED2 : return "OP_RESERVED2"; |
||||
|
||||
// numeric
|
||||
case OP_1ADD : return "OP_1ADD"; |
||||
case OP_1SUB : return "OP_1SUB"; |
||||
case OP_2MUL : return "OP_2MUL"; |
||||
case OP_2DIV : return "OP_2DIV"; |
||||
case OP_NEGATE : return "OP_NEGATE"; |
||||
case OP_ABS : return "OP_ABS"; |
||||
case OP_NOT : return "OP_NOT"; |
||||
case OP_0NOTEQUAL : return "OP_0NOTEQUAL"; |
||||
case OP_ADD : return "OP_ADD"; |
||||
case OP_SUB : return "OP_SUB"; |
||||
case OP_MUL : return "OP_MUL"; |
||||
case OP_DIV : return "OP_DIV"; |
||||
case OP_MOD : return "OP_MOD"; |
||||
case OP_LSHIFT : return "OP_LSHIFT"; |
||||
case OP_RSHIFT : return "OP_RSHIFT"; |
||||
case OP_BOOLAND : return "OP_BOOLAND"; |
||||
case OP_BOOLOR : return "OP_BOOLOR"; |
||||
case OP_NUMEQUAL : return "OP_NUMEQUAL"; |
||||
case OP_NUMEQUALVERIFY : return "OP_NUMEQUALVERIFY"; |
||||
case OP_NUMNOTEQUAL : return "OP_NUMNOTEQUAL"; |
||||
case OP_LESSTHAN : return "OP_LESSTHAN"; |
||||
case OP_GREATERTHAN : return "OP_GREATERTHAN"; |
||||
case OP_LESSTHANOREQUAL : return "OP_LESSTHANOREQUAL"; |
||||
case OP_GREATERTHANOREQUAL : return "OP_GREATERTHANOREQUAL"; |
||||
case OP_MIN : return "OP_MIN"; |
||||
case OP_MAX : return "OP_MAX"; |
||||
case OP_WITHIN : return "OP_WITHIN"; |
||||
|
||||
// crypto
|
||||
case OP_RIPEMD160 : return "OP_RIPEMD160"; |
||||
case OP_SHA1 : return "OP_SHA1"; |
||||
case OP_SHA256 : return "OP_SHA256"; |
||||
case OP_HASH160 : return "OP_HASH160"; |
||||
case OP_HASH256 : return "OP_HASH256"; |
||||
case OP_CODESEPARATOR : return "OP_CODESEPARATOR"; |
||||
case OP_CHECKSIG : return "OP_CHECKSIG"; |
||||
case OP_CHECKSIGVERIFY : return "OP_CHECKSIGVERIFY"; |
||||
case OP_CHECKMULTISIG : return "OP_CHECKMULTISIG"; |
||||
case OP_CHECKMULTISIGVERIFY : return "OP_CHECKMULTISIGVERIFY"; |
||||
|
||||
|
||||
|
||||
// multi-byte opcodes
|
||||
case OP_SINGLEBYTE_END : return "OP_SINGLEBYTE_END"; |
||||
case OP_DOUBLEBYTE_BEGIN : return "OP_DOUBLEBYTE_BEGIN"; |
||||
case OP_PUBKEY : return "OP_PUBKEY"; |
||||
case OP_PUBKEYHASH : return "OP_PUBKEYHASH"; |
||||
|
||||
|
||||
|
||||
case OP_INVALIDOPCODE : return "OP_INVALIDOPCODE"; |
||||
default: |
||||
return "UNKNOWN_OPCODE"; |
||||
} |
||||
}; |
||||
|
||||
|
||||
|
||||
|
||||
inline string ValueString(const vector<unsigned char>& vch) |
||||
{ |
||||
if (vch.size() <= 4) |
||||
return strprintf("%d", CBigNum(vch).getint()); |
||||
else |
||||
return HexNumStr(vch.begin(), vch.end()); |
||||
//return string("(") + HexStr(vch.begin(), vch.end()) + string(")");
|
||||
} |
||||
|
||||
inline string StackString(const vector<vector<unsigned char> >& vStack) |
||||
{ |
||||
string str; |
||||
foreach(const vector<unsigned char>& vch, vStack) |
||||
{ |
||||
if (!str.empty()) |
||||
str += " "; |
||||
str += ValueString(vch); |
||||
} |
||||
return str; |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class CScript : public vector<unsigned char> |
||||
{ |
||||
protected: |
||||
CScript& push_int64(int64 n) |
||||
{ |
||||
if (n == -1 || (n >= 1 && n <= 16)) |
||||
{ |
||||
push_back(n + (OP_1 - 1)); |
||||
} |
||||
else |
||||
{ |
||||
CBigNum bn(n); |
||||
*this << bn.getvch(); |
||||
} |
||||
return (*this); |
||||
} |
||||
|
||||
CScript& push_uint64(uint64 n) |
||||
{ |
||||
if (n == -1 || (n >= 1 && n <= 16)) |
||||
{ |
||||
push_back(n + (OP_1 - 1)); |
||||
} |
||||
else |
||||
{ |
||||
CBigNum bn(n); |
||||
*this << bn.getvch(); |
||||
} |
||||
return (*this); |
||||
} |
||||
|
||||
public: |
||||
CScript() { } |
||||
CScript(const CScript& b) : vector<unsigned char>(b.begin(), b.end()) { } |
||||
CScript(const_iterator pbegin, const_iterator pend) : vector<unsigned char>(pbegin, pend) { } |
||||
#ifndef _MSC_VER |
||||
CScript(const unsigned char* pbegin, const unsigned char* pend) : vector<unsigned char>(pbegin, pend) { } |
||||
#endif |
||||
|
||||
CScript& operator+=(const CScript& b) |
||||
{ |
||||
insert(end(), b.begin(), b.end()); |
||||
return *this; |
||||
} |
||||
|
||||
friend CScript operator+(const CScript& a, const CScript& b) |
||||
{ |
||||
CScript ret = a; |
||||
ret += b; |
||||
return (ret); |
||||
} |
||||
|
||||
|
||||
explicit CScript(char b) { operator<<(b); } |
||||
explicit CScript(short b) { operator<<(b); } |
||||
explicit CScript(int b) { operator<<(b); } |
||||
explicit CScript(long b) { operator<<(b); } |
||||
explicit CScript(int64 b) { operator<<(b); } |
||||
explicit CScript(unsigned char b) { operator<<(b); } |
||||
explicit CScript(unsigned int b) { operator<<(b); } |
||||
explicit CScript(unsigned short b) { operator<<(b); } |
||||
explicit CScript(unsigned long b) { operator<<(b); } |
||||
explicit CScript(uint64 b) { operator<<(b); } |
||||
|
||||
explicit CScript(opcodetype b) { operator<<(b); } |
||||
explicit CScript(const uint256& b) { operator<<(b); } |
||||
explicit CScript(const CBigNum& b) { operator<<(b); } |
||||
explicit CScript(const vector<unsigned char>& b) { operator<<(b); } |
||||
|
||||
|
||||
CScript& operator<<(char b) { return (push_int64(b)); } |
||||
CScript& operator<<(short b) { return (push_int64(b)); } |
||||
CScript& operator<<(int b) { return (push_int64(b)); } |
||||
CScript& operator<<(long b) { return (push_int64(b)); } |
||||
CScript& operator<<(int64 b) { return (push_int64(b)); } |
||||
CScript& operator<<(unsigned char b) { return (push_uint64(b)); } |
||||
CScript& operator<<(unsigned int b) { return (push_uint64(b)); } |
||||
CScript& operator<<(unsigned short b) { return (push_uint64(b)); } |
||||
CScript& operator<<(unsigned long b) { return (push_uint64(b)); } |
||||
CScript& operator<<(uint64 b) { return (push_uint64(b)); } |
||||
|
||||
CScript& operator<<(opcodetype opcode) |
||||
{ |
||||
if (opcode <= OP_SINGLEBYTE_END) |
||||
{ |
||||
insert(end(), (unsigned char)opcode); |
||||
} |
||||
else |
||||
{ |
||||
assert(opcode >= OP_DOUBLEBYTE_BEGIN); |
||||
insert(end(), (unsigned char)(opcode >> 8)); |
||||
insert(end(), (unsigned char)(opcode & 0xFF)); |
||||
} |
||||
return (*this); |
||||
} |
||||
|
||||
CScript& operator<<(const uint160& b) |
||||
{ |
||||
insert(end(), sizeof(b)); |
||||
insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b)); |
||||
return (*this); |
||||
} |
||||
|
||||
CScript& operator<<(const uint256& b) |
||||
{ |
||||
insert(end(), sizeof(b)); |
||||
insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b)); |
||||
return (*this); |
||||
} |
||||
|
||||
CScript& operator<<(const CBigNum& b) |
||||
{ |
||||
*this << b.getvch(); |
||||
return (*this); |
||||
} |
||||
|
||||
CScript& operator<<(const vector<unsigned char>& b) |
||||
{ |
||||
if (b.size() < OP_PUSHDATA1) |
||||
{ |
||||
insert(end(), (unsigned char)b.size()); |
||||
} |
||||
else if (b.size() <= 0xff) |
||||
{ |
||||
insert(end(), OP_PUSHDATA1); |
||||
insert(end(), (unsigned char)b.size()); |
||||
} |
||||
else |
||||
{ |
||||
insert(end(), OP_PUSHDATA2); |
||||
unsigned short nSize = b.size(); |
||||
insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize)); |
||||
} |
||||
insert(end(), b.begin(), b.end()); |
||||
return (*this); |
||||
} |
||||
|
||||
CScript& operator<<(const CScript& b) |
||||
{ |
||||
// I'm not sure if this should push the script or concatenate scripts.
|
||||
// If there's ever a use for pushing a script onto a script, delete this member fn
|
||||
assert(("warning: pushing a CScript onto a CScript with << is probably not intended, use + to concatenate", false)); |
||||
return (*this); |
||||
} |
||||
|
||||
|
||||
bool GetOp(iterator& pc, opcodetype& opcodeRet, vector<unsigned char>& vchRet) |
||||
{ |
||||
// This is why people hate C++
|
||||
const_iterator pc2 = pc; |
||||
bool fRet = GetOp(pc2, opcodeRet, vchRet); |
||||
pc = begin() + (pc2 - begin()); |
||||
return fRet; |
||||
} |
||||
|
||||
bool GetOp(const_iterator& pc, opcodetype& opcodeRet, vector<unsigned char>& vchRet) const |
||||
{ |
||||
opcodeRet = OP_INVALIDOPCODE; |
||||
vchRet.clear(); |
||||
if (pc >= end()) |
||||
return false; |
||||
|
||||
// Read instruction
|
||||
unsigned int opcode = *pc++; |
||||
if (opcode >= OP_SINGLEBYTE_END) |
||||
{ |
||||
if (pc + 1 > end()) |
||||
return false; |
||||
opcode <<= 8; |
||||
opcode |= *pc++; |
||||
} |
||||
|
||||
// Immediate operand
|
||||
if (opcode <= OP_PUSHDATA4) |
||||
{ |
||||
unsigned int nSize = opcode; |
||||
if (opcode == OP_PUSHDATA1) |
||||
{ |
||||
if (pc + 1 > end()) |
||||
return false; |
||||
nSize = *pc++; |
||||
} |
||||
else if (opcode == OP_PUSHDATA2) |
||||
{ |
||||
if (pc + 2 > end()) |
||||
return false; |
||||
nSize = 0; |
||||
memcpy(&nSize, &pc[0], 2); |
||||
pc += 2; |
||||
} |
||||
else if (opcode == OP_PUSHDATA4) |
||||
{ |
||||
if (pc + 4 > end()) |
||||
return false; |
||||
memcpy(&nSize, &pc[0], 4); |
||||
pc += 4; |
||||
} |
||||
if (pc + nSize > end()) |
||||
return false; |
||||
vchRet.assign(pc, pc + nSize); |
||||
pc += nSize; |
||||
} |
||||
|
||||
opcodeRet = (opcodetype)opcode; |
||||
return true; |
||||
} |
||||
|
||||
|
||||
void FindAndDelete(const CScript& b) |
||||
{ |
||||
iterator pc = begin(); |
||||
opcodetype opcode; |
||||
vector<unsigned char> vchPushValue; |
||||
int count = 0; |
||||
do |
||||
{ |
||||
while (end() - pc >= b.size() && memcmp(&pc[0], &b[0], b.size()) == 0) |
||||
{ |
||||
erase(pc, pc + b.size()); |
||||
count++; |
||||
} |
||||
} |
||||
while (GetOp(pc, opcode, vchPushValue)); |
||||
//printf("FindAndDeleted deleted %d items\n", count); /// debug
|
||||
} |
||||
|
||||
|
||||
void PrintHex() const |
||||
{ |
||||
printf("CScript(%s)\n", HexStr(begin(), end()).c_str()); |
||||
} |
||||
|
||||
string ToString() const |
||||
{ |
||||
string str; |
||||
opcodetype opcode; |
||||
vector<unsigned char> vch; |
||||
const_iterator it = begin(); |
||||
while (GetOp(it, opcode, vch)) |
||||
{ |
||||
if (!str.empty()) |
||||
str += " "; |
||||
if (opcode <= OP_PUSHDATA4) |
||||
str += ValueString(vch); |
||||
else |
||||
str += GetOpName(opcode); |
||||
} |
||||
return str; |
||||
} |
||||
|
||||
void print() const |
||||
{ |
||||
printf("%s\n", ToString().c_str()); |
||||
} |
||||
}; |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType=0, |
||||
vector<vector<unsigned char> >* pvStackRet=NULL); |
||||
uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); |
||||
bool IsMine(const CScript& scriptPubKey); |
||||
bool ExtractPubKey(const CScript& scriptPubKey, bool fMineOnly, vector<unsigned char>& vchPubKeyRet); |
||||
bool ExtractHash160(const CScript& scriptPubKey, uint160& hash160Ret); |
||||
bool SignSignature(const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL, CScript scriptPrereq=CScript()); |
||||
bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, int nHashType=0); |
@ -0,0 +1,554 @@
@@ -0,0 +1,554 @@
|
||||
// This file is public domain
|
||||
// SHA routines extracted as a standalone file from:
|
||||
// Crypto++: a C++ Class Library of Cryptographic Schemes
|
||||
// Version 5.5.2 (9/24/2007)
|
||||
// http://www.cryptopp.com
|
||||
|
||||
// sha.cpp - modified by Wei Dai from Steve Reid's public domain sha1.c
|
||||
|
||||
// Steve Reid implemented SHA-1. Wei Dai implemented SHA-2.
|
||||
// Both are in the public domain.
|
||||
|
||||
#include <assert.h> |
||||
#include <memory.h> |
||||
#include "sha.h" |
||||
|
||||
namespace CryptoPP |
||||
{ |
||||
|
||||
// start of Steve Reid's code
|
||||
|
||||
#define blk0(i) (W[i] = data[i]) |
||||
#define blk1(i) (W[i&15] = rotlFixed(W[(i+13)&15]^W[(i+8)&15]^W[(i+2)&15]^W[i&15],1)) |
||||
|
||||
void SHA1::InitState(HashWordType *state) |
||||
{ |
||||
state[0] = 0x67452301L; |
||||
state[1] = 0xEFCDAB89L; |
||||
state[2] = 0x98BADCFEL; |
||||
state[3] = 0x10325476L; |
||||
state[4] = 0xC3D2E1F0L; |
||||
} |
||||
|
||||
#define f1(x,y,z) (z^(x&(y^z))) |
||||
#define f2(x,y,z) (x^y^z) |
||||
#define f3(x,y,z) ((x&y)|(z&(x|y))) |
||||
#define f4(x,y,z) (x^y^z) |
||||
|
||||
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ |
||||
#define R0(v,w,x,y,z,i) z+=f1(w,x,y)+blk0(i)+0x5A827999+rotlFixed(v,5);w=rotlFixed(w,30); |
||||
#define R1(v,w,x,y,z,i) z+=f1(w,x,y)+blk1(i)+0x5A827999+rotlFixed(v,5);w=rotlFixed(w,30); |
||||
#define R2(v,w,x,y,z,i) z+=f2(w,x,y)+blk1(i)+0x6ED9EBA1+rotlFixed(v,5);w=rotlFixed(w,30); |
||||
#define R3(v,w,x,y,z,i) z+=f3(w,x,y)+blk1(i)+0x8F1BBCDC+rotlFixed(v,5);w=rotlFixed(w,30); |
||||
#define R4(v,w,x,y,z,i) z+=f4(w,x,y)+blk1(i)+0xCA62C1D6+rotlFixed(v,5);w=rotlFixed(w,30); |
||||
|
||||
void SHA1::Transform(word32 *state, const word32 *data) |
||||
{ |
||||
word32 W[16]; |
||||
/* Copy context->state[] to working vars */ |
||||
word32 a = state[0]; |
||||
word32 b = state[1]; |
||||
word32 c = state[2]; |
||||
word32 d = state[3]; |
||||
word32 e = state[4]; |
||||
/* 4 rounds of 20 operations each. Loop unrolled. */ |
||||
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); |
||||
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); |
||||
R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); |
||||
R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); |
||||
R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); |
||||
R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); |
||||
R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); |
||||
R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); |
||||
R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); |
||||
R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); |
||||
R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); |
||||
R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); |
||||
R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); |
||||
R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); |
||||
R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); |
||||
R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); |
||||
R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); |
||||
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); |
||||
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); |
||||
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); |
||||
/* Add the working vars back into context.state[] */ |
||||
state[0] += a; |
||||
state[1] += b; |
||||
state[2] += c; |
||||
state[3] += d; |
||||
state[4] += e; |
||||
} |
||||
|
||||
// end of Steve Reid's code
|
||||
|
||||
// *************************************************************
|
||||
|
||||
void SHA224::InitState(HashWordType *state) |
||||
{ |
||||
static const word32 s[8] = {0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4}; |
||||
memcpy(state, s, sizeof(s)); |
||||
} |
||||
|
||||
void SHA256::InitState(HashWordType *state) |
||||
{ |
||||
static const word32 s[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; |
||||
memcpy(state, s, sizeof(s)); |
||||
} |
||||
|
||||
static const word32 SHA256_K[64] = { |
||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, |
||||
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, |
||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, |
||||
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, |
||||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, |
||||
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, |
||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, |
||||
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, |
||||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, |
||||
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, |
||||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, |
||||
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, |
||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, |
||||
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, |
||||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, |
||||
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 |
||||
}; |
||||
|
||||
#define blk2(i) (W[i&15]+=s1(W[(i-2)&15])+W[(i-7)&15]+s0(W[(i-15)&15])) |
||||
|
||||
#define Ch(x,y,z) (z^(x&(y^z))) |
||||
#define Maj(x,y,z) ((x&y)|(z&(x|y))) |
||||
|
||||
#define a(i) T[(0-i)&7] |
||||
#define b(i) T[(1-i)&7] |
||||
#define c(i) T[(2-i)&7] |
||||
#define d(i) T[(3-i)&7] |
||||
#define e(i) T[(4-i)&7] |
||||
#define f(i) T[(5-i)&7] |
||||
#define g(i) T[(6-i)&7] |
||||
#define h(i) T[(7-i)&7] |
||||
|
||||
#define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA256_K[i+j]+(j?blk2(i):blk0(i));\ |
||||
d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i)) |
||||
|
||||
// for SHA256
|
||||
#define S0(x) (rotrFixed(x,2)^rotrFixed(x,13)^rotrFixed(x,22)) |
||||
#define S1(x) (rotrFixed(x,6)^rotrFixed(x,11)^rotrFixed(x,25)) |
||||
#define s0(x) (rotrFixed(x,7)^rotrFixed(x,18)^(x>>3)) |
||||
#define s1(x) (rotrFixed(x,17)^rotrFixed(x,19)^(x>>10)) |
||||
|
||||
void SHA256::Transform(word32 *state, const word32 *data) |
||||
{ |
||||
word32 W[16]; |
||||
word32 T[8]; |
||||
/* Copy context->state[] to working vars */ |
||||
memcpy(T, state, sizeof(T)); |
||||
/* 64 operations, partially loop unrolled */ |
||||
for (unsigned int j=0; j<64; j+=16) |
||||
{ |
||||
R( 0); R( 1); R( 2); R( 3); |
||||
R( 4); R( 5); R( 6); R( 7); |
||||
R( 8); R( 9); R(10); R(11); |
||||
R(12); R(13); R(14); R(15); |
||||
} |
||||
/* Add the working vars back into context.state[] */ |
||||
state[0] += a(0); |
||||
state[1] += b(0); |
||||
state[2] += c(0); |
||||
state[3] += d(0); |
||||
state[4] += e(0); |
||||
state[5] += f(0); |
||||
state[6] += g(0); |
||||
state[7] += h(0); |
||||
} |
||||
|
||||
/*
|
||||
// smaller but slower
|
||||
void SHA256_Transform(word32 *state, const word32 *data) |
||||
{ |
||||
word32 T[20]; |
||||
word32 W[32]; |
||||
unsigned int i = 0, j = 0; |
||||
word32 *t = T+8; |
||||
|
||||
memcpy(t, state, 8*4); |
||||
word32 e = t[4], a = t[0]; |
||||
|
||||
do |
||||
{ |
||||
word32 w = data[j]; |
||||
W[j] = w; |
||||
w += K[j]; |
||||
w += t[7]; |
||||
w += S1(e); |
||||
w += Ch(e, t[5], t[6]); |
||||
e = t[3] + w; |
||||
t[3] = t[3+8] = e; |
||||
w += S0(t[0]); |
||||
a = w + Maj(a, t[1], t[2]); |
||||
t[-1] = t[7] = a; |
||||
--t; |
||||
++j; |
||||
if (j%8 == 0) |
||||
t += 8; |
||||
} while (j<16); |
||||
|
||||
do |
||||
{ |
||||
i = j&0xf; |
||||
word32 w = s1(W[i+16-2]) + s0(W[i+16-15]) + W[i] + W[i+16-7]; |
||||
W[i+16] = W[i] = w; |
||||
w += K[j]; |
||||
w += t[7]; |
||||
w += S1(e); |
||||
w += Ch(e, t[5], t[6]); |
||||
e = t[3] + w; |
||||
t[3] = t[3+8] = e; |
||||
w += S0(t[0]); |
||||
a = w + Maj(a, t[1], t[2]); |
||||
t[-1] = t[7] = a; |
||||
|
||||
w = s1(W[(i+1)+16-2]) + s0(W[(i+1)+16-15]) + W[(i+1)] + W[(i+1)+16-7]; |
||||
W[(i+1)+16] = W[(i+1)] = w; |
||||
w += K[j+1]; |
||||
w += (t-1)[7]; |
||||
w += S1(e); |
||||
w += Ch(e, (t-1)[5], (t-1)[6]); |
||||
e = (t-1)[3] + w; |
||||
(t-1)[3] = (t-1)[3+8] = e; |
||||
w += S0((t-1)[0]); |
||||
a = w + Maj(a, (t-1)[1], (t-1)[2]); |
||||
(t-1)[-1] = (t-1)[7] = a; |
||||
|
||||
t-=2; |
||||
j+=2; |
||||
if (j%8 == 0) |
||||
t += 8; |
||||
} while (j<64); |
||||
|
||||
state[0] += a; |
||||
state[1] += t[1]; |
||||
state[2] += t[2]; |
||||
state[3] += t[3]; |
||||
state[4] += e; |
||||
state[5] += t[5]; |
||||
state[6] += t[6]; |
||||
state[7] += t[7]; |
||||
} |
||||
*/ |
||||
|
||||
#undef S0 |
||||
#undef S1 |
||||
#undef s0 |
||||
#undef s1 |
||||
#undef R |
||||
|
||||
// *************************************************************
|
||||
|
||||
#ifdef WORD64_AVAILABLE |
||||
|
||||
void SHA384::InitState(HashWordType *state) |
||||
{ |
||||
static const word64 s[8] = { |
||||
W64LIT(0xcbbb9d5dc1059ed8), W64LIT(0x629a292a367cd507), |
||||
W64LIT(0x9159015a3070dd17), W64LIT(0x152fecd8f70e5939), |
||||
W64LIT(0x67332667ffc00b31), W64LIT(0x8eb44a8768581511), |
||||
W64LIT(0xdb0c2e0d64f98fa7), W64LIT(0x47b5481dbefa4fa4)}; |
||||
memcpy(state, s, sizeof(s)); |
||||
} |
||||
|
||||
void SHA512::InitState(HashWordType *state) |
||||
{ |
||||
static const word64 s[8] = { |
||||
W64LIT(0x6a09e667f3bcc908), W64LIT(0xbb67ae8584caa73b), |
||||
W64LIT(0x3c6ef372fe94f82b), W64LIT(0xa54ff53a5f1d36f1), |
||||
W64LIT(0x510e527fade682d1), W64LIT(0x9b05688c2b3e6c1f), |
||||
W64LIT(0x1f83d9abfb41bd6b), W64LIT(0x5be0cd19137e2179)}; |
||||
memcpy(state, s, sizeof(s)); |
||||
} |
||||
|
||||
CRYPTOPP_ALIGN_DATA(16) static const word64 SHA512_K[80] CRYPTOPP_SECTION_ALIGN16 = { |
||||
W64LIT(0x428a2f98d728ae22), W64LIT(0x7137449123ef65cd), |
||||
W64LIT(0xb5c0fbcfec4d3b2f), W64LIT(0xe9b5dba58189dbbc), |
||||
W64LIT(0x3956c25bf348b538), W64LIT(0x59f111f1b605d019), |
||||
W64LIT(0x923f82a4af194f9b), W64LIT(0xab1c5ed5da6d8118), |
||||
W64LIT(0xd807aa98a3030242), W64LIT(0x12835b0145706fbe), |
||||
W64LIT(0x243185be4ee4b28c), W64LIT(0x550c7dc3d5ffb4e2), |
||||
W64LIT(0x72be5d74f27b896f), W64LIT(0x80deb1fe3b1696b1), |
||||
W64LIT(0x9bdc06a725c71235), W64LIT(0xc19bf174cf692694), |
||||
W64LIT(0xe49b69c19ef14ad2), W64LIT(0xefbe4786384f25e3), |
||||
W64LIT(0x0fc19dc68b8cd5b5), W64LIT(0x240ca1cc77ac9c65), |
||||
W64LIT(0x2de92c6f592b0275), W64LIT(0x4a7484aa6ea6e483), |
||||
W64LIT(0x5cb0a9dcbd41fbd4), W64LIT(0x76f988da831153b5), |
||||
W64LIT(0x983e5152ee66dfab), W64LIT(0xa831c66d2db43210), |
||||
W64LIT(0xb00327c898fb213f), W64LIT(0xbf597fc7beef0ee4), |
||||
W64LIT(0xc6e00bf33da88fc2), W64LIT(0xd5a79147930aa725), |
||||
W64LIT(0x06ca6351e003826f), W64LIT(0x142929670a0e6e70), |
||||
W64LIT(0x27b70a8546d22ffc), W64LIT(0x2e1b21385c26c926), |
||||
W64LIT(0x4d2c6dfc5ac42aed), W64LIT(0x53380d139d95b3df), |
||||
W64LIT(0x650a73548baf63de), W64LIT(0x766a0abb3c77b2a8), |
||||
W64LIT(0x81c2c92e47edaee6), W64LIT(0x92722c851482353b), |
||||
W64LIT(0xa2bfe8a14cf10364), W64LIT(0xa81a664bbc423001), |
||||
W64LIT(0xc24b8b70d0f89791), W64LIT(0xc76c51a30654be30), |
||||
W64LIT(0xd192e819d6ef5218), W64LIT(0xd69906245565a910), |
||||
W64LIT(0xf40e35855771202a), W64LIT(0x106aa07032bbd1b8), |
||||
W64LIT(0x19a4c116b8d2d0c8), W64LIT(0x1e376c085141ab53), |
||||
W64LIT(0x2748774cdf8eeb99), W64LIT(0x34b0bcb5e19b48a8), |
||||
W64LIT(0x391c0cb3c5c95a63), W64LIT(0x4ed8aa4ae3418acb), |
||||
W64LIT(0x5b9cca4f7763e373), W64LIT(0x682e6ff3d6b2b8a3), |
||||
W64LIT(0x748f82ee5defb2fc), W64LIT(0x78a5636f43172f60), |
||||
W64LIT(0x84c87814a1f0ab72), W64LIT(0x8cc702081a6439ec), |
||||
W64LIT(0x90befffa23631e28), W64LIT(0xa4506cebde82bde9), |
||||
W64LIT(0xbef9a3f7b2c67915), W64LIT(0xc67178f2e372532b), |
||||
W64LIT(0xca273eceea26619c), W64LIT(0xd186b8c721c0c207), |
||||
W64LIT(0xeada7dd6cde0eb1e), W64LIT(0xf57d4f7fee6ed178), |
||||
W64LIT(0x06f067aa72176fba), W64LIT(0x0a637dc5a2c898a6), |
||||
W64LIT(0x113f9804bef90dae), W64LIT(0x1b710b35131c471b), |
||||
W64LIT(0x28db77f523047d84), W64LIT(0x32caab7b40c72493), |
||||
W64LIT(0x3c9ebe0a15c9bebc), W64LIT(0x431d67c49c100d4c), |
||||
W64LIT(0x4cc5d4becb3e42b6), W64LIT(0x597f299cfc657e2a), |
||||
W64LIT(0x5fcb6fab3ad6faec), W64LIT(0x6c44198c4a475817) |
||||
}; |
||||
|
||||
#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86 |
||||
// put assembly version in separate function, otherwise MSVC 2005 SP1 doesn't generate correct code for the non-assembly version
|
||||
CRYPTOPP_NAKED static void CRYPTOPP_FASTCALL SHA512_SSE2_Transform(word64 *state, const word64 *data) |
||||
{ |
||||
#ifdef __GNUC__ |
||||
__asm__ __volatile__ |
||||
( |
||||
".intel_syntax noprefix;" |
||||
AS1( push ebx) |
||||
AS2( mov ebx, eax) |
||||
#else |
||||
AS1( push ebx) |
||||
AS1( push esi) |
||||
AS1( push edi) |
||||
AS2( lea ebx, SHA512_K) |
||||
#endif |
||||
|
||||
AS2( mov eax, esp) |
||||
AS2( and esp, 0xfffffff0) |
||||
AS2( sub esp, 27*16) // 17*16 for expanded data, 20*8 for state
|
||||
AS1( push eax) |
||||
AS2( xor eax, eax) |
||||
AS2( lea edi, [esp+4+8*8]) // start at middle of state buffer. will decrement pointer each round to avoid copying
|
||||
AS2( lea esi, [esp+4+20*8+8]) // 16-byte alignment, then add 8
|
||||
|
||||
AS2( movq mm4, [ecx+0*8]) |
||||
AS2( movq [edi+0*8], mm4) |
||||
AS2( movq mm0, [ecx+1*8]) |
||||
AS2( movq [edi+1*8], mm0) |
||||
AS2( movq mm0, [ecx+2*8]) |
||||
AS2( movq [edi+2*8], mm0) |
||||
AS2( movq mm0, [ecx+3*8]) |
||||
AS2( movq [edi+3*8], mm0) |
||||
AS2( movq mm5, [ecx+4*8]) |
||||
AS2( movq [edi+4*8], mm5) |
||||
AS2( movq mm0, [ecx+5*8]) |
||||
AS2( movq [edi+5*8], mm0) |
||||
AS2( movq mm0, [ecx+6*8]) |
||||
AS2( movq [edi+6*8], mm0) |
||||
AS2( movq mm0, [ecx+7*8]) |
||||
AS2( movq [edi+7*8], mm0) |
||||
ASJ( jmp, 0, f) |
||||
|
||||
#define SSE2_S0_S1(r, a, b, c) \ |
||||
AS2( movq mm6, r)\ |
||||
AS2( psrlq r, a)\ |
||||
AS2( movq mm7, r)\ |
||||
AS2( psllq mm6, 64-c)\ |
||||
AS2( pxor mm7, mm6)\ |
||||
AS2( psrlq r, b-a)\ |
||||
AS2( pxor mm7, r)\ |
||||
AS2( psllq mm6, c-b)\ |
||||
AS2( pxor mm7, mm6)\ |
||||
AS2( psrlq r, c-b)\ |
||||
AS2( pxor r, mm7)\ |
||||
AS2( psllq mm6, b-a)\ |
||||
AS2( pxor r, mm6) |
||||
|
||||
#define SSE2_s0(r, a, b, c) \ |
||||
AS2( movdqa xmm6, r)\ |
||||
AS2( psrlq r, a)\ |
||||
AS2( movdqa xmm7, r)\ |
||||
AS2( psllq xmm6, 64-c)\ |
||||
AS2( pxor xmm7, xmm6)\ |
||||
AS2( psrlq r, b-a)\ |
||||
AS2( pxor xmm7, r)\ |
||||
AS2( psrlq r, c-b)\ |
||||
AS2( pxor r, xmm7)\ |
||||
AS2( psllq xmm6, c-a)\ |
||||
AS2( pxor r, xmm6) |
||||
|
||||
#define SSE2_s1(r, a, b, c) \ |
||||
AS2( movdqa xmm6, r)\ |
||||
AS2( psrlq r, a)\ |
||||
AS2( movdqa xmm7, r)\ |
||||
AS2( psllq xmm6, 64-c)\ |
||||
AS2( pxor xmm7, xmm6)\ |
||||
AS2( psrlq r, b-a)\ |
||||
AS2( pxor xmm7, r)\ |
||||
AS2( psllq xmm6, c-b)\ |
||||
AS2( pxor xmm7, xmm6)\ |
||||
AS2( psrlq r, c-b)\ |
||||
AS2( pxor r, xmm7) |
||||
|
||||
ASL(SHA512_Round) |
||||
// k + w is in mm0, a is in mm4, e is in mm5
|
||||
AS2( paddq mm0, [edi+7*8]) // h
|
||||
AS2( movq mm2, [edi+5*8]) // f
|
||||
AS2( movq mm3, [edi+6*8]) // g
|
||||
AS2( pxor mm2, mm3) |
||||
AS2( pand mm2, mm5) |
||||
SSE2_S0_S1(mm5,14,18,41) |
||||
AS2( pxor mm2, mm3) |
||||
AS2( paddq mm0, mm2) // h += Ch(e,f,g)
|
||||
AS2( paddq mm5, mm0) // h += S1(e)
|
||||
AS2( movq mm2, [edi+1*8]) // b
|
||||
AS2( movq mm1, mm2) |
||||
AS2( por mm2, mm4) |
||||
AS2( pand mm2, [edi+2*8]) // c
|
||||
AS2( pand mm1, mm4) |
||||
AS2( por mm1, mm2) |
||||
AS2( paddq mm1, mm5) // temp = h + Maj(a,b,c)
|
||||
AS2( paddq mm5, [edi+3*8]) // e = d + h
|
||||
AS2( movq [edi+3*8], mm5) |
||||
AS2( movq [edi+11*8], mm5) |
||||
SSE2_S0_S1(mm4,28,34,39) // S0(a)
|
||||
AS2( paddq mm4, mm1) // a = temp + S0(a)
|
||||
AS2( movq [edi-8], mm4) |
||||
AS2( movq [edi+7*8], mm4) |
||||
AS1( ret) |
||||
|
||||
// first 16 rounds
|
||||
ASL(0) |
||||
AS2( movq mm0, [edx+eax*8]) |
||||
AS2( movq [esi+eax*8], mm0) |
||||
AS2( movq [esi+eax*8+16*8], mm0) |
||||
AS2( paddq mm0, [ebx+eax*8]) |
||||
ASC( call, SHA512_Round) |
||||
AS1( inc eax) |
||||
AS2( sub edi, 8) |
||||
AS2( test eax, 7) |
||||
ASJ( jnz, 0, b) |
||||
AS2( add edi, 8*8) |
||||
AS2( cmp eax, 16) |
||||
ASJ( jne, 0, b) |
||||
|
||||
// rest of the rounds
|
||||
AS2( movdqu xmm0, [esi+(16-2)*8]) |
||||
ASL(1) |
||||
// data expansion, W[i-2] already in xmm0
|
||||
AS2( movdqu xmm3, [esi]) |
||||
AS2( paddq xmm3, [esi+(16-7)*8]) |
||||
AS2( movdqa xmm2, [esi+(16-15)*8]) |
||||
SSE2_s1(xmm0, 6, 19, 61) |
||||
AS2( paddq xmm0, xmm3) |
||||
SSE2_s0(xmm2, 1, 7, 8) |
||||
AS2( paddq xmm0, xmm2) |
||||
AS2( movdq2q mm0, xmm0) |
||||
AS2( movhlps xmm1, xmm0) |
||||
AS2( paddq mm0, [ebx+eax*8]) |
||||
AS2( movlps [esi], xmm0) |
||||
AS2( movlps [esi+8], xmm1) |
||||
AS2( movlps [esi+8*16], xmm0) |
||||
AS2( movlps [esi+8*17], xmm1) |
||||
// 2 rounds
|
||||
ASC( call, SHA512_Round) |
||||
AS2( sub edi, 8) |
||||
AS2( movdq2q mm0, xmm1) |
||||
AS2( paddq mm0, [ebx+eax*8+8]) |
||||
ASC( call, SHA512_Round) |
||||
// update indices and loop
|
||||
AS2( add esi, 16) |
||||
AS2( add eax, 2) |
||||
AS2( sub edi, 8) |
||||
AS2( test eax, 7) |
||||
ASJ( jnz, 1, b) |
||||
// do housekeeping every 8 rounds
|
||||
AS2( mov esi, 0xf) |
||||
AS2( and esi, eax) |
||||
AS2( lea esi, [esp+4+20*8+8+esi*8]) |
||||
AS2( add edi, 8*8) |
||||
AS2( cmp eax, 80) |
||||
ASJ( jne, 1, b) |
||||
|
||||
#define SSE2_CombineState(i) \ |
||||
AS2( movq mm0, [edi+i*8])\ |
||||
AS2( paddq mm0, [ecx+i*8])\ |
||||
AS2( movq [ecx+i*8], mm0) |
||||
|
||||
SSE2_CombineState(0) |
||||
SSE2_CombineState(1) |
||||
SSE2_CombineState(2) |
||||
SSE2_CombineState(3) |
||||
SSE2_CombineState(4) |
||||
SSE2_CombineState(5) |
||||
SSE2_CombineState(6) |
||||
SSE2_CombineState(7) |
||||
|
||||
AS1( pop esp) |
||||
AS1( emms) |
||||
|
||||
#if defined(__GNUC__) |
||||
AS1( pop ebx) |
||||
".att_syntax prefix;" |
||||
: |
||||
: "a" (SHA512_K), "c" (state), "d" (data) |
||||
: "%esi", "%edi", "memory", "cc" |
||||
); |
||||
#else |
||||
AS1( pop edi) |
||||
AS1( pop esi) |
||||
AS1( pop ebx) |
||||
AS1( ret) |
||||
#endif |
||||
} |
||||
#endif // #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
|
||||
|
||||
void SHA512::Transform(word64 *state, const word64 *data) |
||||
{ |
||||
#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86 |
||||
if (HasSSE2()) |
||||
{ |
||||
SHA512_SSE2_Transform(state, data); |
||||
return; |
||||
} |
||||
#endif |
||||
|
||||
#define S0(x) (rotrFixed(x,28)^rotrFixed(x,34)^rotrFixed(x,39)) |
||||
#define S1(x) (rotrFixed(x,14)^rotrFixed(x,18)^rotrFixed(x,41)) |
||||
#define s0(x) (rotrFixed(x,1)^rotrFixed(x,8)^(x>>7)) |
||||
#define s1(x) (rotrFixed(x,19)^rotrFixed(x,61)^(x>>6)) |
||||
|
||||
#define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA512_K[i+j]+(j?blk2(i):blk0(i));\ |
||||
d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i)) |
||||
|
||||
word64 W[16]; |
||||
word64 T[8]; |
||||
/* Copy context->state[] to working vars */ |
||||
memcpy(T, state, sizeof(T)); |
||||
/* 80 operations, partially loop unrolled */ |
||||
for (unsigned int j=0; j<80; j+=16) |
||||
{ |
||||
R( 0); R( 1); R( 2); R( 3); |
||||
R( 4); R( 5); R( 6); R( 7); |
||||
R( 8); R( 9); R(10); R(11); |
||||
R(12); R(13); R(14); R(15); |
||||
} |
||||
/* Add the working vars back into context.state[] */ |
||||
state[0] += a(0); |
||||
state[1] += b(0); |
||||
state[2] += c(0); |
||||
state[3] += d(0); |
||||
state[4] += e(0); |
||||
state[5] += f(0); |
||||
state[6] += g(0); |
||||
state[7] += h(0); |
||||
} |
||||
|
||||
#endif |
||||
|
||||
} |
@ -0,0 +1,177 @@
@@ -0,0 +1,177 @@
|
||||
// This file is public domain
|
||||
// SHA routines extracted as a standalone file from:
|
||||
// Crypto++: a C++ Class Library of Cryptographic Schemes
|
||||
// Version 5.5.2 (9/24/2007)
|
||||
// http://www.cryptopp.com
|
||||
#ifndef CRYPTOPP_SHA_H |
||||
#define CRYPTOPP_SHA_H |
||||
#include <stdlib.h> |
||||
|
||||
namespace CryptoPP |
||||
{ |
||||
|
||||
//
|
||||
// Dependencies
|
||||
//
|
||||
|
||||
typedef unsigned char byte; |
||||
typedef unsigned short word16; |
||||
typedef unsigned int word32; |
||||
#if defined(_MSC_VER) || defined(__BORLANDC__) |
||||
typedef unsigned __int64 word64; |
||||
#else |
||||
typedef unsigned long long word64; |
||||
#endif |
||||
|
||||
template <class T> inline T rotlFixed(T x, unsigned int y) |
||||
{ |
||||
assert(y < sizeof(T)*8); |
||||
return T((x<<y) | (x>>(sizeof(T)*8-y))); |
||||
} |
||||
|
||||
template <class T> inline T rotrFixed(T x, unsigned int y) |
||||
{ |
||||
assert(y < sizeof(T)*8); |
||||
return T((x>>y) | (x<<(sizeof(T)*8-y))); |
||||
} |
||||
|
||||
// ************** endian reversal ***************
|
||||
|
||||
#ifdef _MSC_VER |
||||
#if _MSC_VER >= 1400 |
||||
#define CRYPTOPP_FAST_ROTATE(x) 1 |
||||
#elif _MSC_VER >= 1300 |
||||
#define CRYPTOPP_FAST_ROTATE(x) ((x) == 32 | (x) == 64) |
||||
#else |
||||
#define CRYPTOPP_FAST_ROTATE(x) ((x) == 32) |
||||
#endif |
||||
#elif (defined(__MWERKS__) && TARGET_CPU_PPC) || \ |
||||
(defined(__GNUC__) && (defined(_ARCH_PWR2) || defined(_ARCH_PWR) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || defined(_ARCH_COM))) |
||||
#define CRYPTOPP_FAST_ROTATE(x) ((x) == 32) |
||||
#elif defined(__GNUC__) && (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86) // depend on GCC's peephole optimization to generate rotate instructions
|
||||
#define CRYPTOPP_FAST_ROTATE(x) 1 |
||||
#else |
||||
#define CRYPTOPP_FAST_ROTATE(x) 0 |
||||
#endif |
||||
|
||||
inline byte ByteReverse(byte value) |
||||
{ |
||||
return value; |
||||
} |
||||
|
||||
inline word16 ByteReverse(word16 value) |
||||
{ |
||||
#ifdef CRYPTOPP_BYTESWAP_AVAILABLE |
||||
return bswap_16(value); |
||||
#elif defined(_MSC_VER) && _MSC_VER >= 1300 |
||||
return _byteswap_ushort(value); |
||||
#else |
||||
return rotlFixed(value, 8U); |
||||
#endif |
||||
} |
||||
|
||||
inline word32 ByteReverse(word32 value) |
||||
{ |
||||
#if defined(__GNUC__) |
||||
__asm__ ("bswap %0" : "=r" (value) : "0" (value)); |
||||
return value; |
||||
#elif defined(CRYPTOPP_BYTESWAP_AVAILABLE) |
||||
return bswap_32(value); |
||||
#elif defined(__MWERKS__) && TARGET_CPU_PPC |
||||
return (word32)__lwbrx(&value,0); |
||||
#elif _MSC_VER >= 1400 || (_MSC_VER >= 1300 && !defined(_DLL)) |
||||
return _byteswap_ulong(value); |
||||
#elif CRYPTOPP_FAST_ROTATE(32) |
||||
// 5 instructions with rotate instruction, 9 without
|
||||
return (rotrFixed(value, 8U) & 0xff00ff00) | (rotlFixed(value, 8U) & 0x00ff00ff); |
||||
#else |
||||
// 6 instructions with rotate instruction, 8 without
|
||||
value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8); |
||||
return rotlFixed(value, 16U); |
||||
#endif |
||||
} |
||||
|
||||
#ifdef WORD64_AVAILABLE |
||||
inline word64 ByteReverse(word64 value) |
||||
{ |
||||
#if defined(__GNUC__) && defined(__x86_64__) |
||||
__asm__ ("bswap %0" : "=r" (value) : "0" (value)); |
||||
return value; |
||||
#elif defined(CRYPTOPP_BYTESWAP_AVAILABLE) |
||||
return bswap_64(value); |
||||
#elif defined(_MSC_VER) && _MSC_VER >= 1300 |
||||
return _byteswap_uint64(value); |
||||
#elif defined(CRYPTOPP_SLOW_WORD64) |
||||
return (word64(ByteReverse(word32(value))) << 32) | ByteReverse(word32(value>>32)); |
||||
#else |
||||
value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) | ((value & W64LIT(0x00FF00FF00FF00FF)) << 8); |
||||
value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) | ((value & W64LIT(0x0000FFFF0000FFFF)) << 16); |
||||
return rotlFixed(value, 32U); |
||||
#endif |
||||
} |
||||
#endif |
||||
|
||||
|
||||
//
|
||||
// SHA
|
||||
//
|
||||
|
||||
// http://www.weidai.com/scan-mirror/md.html#SHA-1
|
||||
class SHA1 |
||||
{ |
||||
public: |
||||
typedef word32 HashWordType; |
||||
static void InitState(word32 *state); |
||||
static void Transform(word32 *digest, const word32 *data); |
||||
static const char * StaticAlgorithmName() {return "SHA-1";} |
||||
}; |
||||
|
||||
typedef SHA1 SHA; // for backwards compatibility
|
||||
|
||||
// implements the SHA-256 standard
|
||||
class SHA256 |
||||
{ |
||||
public: |
||||
typedef word32 HashWordType; |
||||
static void InitState(word32 *state); |
||||
static void Transform(word32 *digest, const word32 *data); |
||||
static const char * StaticAlgorithmName() {return "SHA-256";} |
||||
}; |
||||
|
||||
// implements the SHA-224 standard
|
||||
class SHA224 |
||||
{ |
||||
public: |
||||
typedef word32 HashWordType; |
||||
static void InitState(word32 *state); |
||||
static void Transform(word32 *digest, const word32 *data) {SHA256::Transform(digest, data);} |
||||
static const char * StaticAlgorithmName() {return "SHA-224";} |
||||
}; |
||||
|
||||
#ifdef WORD64_AVAILABLE |
||||
|
||||
// implements the SHA-512 standard
|
||||
class SHA512 |
||||
{ |
||||
public: |
||||
typedef word64 HashWordType; |
||||
static void InitState(word64 *state); |
||||
static void Transform(word64 *digest, const word64 *data); |
||||
static const char * StaticAlgorithmName() {return "SHA-512";} |
||||
}; |
||||
|
||||
// implements the SHA-384 standard
|
||||
class SHA384 |
||||
{ |
||||
public: |
||||
typedef word64 HashWordType; |
||||
static void InitState(word64 *state); |
||||
static void Transform(word64 *digest, const word64 *data) {SHA512::Transform(digest, data);} |
||||
static const char * StaticAlgorithmName() {return "SHA-384";} |
||||
}; |
||||
|
||||
#endif |
||||
|
||||
} |
||||
|
||||
#endif |
@ -0,0 +1,420 @@
@@ -0,0 +1,420 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
|
||||
|
||||
DECLARE_EVENT_TYPE(wxEVT_CROSSTHREADCALL, -1) |
||||
DECLARE_EVENT_TYPE(wxEVT_REPLY1, -1) |
||||
DECLARE_EVENT_TYPE(wxEVT_REPLY2, -1) |
||||
DECLARE_EVENT_TYPE(wxEVT_REPLY3, -1) |
||||
DECLARE_EVENT_TYPE(wxEVT_TABLEADDED, -1) |
||||
DECLARE_EVENT_TYPE(wxEVT_TABLEUPDATED, -1) |
||||
DECLARE_EVENT_TYPE(wxEVT_TABLEDELETED, -1) |
||||
|
||||
enum |
||||
{ |
||||
UICALL_ADDORDER = 1, |
||||
UICALL_UPDATEORDER, |
||||
}; |
||||
|
||||
|
||||
|
||||
extern void HandleCtrlA(wxKeyEvent& event); |
||||
extern string DateTimeStr(int64 nTime); |
||||
extern string FormatTxStatus(const CWalletTx& wtx); |
||||
extern void CrossThreadCall(int nID, void* pdata); |
||||
extern void MainFrameRepaint(); |
||||
extern void Shutdown(void* parg); |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class CMainFrame : public CMainFrameBase |
||||
{ |
||||
protected: |
||||
// Event handlers
|
||||
void OnClose(wxCloseEvent& event); |
||||
void OnMouseEvents(wxMouseEvent& event); |
||||
void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); } |
||||
void OnIdle(wxIdleEvent& event); |
||||
void OnPaint(wxPaintEvent& event); |
||||
void OnPaintListCtrl(wxPaintEvent& event); |
||||
void OnMenuFileExit(wxCommandEvent& event); |
||||
void OnMenuOptionsGenerate(wxCommandEvent& event); |
||||
void OnMenuOptionsChangeYourAddress(wxCommandEvent& event); |
||||
void OnMenuOptionsOptions(wxCommandEvent& event); |
||||
void OnMenuHelpAbout(wxCommandEvent& event); |
||||
void OnButtonSend(wxCommandEvent& event); |
||||
void OnButtonAddressBook(wxCommandEvent& event); |
||||
void OnSetFocusAddress(wxFocusEvent& event); |
||||
void OnMouseEventsAddress(wxMouseEvent& event); |
||||
void OnButtonCopy(wxCommandEvent& event); |
||||
void OnButtonChange(wxCommandEvent& event); |
||||
void OnListColBeginDrag(wxListEvent& event); |
||||
void OnListItemActivatedAllTransactions(wxListEvent& event); |
||||
void OnListItemActivatedProductsSent(wxListEvent& event); |
||||
void OnListItemActivatedOrdersSent(wxListEvent& event); |
||||
void OnListItemActivatedOrdersReceived(wxListEvent& event); |
||||
|
||||
public: |
||||
/** Constructor */ |
||||
CMainFrame(wxWindow* parent); |
||||
~CMainFrame(); |
||||
|
||||
// Custom
|
||||
bool fRefreshListCtrl; |
||||
bool fRefreshListCtrlRunning; |
||||
bool fOnSetFocusAddress; |
||||
CBlockIndex* pindexBestLast; |
||||
set<uint256> setUnmaturedDisplayed; |
||||
|
||||
void OnCrossThreadCall(wxCommandEvent& event); |
||||
void InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxString& str1, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5); |
||||
void InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex=-1); |
||||
void RefreshListCtrl(); |
||||
void RefreshStatus(); |
||||
}; |
||||
|
||||
|
||||
|
||||
|
||||
class CTxDetailsDialog : public CTxDetailsDialogBase |
||||
{ |
||||
protected: |
||||
// Event handlers
|
||||
void OnButtonOK(wxCommandEvent& event); |
||||
|
||||
public: |
||||
/** Constructor */ |
||||
CTxDetailsDialog(wxWindow* parent, CWalletTx wtx); |
||||
|
||||
// State
|
||||
CWalletTx wtx; |
||||
}; |
||||
|
||||
|
||||
|
||||
class COptionsDialog : public COptionsDialogBase |
||||
{ |
||||
protected: |
||||
// Event handlers
|
||||
void OnKillFocusTransactionFee(wxFocusEvent& event); |
||||
void OnButtonOK(wxCommandEvent& event); |
||||
void OnButtonCancel(wxCommandEvent& event); |
||||
|
||||
public: |
||||
/** Constructor */ |
||||
COptionsDialog(wxWindow* parent); |
||||
}; |
||||
|
||||
|
||||
|
||||
class CAboutDialog : public CAboutDialogBase |
||||
{ |
||||
protected: |
||||
// Event handlers
|
||||
void OnButtonOK(wxCommandEvent& event); |
||||
|
||||
public: |
||||
/** Constructor */ |
||||
CAboutDialog(wxWindow* parent); |
||||
}; |
||||
|
||||
|
||||
|
||||
class CSendDialog : public CSendDialogBase |
||||
{ |
||||
protected: |
||||
// Event handlers
|
||||
void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); } |
||||
void OnTextAddress(wxCommandEvent& event); |
||||
void OnKillFocusAmount(wxFocusEvent& event); |
||||
void OnButtonAddressBook(wxCommandEvent& event); |
||||
void OnButtonPaste(wxCommandEvent& event); |
||||
void OnButtonSend(wxCommandEvent& event); |
||||
void OnButtonCancel(wxCommandEvent& event); |
||||
|
||||
public: |
||||
/** Constructor */ |
||||
CSendDialog(wxWindow* parent, const wxString& strAddress=""); |
||||
}; |
||||
|
||||
|
||||
|
||||
class CSendingDialog : public CSendingDialogBase |
||||
{ |
||||
public: |
||||
// Event handlers
|
||||
void OnClose(wxCloseEvent& event); |
||||
void OnButtonOK(wxCommandEvent& event); |
||||
void OnButtonCancel(wxCommandEvent& event); |
||||
void OnPaint(wxPaintEvent& event); |
||||
|
||||
public: |
||||
/** Constructor */ |
||||
CSendingDialog(wxWindow* parent, const CAddress& addrIn, int64 nPriceIn, const CWalletTx& wtxIn); |
||||
~CSendingDialog(); |
||||
|
||||
// State
|
||||
CAddress addr; |
||||
int64 nPrice; |
||||
CWalletTx wtx; |
||||
wxDateTime start; |
||||
string strStatus; |
||||
bool fCanCancel; |
||||
bool fAbort; |
||||
bool fSuccess; |
||||
bool fUIDone; |
||||
bool fWorkDone; |
||||
|
||||
void Close(); |
||||
void Repaint(); |
||||
bool Status(); |
||||
bool Status(const string& str); |
||||
bool Error(const string& str); |
||||
void StartTransfer(); |
||||
void OnReply2(CDataStream& vRecv); |
||||
void OnReply3(CDataStream& vRecv); |
||||
}; |
||||
|
||||
void SendingDialogStartTransfer(void* parg); |
||||
void SendingDialogOnReply2(void* parg, CDataStream& vRecv); |
||||
void SendingDialogOnReply3(void* parg, CDataStream& vRecv); |
||||
|
||||
|
||||
|
||||
class CYourAddressDialog : public CYourAddressDialogBase |
||||
{ |
||||
protected: |
||||
// Event handlers
|
||||
void OnListEndLabelEdit(wxListEvent& event); |
||||
void OnListItemSelected(wxListEvent& event); |
||||
void OnListItemActivated(wxListEvent& event); |
||||
void OnButtonRename(wxCommandEvent& event); |
||||
void OnButtonNew(wxCommandEvent& event); |
||||
void OnButtonCopy(wxCommandEvent& event); |
||||
void OnButtonOK(wxCommandEvent& event); |
||||
void OnButtonCancel(wxCommandEvent& event); |
||||
void OnClose(wxCloseEvent& event); |
||||
|
||||
public: |
||||
/** Constructor */ |
||||
CYourAddressDialog(wxWindow* parent); |
||||
CYourAddressDialog(wxWindow* parent, const string& strInitSelected); |
||||
|
||||
// Custom
|
||||
wxString GetAddress(); |
||||
}; |
||||
|
||||
|
||||
|
||||
class CAddressBookDialog : public CAddressBookDialogBase |
||||
{ |
||||
protected: |
||||
// Event handlers
|
||||
void OnListEndLabelEdit(wxListEvent& event); |
||||
void OnListItemSelected(wxListEvent& event); |
||||
void OnListItemActivated(wxListEvent& event); |
||||
void OnButtonEdit(wxCommandEvent& event); |
||||
void OnButtonDelete(wxCommandEvent& event); |
||||
void OnButtonNew(wxCommandEvent& event); |
||||
void OnButtonCopy(wxCommandEvent& event); |
||||
void OnButtonOK(wxCommandEvent& event); |
||||
void OnButtonCancel(wxCommandEvent& event); |
||||
void OnClose(wxCloseEvent& event); |
||||
|
||||
public: |
||||
/** Constructor */ |
||||
CAddressBookDialog(wxWindow* parent, const wxString& strInitSelected, bool fSendingIn); |
||||
|
||||
// Custom
|
||||
bool fSending; |
||||
wxString GetAddress(); |
||||
bool CheckIfMine(const string& strAddress, const string& strTitle); |
||||
}; |
||||
|
||||
|
||||
|
||||
class CProductsDialog : public CProductsDialogBase |
||||
{ |
||||
protected: |
||||
// Event handlers
|
||||
void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); } |
||||
void OnCombobox(wxCommandEvent& event); |
||||
void OnButtonSearch(wxCommandEvent& event); |
||||
void OnListItemActivated(wxListEvent& event); |
||||
|
||||
public: |
||||
/** Constructor */ |
||||
CProductsDialog(wxWindow* parent); |
||||
|
||||
// Custom
|
||||
vector<CProduct> m_vProduct; |
||||
}; |
||||
|
||||
|
||||
|
||||
class CEditProductDialog : public CEditProductDialogBase |
||||
{ |
||||
protected: |
||||
// Event handlers
|
||||
void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); } |
||||
void OnButtonDel0(wxCommandEvent& event); |
||||
void OnButtonDel1(wxCommandEvent& event); |
||||
void OnButtonDel2(wxCommandEvent& event); |
||||
void OnButtonDel3(wxCommandEvent& event); |
||||
void OnButtonDel4(wxCommandEvent& event); |
||||
void OnButtonDel5(wxCommandEvent& event); |
||||
void OnButtonDel6(wxCommandEvent& event); |
||||
void OnButtonDel7(wxCommandEvent& event); |
||||
void OnButtonDel8(wxCommandEvent& event); |
||||
void OnButtonDel9(wxCommandEvent& event); |
||||
void OnButtonDel10(wxCommandEvent& event); |
||||
void OnButtonDel11(wxCommandEvent& event); |
||||
void OnButtonDel12(wxCommandEvent& event); |
||||
void OnButtonDel13(wxCommandEvent& event); |
||||
void OnButtonDel14(wxCommandEvent& event); |
||||
void OnButtonDel15(wxCommandEvent& event); |
||||
void OnButtonDel16(wxCommandEvent& event); |
||||
void OnButtonDel17(wxCommandEvent& event); |
||||
void OnButtonDel18(wxCommandEvent& event); |
||||
void OnButtonDel19(wxCommandEvent& event); |
||||
void OnButtonAddField(wxCommandEvent& event); |
||||
void OnButtonSend(wxCommandEvent& event); |
||||
void OnButtonPreview(wxCommandEvent& event); |
||||
void OnButtonCancel(wxCommandEvent& event); |
||||
|
||||
public: |
||||
/** Constructor */ |
||||
CEditProductDialog(wxWindow* parent); |
||||
|
||||
// Custom
|
||||
enum { FIELDS_MAX = 20 }; |
||||
wxTextCtrl* m_textCtrlLabel[FIELDS_MAX]; |
||||
wxTextCtrl* m_textCtrlField[FIELDS_MAX]; |
||||
wxButton* m_buttonDel[FIELDS_MAX]; |
||||
|
||||
void LayoutAll(); |
||||
void ShowLine(int i, bool fShow=true); |
||||
void OnButtonDel(wxCommandEvent& event, int n); |
||||
void SetProduct(const CProduct& productIn); |
||||
void GetProduct(CProduct& product); |
||||
|
||||
}; |
||||
|
||||
|
||||
|
||||
class CViewProductDialog : public CViewProductDialogBase |
||||
{ |
||||
protected: |
||||
// Event handlers
|
||||
void OnButtonSubmitForm(wxCommandEvent& event); |
||||
void OnButtonCancelForm(wxCommandEvent& event); |
||||
void OnButtonBack(wxCommandEvent& event); |
||||
void OnButtonNext(wxCommandEvent& event); |
||||
void OnButtonCancel(wxCommandEvent& event); |
||||
|
||||
public: |
||||
/** Constructor */ |
||||
CViewProductDialog(wxWindow* parent, const CProduct& productIn); |
||||
~CViewProductDialog(); |
||||
|
||||
// Custom
|
||||
CProduct product; |
||||
enum { FIELDS_MAX = 20 }; |
||||
wxStaticText* m_staticTextLabel[FIELDS_MAX]; |
||||
wxTextCtrl* m_textCtrlField[FIELDS_MAX]; |
||||
wxChoice* m_choiceField[FIELDS_MAX]; |
||||
|
||||
void GetOrder(CWalletTx& order); |
||||
void UpdateProductDisplay(bool fDetails); |
||||
void OnReply1(wxCommandEvent& event); |
||||
}; |
||||
|
||||
|
||||
|
||||
class CViewOrderDialog : public CViewOrderDialogBase |
||||
{ |
||||
protected: |
||||
// Event handlers
|
||||
void OnButtonOK(wxCommandEvent& event); |
||||
|
||||
public: |
||||
/** Constructor */ |
||||
CViewOrderDialog(wxWindow* parent, CWalletTx order, bool fReceived); |
||||
|
||||
// Custom
|
||||
bool fReceived; |
||||
}; |
||||
|
||||
|
||||
|
||||
class CEditReviewDialog : public CEditReviewDialogBase |
||||
{ |
||||
protected: |
||||
// Event handlers
|
||||
void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); } |
||||
void OnButtonSubmit(wxCommandEvent& event); |
||||
void OnButtonCancel(wxCommandEvent& event); |
||||
|
||||
public: |
||||
/** Constructor */ |
||||
CEditReviewDialog(wxWindow* parent); |
||||
|
||||
// Custom
|
||||
void GetReview(CReview& review); |
||||
}; |
||||
|
||||
|
||||
|
||||
class CGetTextFromUserDialog : public CGetTextFromUserDialogBase |
||||
{ |
||||
protected: |
||||
// Event handlers
|
||||
void OnButtonOK(wxCommandEvent& event) { EndModal(true); } |
||||
void OnButtonCancel(wxCommandEvent& event) { EndModal(false); } |
||||
void OnClose(wxCloseEvent& event) { EndModal(false); } |
||||
|
||||
void OnKeyDown(wxKeyEvent& event) |
||||
{ |
||||
if (event.GetKeyCode() == '\r' || event.GetKeyCode() == WXK_NUMPAD_ENTER) |
||||
EndModal(true); |
||||
else |
||||
HandleCtrlA(event); |
||||
} |
||||
|
||||
public: |
||||
/** Constructor */ |
||||
CGetTextFromUserDialog(wxWindow* parent, |
||||
const string& strCaption, |
||||
const string& strMessage1, |
||||
const string& strValue1="", |
||||
const string& strMessage2="", |
||||
const string& strValue2="") : CGetTextFromUserDialogBase(parent, wxID_ANY, strCaption) |
||||
{ |
||||
m_staticTextMessage1->SetLabel(strMessage1); |
||||
m_textCtrl1->SetValue(strValue1); |
||||
if (!strMessage2.empty()) |
||||
{ |
||||
m_staticTextMessage2->Show(true); |
||||
m_staticTextMessage2->SetLabel(strMessage2); |
||||
m_textCtrl2->Show(true); |
||||
m_textCtrl2->SetValue(strValue2); |
||||
SetSize(wxDefaultCoord, 180); |
||||
} |
||||
} |
||||
|
||||
// Custom
|
||||
string GetValue() { return (string)m_textCtrl1->GetValue(); } |
||||
string GetValue1() { return (string)m_textCtrl1->GetValue(); } |
||||
string GetValue2() { return (string)m_textCtrl2->GetValue(); } |
||||
}; |
||||
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,14 @@
@@ -0,0 +1,14 @@
|
||||
bitcoin ICON "rc/bitcoin.ico" |
||||
|
||||
#include "wx/msw/wx.rc" |
||||
|
||||
check ICON "rc/check.ico" |
||||
send16 BITMAP "rc/send16.bmp" |
||||
send16mask BITMAP "rc/send16mask.bmp" |
||||
send16masknoshadow BITMAP "rc/send16masknoshadow.bmp" |
||||
send20 BITMAP "rc/send20.bmp" |
||||
send20mask BITMAP "rc/send20mask.bmp" |
||||
addressbook16 BITMAP "rc/addressbook16.bmp" |
||||
addressbook16mask BITMAP "rc/addressbook16mask.bmp" |
||||
addressbook20 BITMAP "rc/addressbook20.bmp" |
||||
addressbook20mask BITMAP "rc/addressbook20mask.bmp" |
@ -0,0 +1,723 @@
@@ -0,0 +1,723 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Apr 16 2008)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO "NOT" EDIT THIS FILE!
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __uibase__ |
||||
#define __uibase__ |
||||
|
||||
#include <wx/string.h> |
||||
#include <wx/bitmap.h> |
||||
#include <wx/image.h> |
||||
#include <wx/icon.h> |
||||
#include <wx/menu.h> |
||||
#include <wx/gdicmn.h> |
||||
#include <wx/font.h> |
||||
#include <wx/colour.h> |
||||
#include <wx/settings.h> |
||||
#include <wx/toolbar.h> |
||||
#include <wx/statusbr.h> |
||||
#include <wx/stattext.h> |
||||
#include <wx/textctrl.h> |
||||
#include <wx/button.h> |
||||
#include <wx/sizer.h> |
||||
#include <wx/panel.h> |
||||
#include <wx/choice.h> |
||||
#include <wx/listctrl.h> |
||||
#include <wx/notebook.h> |
||||
#include <wx/frame.h> |
||||
#include <wx/html/htmlwin.h> |
||||
#include <wx/dialog.h> |
||||
#include <wx/statbmp.h> |
||||
#include <wx/combobox.h> |
||||
#include <wx/scrolwin.h> |
||||
#include <wx/richtext/richtextctrl.h> |
||||
#include <wx/treectrl.h> |
||||
#include <wx/checkbox.h> |
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define wxID_MAINFRAME 1000 |
||||
#define wxID_OPTIONSGENERATEBITCOINS 1001 |
||||
#define wxID_BUTTONSEND 1002 |
||||
#define wxID_BUTTONRECEIVE 1003 |
||||
#define wxID_TEXTCTRLADDRESS 1004 |
||||
#define wxID_BUTTONCOPY 1005 |
||||
#define wxID_BUTTONCHANGE 1006 |
||||
#define wxID_TRANSACTIONFEE 1007 |
||||
#define wxID_TEXTCTRLPAYTO 1008 |
||||
#define wxID_BUTTONPASTE 1009 |
||||
#define wxID_BUTTONADDRESSBOOK 1010 |
||||
#define wxID_TEXTCTRLAMOUNT 1011 |
||||
#define wxID_CHOICETRANSFERTYPE 1012 |
||||
#define wxID_LISTCTRL 1013 |
||||
#define wxID_BUTTONRENAME 1014 |
||||
#define wxID_BUTTONNEW 1015 |
||||
#define wxID_BUTTONEDIT 1016 |
||||
#define wxID_BUTTONDELETE 1017 |
||||
#define wxID_DEL0 1018 |
||||
#define wxID_DEL1 1019 |
||||
#define wxID_DEL2 1020 |
||||
#define wxID_DEL3 1021 |
||||
#define wxID_DEL4 1022 |
||||
#define wxID_DEL5 1023 |
||||
#define wxID_DEL6 1024 |
||||
#define wxID_DEL7 1025 |
||||
#define wxID_DEL8 1026 |
||||
#define wxID_DEL9 1027 |
||||
#define wxID_DEL10 1028 |
||||
#define wxID_DEL11 1029 |
||||
#define wxID_DEL12 1030 |
||||
#define wxID_DEL13 1031 |
||||
#define wxID_DEL14 1032 |
||||
#define wxID_DEL15 1033 |
||||
#define wxID_DEL16 1034 |
||||
#define wxID_DEL17 1035 |
||||
#define wxID_DEL18 1036 |
||||
#define wxID_DEL19 1037 |
||||
#define wxID_BUTTONPREVIEW 1038 |
||||
#define wxID_BUTTONSAMPLE 1039 |
||||
#define wxID_CANCEL2 1040 |
||||
#define wxID_BUTTONBACK 1041 |
||||
#define wxID_BUTTONNEXT 1042 |
||||
#define wxID_SUBMIT 1043 |
||||
#define wxID_OPENNEWTABLE 1044 |
||||
#define wxID_DEALHAND 1045 |
||||
#define wxID_FOLD 1046 |
||||
#define wxID_CALL 1047 |
||||
#define wxID_RAISE 1048 |
||||
#define wxID_LEAVETABLE 1049 |
||||
#define wxID_DITCHPLAYER 1050 |
||||
#define wxID_TEXTCTRL 1051 |
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class CMainFrameBase
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class CMainFrameBase : public wxFrame |
||||
{ |
||||
private: |
||||
|
||||
protected: |
||||
wxMenuBar* m_menubar; |
||||
wxMenu* m_menuFile; |
||||
wxMenu* m_menuHelp; |
||||
wxToolBar* m_toolBar; |
||||
wxStatusBar* m_statusBar; |
||||
|
||||
wxStaticText* m_staticText32; |
||||
wxTextCtrl* m_textCtrlAddress; |
||||
wxButton* m_buttonCopy; |
||||
wxButton* m_button91; |
||||
|
||||
wxPanel* m_panel14; |
||||
wxStaticText* m_staticText41; |
||||
wxStaticText* m_staticTextBalance; |
||||
|
||||
wxChoice* m_choiceFilter; |
||||
wxNotebook* m_notebook; |
||||
wxPanel* m_panel7; |
||||
wxPanel* m_panel9; |
||||
wxPanel* m_panel8; |
||||
wxPanel* m_panel10; |
||||
wxPanel* m_panel11; |
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void OnClose(wxCloseEvent& event){ event.Skip(); } |
||||
virtual void OnIdle(wxIdleEvent& event){ event.Skip(); } |
||||
virtual void OnMouseEvents(wxMouseEvent& event){ event.Skip(); } |
||||
virtual void OnPaint(wxPaintEvent& event){ event.Skip(); } |
||||
virtual void OnMenuFileExit(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnMenuOptionsGenerate(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnMenuOptionsChangeYourAddress(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnMenuOptionsOptions(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnMenuHelpAbout(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonSend(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonAddressBook(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnKeyDown(wxKeyEvent& event){ event.Skip(); } |
||||
virtual void OnMouseEventsAddress(wxMouseEvent& event){ event.Skip(); } |
||||
virtual void OnSetFocusAddress(wxFocusEvent& event){ event.Skip(); } |
||||
virtual void OnButtonCopy(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonChange(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnListColBeginDrag(wxListEvent& event){ event.Skip(); } |
||||
virtual void OnListItemActivatedAllTransactions(wxListEvent& event){ event.Skip(); } |
||||
virtual void OnPaintListCtrl(wxPaintEvent& event){ event.Skip(); } |
||||
virtual void OnListItemActivatedOrdersSent(wxListEvent& event){ event.Skip(); } |
||||
virtual void OnListItemActivatedProductsSent(wxListEvent& event){ event.Skip(); } |
||||
virtual void OnListItemActivatedOrdersReceived(wxListEvent& event){ event.Skip(); } |
||||
|
||||
|
||||
public: |
||||
wxMenu* m_menuOptions; |
||||
wxListCtrl* m_listCtrl; |
||||
wxListCtrl* m_listCtrlEscrows; |
||||
wxListCtrl* m_listCtrlOrdersSent; |
||||
wxListCtrl* m_listCtrlProductsSent; |
||||
wxListCtrl* m_listCtrlOrdersReceived; |
||||
CMainFrameBase(wxWindow* parent, wxWindowID id = wxID_MAINFRAME, const wxString& title = wxT("Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(705,484), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL); |
||||
~CMainFrameBase(); |
||||
|
||||
}; |
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class CTxDetailsDialogBase
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class CTxDetailsDialogBase : public wxDialog |
||||
{ |
||||
private: |
||||
|
||||
protected: |
||||
wxHtmlWindow* m_htmlWin; |
||||
wxButton* m_buttonOK; |
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void OnButtonOK(wxCommandEvent& event){ event.Skip(); } |
||||
|
||||
|
||||
public: |
||||
CTxDetailsDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Transaction Details"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(620,450), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER); |
||||
~CTxDetailsDialogBase(); |
||||
|
||||
}; |
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class COptionsDialogBase
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class COptionsDialogBase : public wxDialog |
||||
{ |
||||
private: |
||||
|
||||
protected: |
||||
|
||||
wxStaticText* m_staticText32; |
||||
wxStaticText* m_staticText31; |
||||
wxTextCtrl* m_textCtrlTransactionFee; |
||||
wxButton* m_buttonOK; |
||||
wxButton* m_buttonCancel; |
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void OnKillFocusTransactionFee(wxFocusEvent& event){ event.Skip(); } |
||||
virtual void OnButtonOK(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); } |
||||
|
||||
|
||||
public: |
||||
COptionsDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Options"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(500,261), long style = wxDEFAULT_DIALOG_STYLE); |
||||
~COptionsDialogBase(); |
||||
|
||||
}; |
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class CAboutDialogBase
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class CAboutDialogBase : public wxDialog |
||||
{ |
||||
private: |
||||
|
||||
protected: |
||||
|
||||
|
||||
wxStaticText* m_staticText40; |
||||
|
||||
wxStaticText* m_staticTextMain; |
||||
|
||||
|
||||
wxButton* m_buttonOK; |
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void OnButtonOK(wxCommandEvent& event){ event.Skip(); } |
||||
|
||||
|
||||
public: |
||||
wxStaticText* m_staticTextVersion; |
||||
CAboutDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("About Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(507,298), long style = wxDEFAULT_DIALOG_STYLE); |
||||
~CAboutDialogBase(); |
||||
|
||||
}; |
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class CSendDialogBase
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class CSendDialogBase : public wxDialog |
||||
{ |
||||
private: |
||||
|
||||
protected: |
||||
|
||||
|
||||
wxStaticText* m_staticText14; |
||||
|
||||
wxStaticBitmap* m_bitmapCheckMark; |
||||
wxStaticText* m_staticText36; |
||||
wxTextCtrl* m_textCtrlAddress; |
||||
wxButton* m_buttonPaste; |
||||
wxButton* m_buttonAddress; |
||||
wxStaticText* m_staticText19; |
||||
wxTextCtrl* m_textCtrlAmount; |
||||
wxStaticText* m_staticText20; |
||||
wxChoice* m_choiceTransferType; |
||||
|
||||
|
||||
wxStaticText* m_staticTextFrom; |
||||
wxTextCtrl* m_textCtrlFrom; |
||||
wxStaticText* m_staticTextMessage; |
||||
wxTextCtrl* m_textCtrlMessage; |
||||
|
||||
wxButton* m_buttonSend; |
||||
wxButton* m_buttonCancel; |
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void OnKeyDown(wxKeyEvent& event){ event.Skip(); } |
||||
virtual void OnTextAddress(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonPaste(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonAddressBook(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnKillFocusAmount(wxFocusEvent& event){ event.Skip(); } |
||||
virtual void OnButtonSend(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); } |
||||
|
||||
|
||||
public: |
||||
CSendDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Send Coins"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(675,312), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER); |
||||
~CSendDialogBase(); |
||||
|
||||
}; |
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class CSendingDialogBase
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class CSendingDialogBase : public wxDialog |
||||
{ |
||||
private: |
||||
|
||||
protected: |
||||
wxStaticText* m_staticTextSending; |
||||
wxTextCtrl* m_textCtrlStatus; |
||||
|
||||
wxButton* m_buttonOK; |
||||
wxButton* m_buttonCancel; |
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void OnClose(wxCloseEvent& event){ event.Skip(); } |
||||
virtual void OnPaint(wxPaintEvent& event){ event.Skip(); } |
||||
virtual void OnButtonOK(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); } |
||||
|
||||
|
||||
public: |
||||
CSendingDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Sending..."), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(442,151), long style = wxDEFAULT_DIALOG_STYLE); |
||||
~CSendingDialogBase(); |
||||
|
||||
}; |
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class CYourAddressDialogBase
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class CYourAddressDialogBase : public wxDialog |
||||
{ |
||||
private: |
||||
|
||||
protected: |
||||
|
||||
wxStaticText* m_staticText45; |
||||
wxListCtrl* m_listCtrl; |
||||
|
||||
wxButton* m_buttonRename; |
||||
wxButton* m_buttonNew; |
||||
wxButton* m_buttonCopy; |
||||
wxButton* m_buttonOK; |
||||
wxButton* m_buttonCancel; |
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void OnClose(wxCloseEvent& event){ event.Skip(); } |
||||
virtual void OnListEndLabelEdit(wxListEvent& event){ event.Skip(); } |
||||
virtual void OnListItemActivated(wxListEvent& event){ event.Skip(); } |
||||
virtual void OnListItemSelected(wxListEvent& event){ event.Skip(); } |
||||
virtual void OnButtonRename(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonNew(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonCopy(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonOK(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); } |
||||
|
||||
|
||||
public: |
||||
CYourAddressDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Your Bitcoin Addresses"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(610,390), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER); |
||||
~CYourAddressDialogBase(); |
||||
|
||||
}; |
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class CAddressBookDialogBase
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class CAddressBookDialogBase : public wxDialog |
||||
{ |
||||
private: |
||||
|
||||
protected: |
||||
|
||||
wxStaticText* m_staticText55; |
||||
wxListCtrl* m_listCtrl; |
||||
|
||||
wxButton* m_buttonEdit; |
||||
wxButton* m_buttonNew; |
||||
wxButton* m_buttonDelete; |
||||
wxButton* m_buttonOK; |
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void OnClose(wxCloseEvent& event){ event.Skip(); } |
||||
virtual void OnListEndLabelEdit(wxListEvent& event){ event.Skip(); } |
||||
virtual void OnListItemActivated(wxListEvent& event){ event.Skip(); } |
||||
virtual void OnListItemSelected(wxListEvent& event){ event.Skip(); } |
||||
virtual void OnButtonEdit(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonNew(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonDelete(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonOK(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); } |
||||
|
||||
|
||||
public: |
||||
wxButton* m_buttonCancel; |
||||
CAddressBookDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Address Book"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(610,390), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER); |
||||
~CAddressBookDialogBase(); |
||||
|
||||
}; |
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class CProductsDialogBase
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class CProductsDialogBase : public wxDialog |
||||
{ |
||||
private: |
||||
|
||||
protected: |
||||
wxComboBox* m_comboBoxCategory; |
||||
wxTextCtrl* m_textCtrlSearch; |
||||
wxButton* m_buttonSearch; |
||||
wxListCtrl* m_listCtrl; |
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void OnCombobox(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnKeyDown(wxKeyEvent& event){ event.Skip(); } |
||||
virtual void OnButtonSearch(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnListItemActivated(wxListEvent& event){ event.Skip(); } |
||||
|
||||
|
||||
public: |
||||
CProductsDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Marketplace"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(708,535), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER); |
||||
~CProductsDialogBase(); |
||||
|
||||
}; |
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class CEditProductDialogBase
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class CEditProductDialogBase : public wxFrame |
||||
{ |
||||
private: |
||||
|
||||
protected: |
||||
wxScrolledWindow* m_scrolledWindow; |
||||
wxStaticText* m_staticText106; |
||||
wxComboBox* m_comboBoxCategory; |
||||
wxStaticText* m_staticText108; |
||||
wxTextCtrl* m_textCtrlTitle; |
||||
wxStaticText* m_staticText107; |
||||
wxTextCtrl* m_textCtrlPrice; |
||||
wxStaticText* m_staticText22; |
||||
wxTextCtrl* m_textCtrlDescription; |
||||
wxStaticText* m_staticText23; |
||||
wxTextCtrl* m_textCtrlInstructions; |
||||
wxStaticText* m_staticText24; |
||||
wxStaticText* m_staticText25; |
||||
|
||||
wxTextCtrl* m_textCtrlLabel0; |
||||
wxTextCtrl* m_textCtrlField0; |
||||
wxButton* m_buttonDel0; |
||||
wxTextCtrl* m_textCtrlLabel1; |
||||
wxTextCtrl* m_textCtrlField1; |
||||
wxButton* m_buttonDel1; |
||||
wxTextCtrl* m_textCtrlLabel2; |
||||
wxTextCtrl* m_textCtrlField2; |
||||
wxButton* m_buttonDel2; |
||||
wxTextCtrl* m_textCtrlLabel3; |
||||
wxTextCtrl* m_textCtrlField3; |
||||
wxButton* m_buttonDel3; |
||||
wxTextCtrl* m_textCtrlLabel4; |
||||
wxTextCtrl* m_textCtrlField4; |
||||
wxButton* m_buttonDel4; |
||||
wxTextCtrl* m_textCtrlLabel5; |
||||
wxTextCtrl* m_textCtrlField5; |
||||
wxButton* m_buttonDel5; |
||||
wxTextCtrl* m_textCtrlLabel6; |
||||
wxTextCtrl* m_textCtrlField6; |
||||
wxButton* m_buttonDel6; |
||||
wxTextCtrl* m_textCtrlLabel7; |
||||
wxTextCtrl* m_textCtrlField7; |
||||
wxButton* m_buttonDel7; |
||||
wxTextCtrl* m_textCtrlLabel8; |
||||
wxTextCtrl* m_textCtrlField8; |
||||
wxButton* m_buttonDel8; |
||||
wxTextCtrl* m_textCtrlLabel9; |
||||
wxTextCtrl* m_textCtrlField9; |
||||
wxButton* m_buttonDel9; |
||||
wxTextCtrl* m_textCtrlLabel10; |
||||
wxTextCtrl* m_textCtrlField10; |
||||
wxButton* m_buttonDel10; |
||||
wxTextCtrl* m_textCtrlLabel11; |
||||
wxTextCtrl* m_textCtrlField11; |
||||
wxButton* m_buttonDel11; |
||||
wxTextCtrl* m_textCtrlLabel12; |
||||
wxTextCtrl* m_textCtrlField12; |
||||
wxButton* m_buttonDel12; |
||||
wxTextCtrl* m_textCtrlLabel13; |
||||
wxTextCtrl* m_textCtrlField13; |
||||
wxButton* m_buttonDel13; |
||||
wxTextCtrl* m_textCtrlLabel14; |
||||
wxTextCtrl* m_textCtrlField14; |
||||
wxButton* m_buttonDel14; |
||||
wxTextCtrl* m_textCtrlLabel15; |
||||
wxTextCtrl* m_textCtrlField15; |
||||
wxButton* m_buttonDel15; |
||||
wxTextCtrl* m_textCtrlLabel16; |
||||
wxTextCtrl* m_textCtrlField16; |
||||
wxButton* m_buttonDel16; |
||||
wxTextCtrl* m_textCtrlLabel17; |
||||
wxTextCtrl* m_textCtrlField17; |
||||
wxButton* m_buttonDel17; |
||||
wxTextCtrl* m_textCtrlLabel18; |
||||
wxTextCtrl* m_textCtrlField18; |
||||
wxButton* m_buttonDel18; |
||||
wxTextCtrl* m_textCtrlLabel19; |
||||
wxTextCtrl* m_textCtrlField19; |
||||
wxButton* m_buttonDel19; |
||||
wxButton* m_buttonAddField; |
||||
wxButton* m_buttonOK; |
||||
wxButton* m_buttonPreview; |
||||
wxButton* m_buttonCancel; |
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void OnKeyDown(wxKeyEvent& event){ event.Skip(); } |
||||
virtual void OnButtonDel0(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonDel1(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonDel2(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonDel3(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonDel4(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonDel5(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonDel6(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonDel7(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonDel8(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonDel9(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonDel10(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonDel11(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonDel12(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonDel13(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonDel14(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonDel15(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonDel16(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonDel17(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonDel18(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonDel19(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonAddField(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonSend(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonPreview(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); } |
||||
|
||||
|
||||
public: |
||||
wxFlexGridSizer* fgSizer5; |
||||
CEditProductDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Edit Product"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(660,640), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL); |
||||
~CEditProductDialogBase(); |
||||
|
||||
}; |
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class CViewProductDialogBase
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class CViewProductDialogBase : public wxFrame |
||||
{ |
||||
private: |
||||
|
||||
protected: |
||||
wxHtmlWindow* m_htmlWinReviews; |
||||
wxScrolledWindow* m_scrolledWindow; |
||||
wxRichTextCtrl* m_richTextHeading; |
||||
wxStaticText* m_staticTextInstructions; |
||||
wxButton* m_buttonSubmitForm; |
||||
wxButton* m_buttonCancelForm; |
||||
wxButton* m_buttonBack; |
||||
wxButton* m_buttonNext; |
||||
wxButton* m_buttonCancel; |
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void OnButtonSubmitForm(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonCancelForm(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonBack(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonNext(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); } |
||||
|
||||
|
||||
public: |
||||
CViewProductDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Order Form"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(630,520), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL); |
||||
~CViewProductDialogBase(); |
||||
|
||||
}; |
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class CViewOrderDialogBase
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class CViewOrderDialogBase : public wxFrame |
||||
{ |
||||
private: |
||||
|
||||
protected: |
||||
wxHtmlWindow* m_htmlWin; |
||||
wxButton* m_buttonOK; |
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void OnButtonOK(wxCommandEvent& event){ event.Skip(); } |
||||
|
||||
|
||||
public: |
||||
CViewOrderDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("View Order"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(630,520), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL); |
||||
~CViewOrderDialogBase(); |
||||
|
||||
}; |
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class CEditReviewDialogBase
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class CEditReviewDialogBase : public wxFrame |
||||
{ |
||||
private: |
||||
|
||||
protected: |
||||
|
||||
wxStaticText* m_staticTextSeller; |
||||
|
||||
wxStaticText* m_staticText110; |
||||
wxChoice* m_choiceStars; |
||||
wxStaticText* m_staticText43; |
||||
wxTextCtrl* m_textCtrlReview; |
||||
wxButton* m_buttonSubmit; |
||||
wxButton* m_buttonCancel; |
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void OnKeyDown(wxKeyEvent& event){ event.Skip(); } |
||||
virtual void OnButtonSubmit(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); } |
||||
|
||||
|
||||
public: |
||||
CEditReviewDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Enter Review"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(630,440), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL); |
||||
~CEditReviewDialogBase(); |
||||
|
||||
}; |
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class CPokerLobbyDialogBase
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class CPokerLobbyDialogBase : public wxFrame |
||||
{ |
||||
private: |
||||
|
||||
protected: |
||||
wxTreeCtrl* m_treeCtrl; |
||||
wxListCtrl* m_listCtrl; |
||||
wxButton* m_buttonNewTable; |
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void OnTreeSelChanged(wxTreeEvent& event){ event.Skip(); } |
||||
virtual void OnListItemActivated(wxListEvent& event){ event.Skip(); } |
||||
virtual void OnListItemSelected(wxListEvent& event){ event.Skip(); } |
||||
virtual void OnButtonNewTable(wxCommandEvent& event){ event.Skip(); } |
||||
|
||||
|
||||
public: |
||||
CPokerLobbyDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Poker Lobby"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(586,457), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL); |
||||
~CPokerLobbyDialogBase(); |
||||
|
||||
}; |
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class CPokerDialogBase
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class CPokerDialogBase : public wxFrame |
||||
{ |
||||
private: |
||||
|
||||
protected: |
||||
wxButton* m_buttonDealHand; |
||||
wxButton* m_buttonFold; |
||||
wxButton* m_buttonCall; |
||||
wxButton* m_buttonRaise; |
||||
wxButton* m_buttonLeaveTable; |
||||
wxTextCtrl* m_textDitchPlayer; |
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void OnClose(wxCloseEvent& event){ event.Skip(); } |
||||
virtual void OnMouseEvents(wxMouseEvent& event){ event.Skip(); } |
||||
virtual void OnPaint(wxPaintEvent& event){ event.Skip(); } |
||||
virtual void OnSize(wxSizeEvent& event){ event.Skip(); } |
||||
virtual void OnCheckSitOut(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonDealHand(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonFold(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonCall(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonRaise(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonLeaveTable(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnDitchPlayer(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnCheckPreFold(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnCheckPreCall(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnCheckPreCallAny(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnCheckPreRaise(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnCheckPreRaiseAny(wxCommandEvent& event){ event.Skip(); } |
||||
|
||||
|
||||
public: |
||||
wxCheckBox* m_checkSitOut; |
||||
wxCheckBox* m_checkPreFold; |
||||
wxCheckBox* m_checkPreCall; |
||||
wxCheckBox* m_checkPreCallAny; |
||||
wxCheckBox* m_checkPreRaise; |
||||
wxCheckBox* m_checkPreRaiseAny; |
||||
wxStatusBar* m_statusBar; |
||||
CPokerDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Poker"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(806,550), long style = wxDEFAULT_FRAME_STYLE|wxFRAME_NO_TASKBAR|wxFULL_REPAINT_ON_RESIZE|wxTAB_TRAVERSAL); |
||||
~CPokerDialogBase(); |
||||
|
||||
}; |
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class CGetTextFromUserDialogBase
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class CGetTextFromUserDialogBase : public wxDialog |
||||
{ |
||||
private: |
||||
|
||||
protected: |
||||
|
||||
wxStaticText* m_staticTextMessage1; |
||||
wxTextCtrl* m_textCtrl1; |
||||
wxStaticText* m_staticTextMessage2; |
||||
wxTextCtrl* m_textCtrl2; |
||||
|
||||
|
||||
wxButton* m_buttonOK; |
||||
wxButton* m_buttonCancel; |
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void OnClose(wxCloseEvent& event){ event.Skip(); } |
||||
virtual void OnKeyDown(wxKeyEvent& event){ event.Skip(); } |
||||
virtual void OnButtonOK(wxCommandEvent& event){ event.Skip(); } |
||||
virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); } |
||||
|
||||
|
||||
public: |
||||
CGetTextFromUserDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(403,138), long style = wxDEFAULT_DIALOG_STYLE); |
||||
~CGetTextFromUserDialogBase(); |
||||
|
||||
}; |
||||
|
||||
#endif //__uibase__
|
@ -0,0 +1,750 @@
@@ -0,0 +1,750 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <limits.h> |
||||
#include <string> |
||||
#if defined(_MSC_VER) || defined(__BORLANDC__) |
||||
typedef __int64 int64; |
||||
typedef unsigned __int64 uint64; |
||||
#else |
||||
typedef long long int64; |
||||
typedef unsigned long long uint64; |
||||
#endif |
||||
#if defined(_MSC_VER) && _MSC_VER < 1300 |
||||
#define for if (false) ; else for |
||||
#endif |
||||
|
||||
|
||||
inline int Testuint256AdHoc(vector<string> vArg); |
||||
|
||||
|
||||
|
||||
// We have to keep a separate base class without constructors
|
||||
// so the compiler will let us use it in a union
|
||||
template<unsigned int BITS> |
||||
class base_uint |
||||
{ |
||||
protected: |
||||
enum { WIDTH=BITS/32 }; |
||||
unsigned int pn[WIDTH]; |
||||
public: |
||||
|
||||
bool operator!() const |
||||
{ |
||||
for (int i = 0; i < WIDTH; i++) |
||||
if (pn[i] != 0) |
||||
return false; |
||||
return true; |
||||
} |
||||
|
||||
const base_uint operator~() const |
||||
{ |
||||
base_uint ret; |
||||
for (int i = 0; i < WIDTH; i++) |
||||
ret.pn[i] = ~pn[i]; |
||||
return ret; |
||||
} |
||||
|
||||
const base_uint operator-() const |
||||
{ |
||||
base_uint ret; |
||||
for (int i = 0; i < WIDTH; i++) |
||||
ret.pn[i] = ~pn[i]; |
||||
ret++; |
||||
return ret; |
||||
} |
||||
|
||||
|
||||
base_uint& operator=(uint64 b) |
||||
{ |
||||
pn[0] = (unsigned int)b; |
||||
pn[1] = (unsigned int)(b >> 32); |
||||
for (int i = 2; i < WIDTH; i++) |
||||
pn[i] = 0; |
||||
return *this; |
||||
} |
||||
|
||||
base_uint& operator^=(const base_uint& b) |
||||
{ |
||||
for (int i = 0; i < WIDTH; i++) |
||||
pn[i] ^= b.pn[i]; |
||||
return *this; |
||||
} |
||||
|
||||
base_uint& operator&=(const base_uint& b) |
||||
{ |
||||
for (int i = 0; i < WIDTH; i++) |
||||
pn[i] &= b.pn[i]; |
||||
return *this; |
||||
} |
||||
|
||||
base_uint& operator|=(const base_uint& b) |
||||
{ |
||||
for (int i = 0; i < WIDTH; i++) |
||||
pn[i] |= b.pn[i]; |
||||
return *this; |
||||
} |
||||
|
||||
base_uint& operator^=(uint64 b) |
||||
{ |
||||
pn[0] ^= (unsigned int)b; |
||||
pn[1] ^= (unsigned int)(b >> 32); |
||||
return *this; |
||||
} |
||||
|
||||
base_uint& operator&=(uint64 b) |
||||
{ |
||||
pn[0] &= (unsigned int)b; |
||||
pn[1] &= (unsigned int)(b >> 32); |
||||
return *this; |
||||
} |
||||
|
||||
base_uint& operator|=(uint64 b) |
||||
{ |
||||
pn[0] |= (unsigned int)b; |
||||
pn[1] |= (unsigned int)(b >> 32); |
||||
return *this; |
||||
} |
||||
|
||||
base_uint& operator<<=(unsigned int shift) |
||||
{ |
||||
base_uint a(*this); |
||||
for (int i = 0; i < WIDTH; i++) |
||||
pn[i] = 0; |
||||
int k = shift / 32; |
||||
shift = shift % 32; |
||||
for (int i = 0; i < WIDTH; i++) |
||||
{ |
||||
if (i+k+1 < WIDTH && shift != 0) |
||||
pn[i+k+1] |= (a.pn[i] >> (32-shift)); |
||||
if (i+k < WIDTH) |
||||
pn[i+k] |= (a.pn[i] << shift); |
||||
} |
||||
return *this; |
||||
} |
||||
|
||||
base_uint& operator>>=(unsigned int shift) |
||||
{ |
||||
base_uint a(*this); |
||||
for (int i = 0; i < WIDTH; i++) |
||||
pn[i] = 0; |
||||
int k = shift / 32; |
||||
shift = shift % 32; |
||||
for (int i = 0; i < WIDTH; i++) |
||||
{ |
||||
if (i-k-1 >= 0 && shift != 0) |
||||
pn[i-k-1] |= (a.pn[i] << (32-shift)); |
||||
if (i-k >= 0) |
||||
pn[i-k] |= (a.pn[i] >> shift); |
||||
} |
||||
return *this; |
||||
} |
||||
|
||||
base_uint& operator+=(const base_uint& b) |
||||
{ |
||||
uint64 carry = 0; |
||||
for (int i = 0; i < WIDTH; i++) |
||||
{ |
||||
uint64 n = carry + pn[i] + b.pn[i]; |
||||
pn[i] = n & 0xffffffff; |
||||
carry = n >> 32; |
||||
} |
||||
return *this; |
||||
} |
||||
|
||||
base_uint& operator-=(const base_uint& b) |
||||
{ |
||||
*this += -b; |
||||
return *this; |
||||
} |
||||
|
||||
base_uint& operator+=(uint64 b64) |
||||
{ |
||||
base_uint b; |
||||
b = b64; |
||||
*this += b; |
||||
return *this; |
||||
} |
||||
|
||||
base_uint& operator-=(uint64 b64) |
||||
{ |
||||
base_uint b; |
||||
b = b64; |
||||
*this += -b; |
||||
return *this; |
||||
} |
||||
|
||||
|
||||
base_uint& operator++() |
||||
{ |
||||
// prefix operator
|
||||
int i = 0; |
||||
while (++pn[i] == 0 && i < WIDTH-1) |
||||
i++; |
||||
return *this; |
||||
} |
||||
|
||||
const base_uint operator++(int) |
||||
{ |
||||
// postfix operator
|
||||
const base_uint ret = *this; |
||||
++(*this); |
||||
return ret; |
||||
} |
||||
|
||||
base_uint& operator--() |
||||
{ |
||||
// prefix operator
|
||||
int i = 0; |
||||
while (--pn[i] == -1 && i < WIDTH-1) |
||||
i++; |
||||
return *this; |
||||
} |
||||
|
||||
const base_uint operator--(int) |
||||
{ |
||||
// postfix operator
|
||||
const base_uint ret = *this; |
||||
--(*this); |
||||
return ret; |
||||
} |
||||
|
||||
|
||||
friend inline bool operator<(const base_uint& a, const base_uint& b) |
||||
{ |
||||
for (int i = base_uint::WIDTH-1; i >= 0; i--) |
||||
{ |
||||
if (a.pn[i] < b.pn[i]) |
||||
return true; |
||||
else if (a.pn[i] > b.pn[i]) |
||||
return false; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
friend inline bool operator<=(const base_uint& a, const base_uint& b) |
||||
{ |
||||
for (int i = base_uint::WIDTH-1; i >= 0; i--) |
||||
{ |
||||
if (a.pn[i] < b.pn[i]) |
||||
return true; |
||||
else if (a.pn[i] > b.pn[i]) |
||||
return false; |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
friend inline bool operator>(const base_uint& a, const base_uint& b) |
||||
{ |
||||
for (int i = base_uint::WIDTH-1; i >= 0; i--) |
||||
{ |
||||
if (a.pn[i] > b.pn[i]) |
||||
return true; |
||||
else if (a.pn[i] < b.pn[i]) |
||||
return false; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
friend inline bool operator>=(const base_uint& a, const base_uint& b) |
||||
{ |
||||
for (int i = base_uint::WIDTH-1; i >= 0; i--) |
||||
{ |
||||
if (a.pn[i] > b.pn[i]) |
||||
return true; |
||||
else if (a.pn[i] < b.pn[i]) |
||||
return false; |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
friend inline bool operator==(const base_uint& a, const base_uint& b) |
||||
{ |
||||
for (int i = 0; i < base_uint::WIDTH; i++) |
||||
if (a.pn[i] != b.pn[i]) |
||||
return false; |
||||
return true; |
||||
} |
||||
|
||||
friend inline bool operator==(const base_uint& a, uint64 b) |
||||
{ |
||||
if (a.pn[0] != (unsigned int)b) |
||||
return false; |
||||
if (a.pn[1] != (unsigned int)(b >> 32)) |
||||
return false; |
||||
for (int i = 2; i < base_uint::WIDTH; i++) |
||||
if (a.pn[i] != 0) |
||||
return false; |
||||
return true; |
||||
} |
||||
|
||||
friend inline bool operator!=(const base_uint& a, const base_uint& b) |
||||
{ |
||||
return (!(a == b)); |
||||
} |
||||
|
||||
friend inline bool operator!=(const base_uint& a, uint64 b) |
||||
{ |
||||
return (!(a == b)); |
||||
} |
||||
|
||||
|
||||
|
||||
std::string GetHex() const |
||||
{ |
||||
char psz[sizeof(pn)*2 + 1]; |
||||
for (int i = 0; i < sizeof(pn); i++) |
||||
sprintf(psz + i*2, "%02x", ((unsigned char*)pn)[sizeof(pn) - i - 1]); |
||||
return string(psz, psz + sizeof(pn)*2); |
||||
} |
||||
|
||||
void SetHex(const std::string& str) |
||||
{ |
||||
for (int i = 0; i < WIDTH; i++) |
||||
pn[i] = 0; |
||||
|
||||
// skip 0x
|
||||
const char* psz = str.c_str(); |
||||
while (isspace(*psz)) |
||||
psz++; |
||||
if (psz[0] == '0' && tolower(psz[1]) == 'x') |
||||
psz += 2; |
||||
while (isspace(*psz)) |
||||
psz++; |
||||
|
||||
// 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++; |
||||
} |
||||
} |
||||
} |
||||
|
||||
std::string ToString() const |
||||
{ |
||||
return (GetHex()); |
||||
} |
||||
|
||||
unsigned char* begin() |
||||
{ |
||||
return (unsigned char*)&pn[0]; |
||||
} |
||||
|
||||
unsigned char* end() |
||||
{ |
||||
return (unsigned char*)&pn[WIDTH]; |
||||
} |
||||
|
||||
unsigned int size() |
||||
{ |
||||
return sizeof(pn); |
||||
} |
||||
|
||||
|
||||
unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const |
||||
{ |
||||
return sizeof(pn); |
||||
} |
||||
|
||||
template<typename Stream> |
||||
void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const |
||||
{ |
||||
s.write((char*)pn, sizeof(pn)); |
||||
} |
||||
|
||||
template<typename Stream> |
||||
void Unserialize(Stream& s, int nType=0, int nVersion=VERSION) |
||||
{ |
||||
s.read((char*)pn, sizeof(pn)); |
||||
} |
||||
|
||||
|
||||
friend class uint160; |
||||
friend class uint256; |
||||
friend inline int Testuint256AdHoc(vector<string> vArg); |
||||
}; |
||||
|
||||
typedef base_uint<160> base_uint160; |
||||
typedef base_uint<256> base_uint256; |
||||
|
||||
|
||||
|
||||
//
|
||||
// uint160 and uint256 could be implemented as templates, but to keep
|
||||
// compile errors and debugging cleaner, they're copy and pasted.
|
||||
// It's safe to search and replace 160 with 256 and vice versa.
|
||||
//
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// uint160
|
||||
//
|
||||
|
||||
class uint160 : public base_uint160 |
||||
{ |
||||
public: |
||||
typedef base_uint160 basetype; |
||||
|
||||
uint160() |
||||
{ |
||||
} |
||||
|
||||
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() |
||||
{ |
||||
} |
||||
|
||||
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); |
||||
} |
@ -0,0 +1,383 @@
@@ -0,0 +1,383 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "headers.h" |
||||
|
||||
|
||||
|
||||
bool fDebug = false; |
||||
|
||||
|
||||
|
||||
|
||||
// Init openssl library multithreading support
|
||||
static HANDLE* lock_cs; |
||||
|
||||
void win32_locking_callback(int mode, int type, const char* file, int line) |
||||
{ |
||||
if (mode & CRYPTO_LOCK) |
||||
WaitForSingleObject(lock_cs[type], INFINITE); |
||||
else |
||||
ReleaseMutex(lock_cs[type]); |
||||
} |
||||
|
||||
// Init
|
||||
class CInit |
||||
{ |
||||
public: |
||||
CInit() |
||||
{ |
||||
// Init openssl library multithreading support
|
||||
lock_cs = (HANDLE*)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(HANDLE)); |
||||
for (int i = 0; i < CRYPTO_num_locks(); i++) |
||||
lock_cs[i] = CreateMutex(NULL,FALSE,NULL); |
||||
CRYPTO_set_locking_callback(win32_locking_callback); |
||||
|
||||
// Seed random number generator with screen scrape and other hardware sources
|
||||
RAND_screen(); |
||||
|
||||
// Seed random number generator with perfmon data
|
||||
RandAddSeed(true); |
||||
} |
||||
~CInit() |
||||
{ |
||||
// Shutdown openssl library multithreading support
|
||||
CRYPTO_set_locking_callback(NULL); |
||||
for (int i =0 ; i < CRYPTO_num_locks(); i++) |
||||
CloseHandle(lock_cs[i]); |
||||
OPENSSL_free(lock_cs); |
||||
} |
||||
} |
||||
instance_of_cinit; |
||||
|
||||
|
||||
|
||||
|
||||
void RandAddSeed(bool fPerfmon) |
||||
{ |
||||
// Seed with CPU performance counter
|
||||
LARGE_INTEGER PerformanceCount; |
||||
QueryPerformanceCounter(&PerformanceCount); |
||||
RAND_add(&PerformanceCount, sizeof(PerformanceCount), 1.5); |
||||
memset(&PerformanceCount, 0, sizeof(PerformanceCount)); |
||||
|
||||
static int64 nLastPerfmon; |
||||
if (fPerfmon || GetTime() > nLastPerfmon + 5 * 60) |
||||
{ |
||||
nLastPerfmon = GetTime(); |
||||
|
||||
// Seed with the entire set of perfmon data
|
||||
unsigned char pdata[250000]; |
||||
memset(pdata, 0, sizeof(pdata)); |
||||
unsigned long nSize = sizeof(pdata); |
||||
long ret = RegQueryValueEx(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize); |
||||
RegCloseKey(HKEY_PERFORMANCE_DATA); |
||||
if (ret == ERROR_SUCCESS) |
||||
{ |
||||
uint256 hash; |
||||
SHA256(pdata, nSize, (unsigned char*)&hash); |
||||
RAND_add(&hash, sizeof(hash), min(nSize/500.0, (double)sizeof(hash))); |
||||
hash = 0; |
||||
memset(pdata, 0, nSize); |
||||
|
||||
time_t nTime; |
||||
time(&nTime); |
||||
struct tm* ptmTime = gmtime(&nTime); |
||||
char pszTime[200]; |
||||
strftime(pszTime, sizeof(pszTime), "%x %H:%M:%S", ptmTime); |
||||
printf("%s RandAddSeed() got %d bytes of performance data\n", pszTime, nSize); |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Safer snprintf
|
||||
// - prints up to limit-1 characters
|
||||
// - output string is always null terminated even if limit reached
|
||||
// - return value is the number of characters actually printed
|
||||
int my_snprintf(char* buffer, size_t limit, const char* format, ...) |
||||
{ |
||||
if (limit == 0) |
||||
return 0; |
||||
va_list arg_ptr; |
||||
va_start(arg_ptr, format); |
||||
int ret = _vsnprintf(buffer, limit, format, arg_ptr); |
||||
va_end(arg_ptr); |
||||
if (ret < 0 || ret >= limit) |
||||
{ |
||||
ret = limit - 1; |
||||
buffer[limit-1] = 0; |
||||
} |
||||
return ret; |
||||
} |
||||
|
||||
|
||||
string strprintf(const char* format, ...) |
||||
{ |
||||
char buffer[50000]; |
||||
char* p = buffer; |
||||
int limit = sizeof(buffer); |
||||
int ret; |
||||
loop |
||||
{ |
||||
va_list arg_ptr; |
||||
va_start(arg_ptr, format); |
||||
ret = _vsnprintf(p, limit, format, arg_ptr); |
||||
va_end(arg_ptr); |
||||
if (ret >= 0 && ret < limit) |
||||
break; |
||||
if (p != buffer) |
||||
delete p; |
||||
limit *= 2; |
||||
p = new char[limit]; |
||||
if (p == NULL) |
||||
throw std::bad_alloc(); |
||||
} |
||||
#ifdef _MSC_VER |
||||
// msvc optimisation
|
||||
if (p == buffer) |
||||
return string(p, p+ret); |
||||
#endif |
||||
string str(p, p+ret); |
||||
if (p != buffer) |
||||
delete p; |
||||
return str; |
||||
} |
||||
|
||||
|
||||
bool error(const char* format, ...) |
||||
{ |
||||
char buffer[50000]; |
||||
int limit = sizeof(buffer); |
||||
va_list arg_ptr; |
||||
va_start(arg_ptr, format); |
||||
int ret = _vsnprintf(buffer, limit, format, arg_ptr); |
||||
va_end(arg_ptr); |
||||
if (ret < 0 || ret >= limit) |
||||
{ |
||||
ret = limit - 1; |
||||
buffer[limit-1] = 0; |
||||
} |
||||
printf("ERROR: %s\n", buffer); |
||||
return false; |
||||
} |
||||
|
||||
|
||||
void PrintException(std::exception* pex, const char* pszThread) |
||||
{ |
||||
char pszModule[260]; |
||||
pszModule[0] = '\0'; |
||||
GetModuleFileName(NULL, pszModule, sizeof(pszModule)); |
||||
_strlwr(pszModule); |
||||
char pszMessage[1000]; |
||||
if (pex) |
||||
snprintf(pszMessage, sizeof(pszMessage), |
||||
"EXCEPTION: %s \n%s \n%s in %s \n", typeid(*pex).name(), pex->what(), pszModule, pszThread); |
||||
else |
||||
snprintf(pszMessage, sizeof(pszMessage), |
||||
"UNKNOWN EXCEPTION \n%s in %s \n", pszModule, pszThread); |
||||
printf("\n\n************************\n%s", pszMessage); |
||||
if (wxTheApp) |
||||
wxMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR); |
||||
throw; |
||||
//DebugBreak();
|
||||
} |
||||
|
||||
|
||||
void ParseString(const string& str, char c, vector<string>& v) |
||||
{ |
||||
unsigned int i1 = 0; |
||||
unsigned int i2; |
||||
do |
||||
{ |
||||
i2 = str.find(c, i1); |
||||
v.push_back(str.substr(i1, i2-i1)); |
||||
i1 = i2+1; |
||||
} |
||||
while (i2 != str.npos); |
||||
} |
||||
|
||||
|
||||
string FormatMoney(int64 n, bool fPlus) |
||||
{ |
||||
n /= CENT; |
||||
string str = strprintf("%I64d.%02I64d", (n > 0 ? n : -n)/100, (n > 0 ? n : -n)%100); |
||||
for (int i = 6; i < str.size(); i += 4) |
||||
if (isdigit(str[str.size() - i - 1])) |
||||
str.insert(str.size() - i, 1, ','); |
||||
if (n < 0) |
||||
str.insert((unsigned int)0, 1, '-'); |
||||
else if (fPlus && n > 0) |
||||
str.insert((unsigned int)0, 1, '+'); |
||||
return str; |
||||
} |
||||
|
||||
bool ParseMoney(const char* pszIn, int64& nRet) |
||||
{ |
||||
string strWhole; |
||||
int64 nCents = 0; |
||||
const char* p = pszIn; |
||||
while (isspace(*p)) |
||||
p++; |
||||
for (; *p; p++) |
||||
{ |
||||
if (*p == ',' && p > pszIn && isdigit(p[-1]) && isdigit(p[1]) && isdigit(p[2]) && isdigit(p[3]) && !isdigit(p[4])) |
||||
continue; |
||||
if (*p == '.') |
||||
{ |
||||
p++; |
||||
if (isdigit(*p)) |
||||
{ |
||||
nCents = 10 * (*p++ - '0'); |
||||
if (isdigit(*p)) |
||||
nCents += (*p++ - '0'); |
||||
} |
||||
break; |
||||
} |
||||
if (isspace(*p)) |
||||
break; |
||||
if (!isdigit(*p)) |
||||
return false; |
||||
strWhole.insert(strWhole.end(), *p); |
||||
} |
||||
for (; *p; p++) |
||||
if (!isspace(*p)) |
||||
return false; |
||||
if (strWhole.size() > 14) |
||||
return false; |
||||
if (nCents < 0 || nCents > 99) |
||||
return false; |
||||
int64 nWhole = atoi64(strWhole); |
||||
int64 nPreValue = nWhole * 100 + nCents; |
||||
int64 nValue = nPreValue * CENT; |
||||
if (nValue / CENT != nPreValue) |
||||
return false; |
||||
if (nValue / COIN != nWhole) |
||||
return false; |
||||
nRet = nValue; |
||||
return true; |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool FileExists(const char* psz) |
||||
{ |
||||
#ifdef WIN32 |
||||
return GetFileAttributes(psz) != -1; |
||||
#else |
||||
return access(psz, 0) != -1; |
||||
#endif |
||||
} |
||||
|
||||
int GetFilesize(FILE* file) |
||||
{ |
||||
int nSavePos = ftell(file); |
||||
int nFilesize = -1; |
||||
if (fseek(file, 0, SEEK_END) == 0) |
||||
nFilesize = ftell(file); |
||||
fseek(file, nSavePos, SEEK_SET); |
||||
return nFilesize; |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
uint64 GetRand(uint64 nMax) |
||||
{ |
||||
if (nMax == 0) |
||||
return 0; |
||||
|
||||
// The range of the random source must be a multiple of the modulus
|
||||
// to give every possible output value an equal possibility
|
||||
uint64 nRange = (_UI64_MAX / nMax) * nMax; |
||||
uint64 nRand = 0; |
||||
do |
||||
RAND_bytes((unsigned char*)&nRand, sizeof(nRand)); |
||||
while (nRand >= nRange); |
||||
return (nRand % nMax); |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// "Never go to sea with two chronometers; take one or three."
|
||||
// Our three chronometers are:
|
||||
// - System clock
|
||||
// - Median of other server's clocks
|
||||
// - NTP servers
|
||||
//
|
||||
// note: NTP isn't implemented yet, so until then we just use the median
|
||||
// of other nodes clocks to correct ours.
|
||||
//
|
||||
|
||||
int64 GetTime() |
||||
{ |
||||
return time(NULL); |
||||
} |
||||
|
||||
static int64 nTimeOffset = 0; |
||||
|
||||
int64 GetAdjustedTime() |
||||
{ |
||||
return GetTime() + nTimeOffset; |
||||
} |
||||
|
||||
void AddTimeData(unsigned int ip, int64 nTime) |
||||
{ |
||||
int64 nOffsetSample = nTime - GetTime(); |
||||
|
||||
// Ignore duplicates
|
||||
static set<unsigned int> setKnown; |
||||
if (!setKnown.insert(ip).second) |
||||
return; |
||||
|
||||
// Add data
|
||||
static vector<int64> vTimeOffsets; |
||||
if (vTimeOffsets.empty()) |
||||
vTimeOffsets.push_back(0); |
||||
vTimeOffsets.push_back(nOffsetSample); |
||||
printf("Added time data, samples %d, ip %08x, offset %+I64d (%+I64d minutes)\n", vTimeOffsets.size(), ip, vTimeOffsets.back(), vTimeOffsets.back()/60); |
||||
if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1) |
||||
{ |
||||
sort(vTimeOffsets.begin(), vTimeOffsets.end()); |
||||
int64 nMedian = vTimeOffsets[vTimeOffsets.size()/2]; |
||||
nTimeOffset = nMedian; |
||||
if ((nMedian > 0 ? nMedian : -nMedian) > 5 * 60) |
||||
{ |
||||
// Only let other nodes change our clock so far before we
|
||||
// go to the NTP servers
|
||||
/// todo: Get time from NTP servers, then set a flag
|
||||
/// to make sure it doesn't get changed again
|
||||
} |
||||
foreach(int64 n, vTimeOffsets) |
||||
printf("%+I64d ", n); |
||||
printf("| nTimeOffset = %+I64d (%+I64d minutes)\n", nTimeOffset, nTimeOffset/60); |
||||
} |
||||
} |
@ -0,0 +1,399 @@
@@ -0,0 +1,399 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__) |
||||
typedef __int64 int64; |
||||
typedef unsigned __int64 uint64; |
||||
#else |
||||
typedef long long int64; |
||||
typedef unsigned long long uint64; |
||||
#endif |
||||
#if defined(_MSC_VER) && _MSC_VER < 1300 |
||||
#define for if (false) ; else for |
||||
#endif |
||||
|
||||
#ifndef _MSC_VER |
||||
#define __forceinline inline |
||||
#endif |
||||
|
||||
#define foreach BOOST_FOREACH |
||||
#define loop for (;;) |
||||
#define BEGIN(a) ((char*)&(a)) |
||||
#define END(a) ((char*)&((&(a))[1])) |
||||
#define UBEGIN(a) ((unsigned char*)&(a)) |
||||
#define UEND(a) ((unsigned char*)&((&(a))[1])) |
||||
#define ARRAYLEN(array) (sizeof(array)/sizeof((array)[0])) |
||||
|
||||
#ifdef _WINDOWS |
||||
#define printf OutputDebugStringF |
||||
#endif |
||||
|
||||
#ifdef snprintf |
||||
#undef snprintf |
||||
#endif |
||||
#define snprintf my_snprintf |
||||
|
||||
#ifndef PRId64 |
||||
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MSVCRT__) |
||||
#define PRId64 "I64d" |
||||
#define PRIu64 "I64u" |
||||
#define PRIx64 "I64x" |
||||
#else |
||||
#define PRId64 "lld" |
||||
#define PRIu64 "llu" |
||||
#define PRIx64 "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; |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
extern bool fDebug; |
||||
|
||||
void RandAddSeed(bool fPerfmon=false); |
||||
int my_snprintf(char* buffer, size_t limit, const char* format, ...); |
||||
string strprintf(const char* format, ...); |
||||
bool error(const char* format, ...); |
||||
void PrintException(std::exception* pex, const char* pszThread); |
||||
void ParseString(const string& str, char c, vector<string>& v); |
||||
string FormatMoney(int64 n, bool fPlus=false); |
||||
bool ParseMoney(const char* pszIn, int64& nRet); |
||||
bool FileExists(const char* psz); |
||||
int GetFilesize(FILE* file); |
||||
uint64 GetRand(uint64 nMax); |
||||
int64 GetTime(); |
||||
int64 GetAdjustedTime(); |
||||
void AddTimeData(unsigned int ip, int64 nTime); |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Wrapper to automatically initialize critical section
|
||||
// Could use wxCriticalSection for portability, but it doesn't support TryEnterCriticalSection
|
||||
class CCriticalSection |
||||
{ |
||||
protected: |
||||
CRITICAL_SECTION cs; |
||||
public: |
||||
char* pszFile; |
||||
int nLine; |
||||
explicit CCriticalSection() { InitializeCriticalSection(&cs); } |
||||
~CCriticalSection() { DeleteCriticalSection(&cs); } |
||||
void Enter() { EnterCriticalSection(&cs); } |
||||
void Leave() { LeaveCriticalSection(&cs); } |
||||
bool TryEnter() { return TryEnterCriticalSection(&cs); } |
||||
CRITICAL_SECTION* operator&() { return &cs; } |
||||
}; |
||||
|
||||
// Automatically leave critical section when leaving block, needed for exception safety
|
||||
class CCriticalBlock |
||||
{ |
||||
protected: |
||||
CRITICAL_SECTION* pcs; |
||||
public: |
||||
CCriticalBlock(CRITICAL_SECTION& csIn) { pcs = &csIn; EnterCriticalSection(pcs); } |
||||
CCriticalBlock(CCriticalSection& csIn) { pcs = &csIn; EnterCriticalSection(pcs); } |
||||
~CCriticalBlock() { LeaveCriticalSection(pcs); } |
||||
}; |
||||
|
||||
// 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: |
||||
CRITICAL_SECTION* pcs; |
||||
public: |
||||
CTryCriticalBlock(CRITICAL_SECTION& csIn) { pcs = (TryEnterCriticalSection(&csIn) ? &csIn : NULL); } |
||||
CTryCriticalBlock(CCriticalSection& csIn) { pcs = (TryEnterCriticalSection(&csIn) ? &csIn : NULL); } |
||||
~CTryCriticalBlock() { if (pcs) LeaveCriticalSection(pcs); } |
||||
bool Entered() { return pcs != NULL; } |
||||
}; |
||||
|
||||
#define TRY_CRITICAL_BLOCK(cs) \ |
||||
for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by TRY_CRITICAL_BLOCK!", !fcriticalblockonce)), fcriticalblockonce=false) \ |
||||
for (CTryCriticalBlock criticalblock(cs); fcriticalblockonce && (fcriticalblockonce = criticalblock.Entered()) && (cs.pszFile=__FILE__, cs.nLine=__LINE__, true); fcriticalblockonce=false, cs.pszFile=NULL, cs.nLine=0) |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
inline string i64tostr(int64 n) |
||||
{ |
||||
return strprintf("%"PRId64, n); |
||||
} |
||||
|
||||
inline string itostr(int n) |
||||
{ |
||||
return strprintf("%d", n); |
||||
} |
||||
|
||||
inline int64 atoi64(const char* psz) |
||||
{ |
||||
#ifdef _MSC_VER |
||||
return _atoi64(psz); |
||||
#else |
||||
return strtoll(psz, NULL, 10); |
||||
#endif |
||||
} |
||||
|
||||
inline int64 atoi64(const string& str) |
||||
{ |
||||
#ifdef _MSC_VER |
||||
return _atoi64(str.c_str()); |
||||
#else |
||||
return strtoll(str.c_str(), NULL, 10); |
||||
#endif |
||||
} |
||||
|
||||
inline int atoi(const string& str) |
||||
{ |
||||
return atoi(str.c_str()); |
||||
} |
||||
|
||||
inline int roundint(double d) |
||||
{ |
||||
return (int)(d > 0 ? d + 0.5 : d - 0.5); |
||||
} |
||||
|
||||
template<typename T> |
||||
string HexStr(const T itbegin, const T itend, bool fSpaces=true) |
||||
{ |
||||
const unsigned char* pbegin = (const unsigned char*)&itbegin[0]; |
||||
const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]); |
||||
string str; |
||||
for (const unsigned char* p = pbegin; p != pend; p++) |
||||
str += strprintf((fSpaces && p != pend-1 ? "%02x " : "%02x"), *p); |
||||
return str; |
||||
} |
||||
|
||||
template<typename T> |
||||
string HexNumStr(const T itbegin, const T itend, bool f0x=true) |
||||
{ |
||||
const unsigned char* pbegin = (const unsigned char*)&itbegin[0]; |
||||
const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]); |
||||
string str = (f0x ? "0x" : ""); |
||||
for (const unsigned char* p = pend-1; p >= pbegin; p--) |
||||
str += strprintf("%02X", *p); |
||||
return str; |
||||
} |
||||
|
||||
template<typename T> |
||||
void PrintHex(const T pbegin, const T pend, const char* pszFormat="%s", bool fSpaces=true) |
||||
{ |
||||
printf(pszFormat, HexStr(pbegin, pend, fSpaces).c_str()); |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
inline int OutputDebugStringF(const char* pszFormat, ...) |
||||
{ |
||||
#ifdef __WXDEBUG__ |
||||
// log file
|
||||
FILE* fileout = fopen("debug.log", "a"); |
||||
if (fileout) |
||||
{ |
||||
va_list arg_ptr; |
||||
va_start(arg_ptr, pszFormat); |
||||
vfprintf(fileout, pszFormat, arg_ptr); |
||||
va_end(arg_ptr); |
||||
fclose(fileout); |
||||
} |
||||
|
||||
// accumulate a line at a time
|
||||
static CCriticalSection cs_OutputDebugStringF; |
||||
CRITICAL_BLOCK(cs_OutputDebugStringF) |
||||
{ |
||||
static char pszBuffer[50000]; |
||||
static char* pend; |
||||
if (pend == NULL) |
||||
pend = pszBuffer; |
||||
va_list arg_ptr; |
||||
va_start(arg_ptr, pszFormat); |
||||
int limit = END(pszBuffer) - pend - 2; |
||||
int ret = _vsnprintf(pend, limit, pszFormat, arg_ptr); |
||||
va_end(arg_ptr); |
||||
if (ret < 0 || ret >= limit) |
||||
{ |
||||
pend = END(pszBuffer) - 2; |
||||
*pend++ = '\n'; |
||||
} |
||||
else |
||||
pend += ret; |
||||
*pend = '\0'; |
||||
char* p1 = pszBuffer; |
||||
char* p2; |
||||
while (p2 = strchr(p1, '\n')) |
||||
{ |
||||
p2++; |
||||
char c = *p2; |
||||
*p2 = '\0'; |
||||
OutputDebugString(p1); |
||||
*p2 = c; |
||||
p1 = p2; |
||||
} |
||||
if (p1 != pszBuffer) |
||||
memmove(pszBuffer, p1, pend - p1 + 1); |
||||
pend -= (p1 - pszBuffer); |
||||
return ret; |
||||
} |
||||
#endif |
||||
|
||||
if (!wxTheApp) |
||||
{ |
||||
// print to console
|
||||
va_list arg_ptr; |
||||
va_start(arg_ptr, pszFormat); |
||||
vprintf(pszFormat, arg_ptr); |
||||
va_end(arg_ptr); |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
inline void heapchk() |
||||
{ |
||||
if (_heapchk() != _HEAPOK) |
||||
DebugBreak(); |
||||
} |
||||
|
||||
// Randomize the stack to help protect against buffer overrun exploits
|
||||
#define IMPLEMENT_RANDOMIZE_STACK(ThreadFn) \ |
||||
{ \ |
||||
static char nLoops; \ |
||||
if (nLoops <= 0) \ |
||||
nLoops = GetRand(50) + 1; \ |
||||
if (nLoops-- > 1) \ |
||||
{ \ |
||||
ThreadFn; \ |
||||
return; \ |
||||
} \ |
||||
} |
||||
|
||||
#define CATCH_PRINT_EXCEPTION(pszFn) \ |
||||
catch (std::exception& e) { \ |
||||
PrintException(&e, (pszFn)); \ |
||||
} catch (...) { \ |
||||
PrintException(NULL, (pszFn)); \ |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template<typename T1> |
||||
inline uint256 Hash(const T1 pbegin, const T1 pend) |
||||
{ |
||||
uint256 hash1; |
||||
SHA256((unsigned char*)&pbegin[0], (pend - pbegin) * sizeof(pbegin[0]), (unsigned char*)&hash1); |
||||
uint256 hash2; |
||||
SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); |
||||
return hash2; |
||||
} |
||||
|
||||
template<typename T1, typename T2> |
||||
inline uint256 Hash(const T1 p1begin, const T1 p1end, |
||||
const T2 p2begin, const T2 p2end) |
||||
{ |
||||
uint256 hash1; |
||||
SHA256_CTX ctx; |
||||
SHA256_Init(&ctx); |
||||
SHA256_Update(&ctx, (unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0])); |
||||
SHA256_Update(&ctx, (unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0])); |
||||
SHA256_Final((unsigned char*)&hash1, &ctx); |
||||
uint256 hash2; |
||||
SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); |
||||
return hash2; |
||||
} |
||||
|
||||
template<typename T1, typename T2, typename T3> |
||||
inline uint256 Hash(const T1 p1begin, const T1 p1end, |
||||
const T2 p2begin, const T2 p2end, |
||||
const T3 p3begin, const T3 p3end) |
||||
{ |
||||
uint256 hash1; |
||||
SHA256_CTX ctx; |
||||
SHA256_Init(&ctx); |
||||
SHA256_Update(&ctx, (unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0])); |
||||
SHA256_Update(&ctx, (unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0])); |
||||
SHA256_Update(&ctx, (unsigned char*)&p3begin[0], (p3end - p3begin) * sizeof(p3begin[0])); |
||||
SHA256_Final((unsigned char*)&hash1, &ctx); |
||||
uint256 hash2; |
||||
SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); |
||||
return hash2; |
||||
} |
||||
|
||||
template<typename T> |
||||
uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=VERSION) |
||||
{ |
||||
// Most of the time is spent allocating and deallocating CDataStream's
|
||||
// buffer. If this ever needs to be optimized further, make a CStaticStream
|
||||
// class with its buffer on the stack.
|
||||
CDataStream ss(nType, nVersion); |
||||
ss.reserve(10000); |
||||
ss << obj; |
||||
return Hash(ss.begin(), ss.end()); |
||||
} |
||||
|
||||
inline uint160 Hash160(const vector<unsigned char>& vch) |
||||
{ |
||||
uint256 hash1; |
||||
SHA256(&vch[0], vch.size(), (unsigned char*)&hash1); |
||||
uint160 hash2; |
||||
RIPEMD160((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); |
||||
return hash2; |
||||
} |