git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@1 1a98c847-1fd6-4fd8-948a-caf3550aa51b0.8
@ -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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
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 @@ |
|||||||
|
# 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 @@ |
|||||||
|
# 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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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; |
||||||
|
} |