You are on page 1of 150

P

| #1 paste
S
tool since
T 2002 E

create new paste

Like

create new paste


54k

N
sign up

Pastebin launched a little side project called HostCabi.net, check it out ;-)

bitcoin
DOWNLOAD | RAW | EMBED | REPORT ABUSE | PRINT

login

my alerts

Public Pastes

Untitled
1 sec ago

36 sec ago
pecesita
7 sec ago
Untitled
10 sec ago

2. inline string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend)
3. {
4.

CAutoBN_CTX pctx;

5.

CBigNum bn58 = 58;

6.

CBigNum bn0 = 0;

7.

vector<unsigned char> vchTmp(pend-pbegin+1, 0);

8.

reverse_copy(pbegin, pend, vchTmp.begin());

9.

CBigNum bn;

10.

bn.setvch(vchTmp);

11.

string str;

12.

str.reserve((pend - pbegin) * 138 / 100 + 1);

13.

CBigNum dv;

14.

CBigNum rem;

15.

while (bn > bn0)

16.

17.

if (!BN_div(&dv, &rem, &bn, &bn58, pctx))

18.

throw bignum_error("EncodeBase58 : BN_div failed");

19.

bn = dv;

20.

unsigned int c = rem.getulong();

21.

str += pszBase58[c];

22.

23.

for (const unsigned char* p = pbegin; p < pend && *p == 0; p++)

24.

str += pszBase58[0];

25.

reverse(str.begin(), str.end());

26.

return str;

27. }
28. inline string EncodeBase58(const vector<unsigned char>& vch)
29. {
30.

return EncodeBase58(&vch[0], &vch[0] + vch.size());

31. }
32. inline bool DecodeBase58(const char* psz, vector<unsigned char>& vchRet)
33. {
34.

CAutoBN_CTX pctx;

35.

vchRet.clear();

36.

CBigNum bn58 = 58;

37.

CBigNum bn = 0;

38.

CBigNum bnChar;

39.

while (isspace(*psz))

40.

psz++;

41.

for (const char* p = psz; *p; p++)

42.

43.

const char* p1 = strchr(pszBase58, *p);

44.

if (p1 == NULL)

45.

46.

while (isspace(*p))

47.

p++;

48.

if (*p != '\0')

49.

return false;

50.

break;

51.

52.

bnChar.setulong(p1 - pszBase58);

53.

if (!BN_mul(&bn, &bn, &bn58, pctx))

54.

throw bignum_error("DecodeBase58 : BN_mul failed");

55.

bn += bnChar;

56.

57.

vector<unsigned char> vchTmp = bn.getvch();

58.

if (vchTmp.size() >= 2 && vchTmp.end()[-1] == 0 && vchTmp.end()[-2] >= 0x80)

59.

vchTmp.erase(vchTmp.end()-1);

60.

int nLeadingZeros = 0;

61.

for (const char* p = psz; *p == pszBase58[0]; p++)

62.

nLeadingZeros++;

63.

vchRet.assign(nLeadingZeros + vchTmp.size(), 0);

64.

reverse_copy(vchTmp.begin(), vchTmp.end(), vchRet.end() - vchTmp.size());

65.

return true;

66. }

archive

faq

my settings

my profile

Don't like ads? PRO users don't see any ads ;-)

Untitled
5 sec ago

1. static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";

api

search...

trending pastes

BY: A GUEST ON SEP 7TH, 2013 | SYNTAX: C++ | SIZE: 414.77 KB | HITS: 115 | EXPIRES: NEVER

tools

Untitled
10 sec ago
Untitled
10 sec ago
Untitled
Modula 3 | 20 sec ago

67. inline bool DecodeBase58(const string& str, vector<unsigned char>& vchRet)


68. {
69.

return DecodeBase58(str.c_str(), vchRet);

70. }
71. inline string EncodeBase58Check(const vector<unsigned char>& vchIn)
72. {
73.

vector<unsigned char> vch(vchIn);

74.

uint256 hash = Hash(vch.begin(), vch.end());

75.

vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4);

76.

return EncodeBase58(vch);

77. }
78. inline bool DecodeBase58Check(const char* psz, vector<unsigned char>& vchRet)
79. {
80.

if (!DecodeBase58(psz, vchRet))

81.

return false;

82.

if (vchRet.size() < 4)

83.

84.

vchRet.clear();

85.

return false;

86.

87.

uint256 hash = Hash(vchRet.begin(), vchRet.end()-4);

88.

if (memcmp(&hash, &vchRet.end()[-4], 4) != 0)

89.

90.

vchRet.clear();

91.

return false;

92.

93.

vchRet.resize(vchRet.size()-4);

94.

return true;

95. }
96. inline bool DecodeBase58Check(const string& str, vector<unsigned char>& vchRet)
97. {
98.

return DecodeBase58Check(str.c_str(), vchRet);

99. }
100. static const unsigned char ADDRESSVERSION = 0;
101. inline string Hash160ToAddress(uint160 hash160)
102. {
103.

vector<unsigned char> vch(1, ADDRESSVERSION);

104.

vch.insert(vch.end(), UBEGIN(hash160), UEND(hash160));

105.

return EncodeBase58Check(vch);

106. }
107. inline bool AddressToHash160(const char* psz, uint160& hash160Ret)
108. {
109.

vector<unsigned char> vch;

110.

if (!DecodeBase58Check(psz, vch))

111.
112.
113.

return false;
if (vch.empty())
return false;

114.

unsigned char nVersion = vch[0];

115.

if (vch.size() != sizeof(hash160Ret) + 1)

116.

return false;

117.

memcpy(&hash160Ret, &vch[1], sizeof(hash160Ret));

118.

return (nVersion <= ADDRESSVERSION);

119. }
120. inline bool AddressToHash160(const string& str, uint160& hash160Ret)
121. {
122.

return AddressToHash160(str.c_str(), hash160Ret);

123. }
124. inline bool IsValidBitcoinAddress(const char* psz)
125. {
126.

uint160 hash160;

127.

return AddressToHash160(psz, hash160);

128. }
129. inline bool IsValidBitcoinAddress(const string& str)
130. {
131.

return IsValidBitcoinAddress(str.c_str());

132. }
133. inline string PubKeyToAddress(const vector<unsigned char>& vchPubKey)
134. {
135.

return Hash160ToAddress(Hash160(vchPubKey));

136. }
137. #include <stdexcept>
138. #include <vector>
139. #include <openssl/bn.h>
140. class bignum_error : public std::runtime_error
141. {
142. public:
143.

explicit bignum_error(const std::string& str) : std::runtime_error(str) {}

144. };
145. class CAutoBN_CTX
146. {
147. protected:
148.

BN_CTX* pctx;

149.

BN_CTX* operator=(BN_CTX* pnew) { return pctx = pnew; }

150. public:
151.

CAutoBN_CTX()

152.

153.

pctx = BN_CTX_new();

154.

if (pctx == NULL)

155.

throw bignum_error("CAutoBN_CTX : BN_CTX_new() returned NULL");

156.

157.

~CAutoBN_CTX()

158.

159.

if (pctx != NULL)

160.

BN_CTX_free(pctx);

161.

162.

operator BN_CTX*() { return pctx; }

163.

BN_CTX& operator*() { return *pctx; }

164.

BN_CTX** operator&() { return &pctx; }

165.

bool operator!() { return (pctx == NULL); }

166. };
167. class CBigNum : public BIGNUM
168. {
169. public:
170.

CBigNum()

171.

172.

BN_init(this);

173.

174.

CBigNum(const CBigNum& b)

175.

176.

BN_init(this);

177.

if (!BN_copy(this, &b))

178.

179.

BN_clear_free(this);

180.

throw bignum_error("CBigNum::CBigNum(const CBigNum&) : BN_copy failed");

181.

182.

183.

explicit CBigNum(const std::string& str)

184.

185.

BN_init(this);

186.

SetHex(str);

187.

188.

CBigNum& operator=(const CBigNum& b)

189.

190.

if (!BN_copy(this, &b))

191.

throw bignum_error("CBigNum::operator= : BN_copy failed");

192.

return (*this);

193.

194.

~CBigNum()

195.

196.

BN_clear_free(this);

197.

198.

CBigNum(char n)

199.

CBigNum(short n)

200.

CBigNum(int n)

201.

CBigNum(long n)

{ BN_init(this); if (n >= 0) setulong(n); else setint64(n); }

202.

CBigNum(int64 n)

{ BN_init(this); setint64(n); }

203.

CBigNum(unsigned char n)

204.

CBigNum(unsigned short n) { BN_init(this); setulong(n); }

205.

CBigNum(unsigned int n)

206.

CBigNum(unsigned long n)

207.

CBigNum(uint64 n)

208.

explicit CBigNum(uint256 n) { BN_init(this); setuint256(n); }

209.

explicit CBigNum(const std::vector<unsigned char>& vch)

210.

211.

{ BN_init(this); if (n >= 0) setulong(n); else setint64(n); }


{ BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
{ BN_init(this); if (n >= 0) setulong(n); else setint64(n); }

{ BN_init(this); setulong(n); }
{ BN_init(this); setulong(n); }
{ BN_init(this); setulong(n); }

{ BN_init(this); setuint64(n); }

BN_init(this);

212.

setvch(vch);

213.

214.

void setulong(unsigned long n)

215.

216.

if (!BN_set_word(this, n))

217.

throw bignum_error("CBigNum conversion from unsigned long : BN_set_word failed");

218.

219.

unsigned long getulong() const

220.

221.

return BN_get_word(this);

222.

223.

unsigned int getuint() const

224.

225.

return BN_get_word(this);

226.

227.

int getint() const

228.

229.

unsigned long n = BN_get_word(this);

230.

if (!BN_is_negative(this))

231.
232.

return (n > INT_MAX ? INT_MAX : n);


else

233.

return (n > INT_MAX ? INT_MIN : -(int)n);

234.

235.

void setint64(int64 n)

236.

237.

unsigned char pch[sizeof(n) + 6];

238.

unsigned char* p = pch + 4;

239.

bool fNegative = false;

240.

if (n < (int64)0)

241.

242.

n = -n;

243.

fNegative = true;

244.

245.

bool fLeadingZeroes = true;

246.

for (int i = 0; i < 8; i++)

247.

248.

unsigned char c = (n >> 56) & 0xff;

249.

n <<= 8;

250.

if (fLeadingZeroes)

251.

252.

if (c == 0)

253.

continue;

254.

if (c & 0x80)

255.

*p++ = (fNegative ? 0x80 : 0);

256.

else if (fNegative)

257.

c |= 0x80;

258.

fLeadingZeroes = false;

259.

260.

*p++ = c;

261.

262.

unsigned int nSize = p - (pch + 4);

263.

pch[0] = (nSize >> 24) & 0xff;

264.

pch[1] = (nSize >> 16) & 0xff;

265.

pch[2] = (nSize >> 8) & 0xff;

266.

pch[3] = (nSize) & 0xff;

267.

BN_mpi2bn(pch, p - pch, this);

268.

269.

void setuint64(uint64 n)

270.

271.

unsigned char pch[sizeof(n) + 6];

272.

unsigned char* p = pch + 4;

273.

bool fLeadingZeroes = true;

274.

for (int i = 0; i < 8; i++)

275.

276.

unsigned char c = (n >> 56) & 0xff;

277.

n <<= 8;

278.

if (fLeadingZeroes)

279.

280.

if (c == 0)

281.

continue;

282.

if (c & 0x80)

283.

*p++ = 0;

284.

fLeadingZeroes = false;

285.

286.

*p++ = c;

287.

288.

unsigned int nSize = p - (pch + 4);

289.

pch[0] = (nSize >> 24) & 0xff;

290.

pch[1] = (nSize >> 16) & 0xff;

291.

pch[2] = (nSize >> 8) & 0xff;

292.

pch[3] = (nSize) & 0xff;

293.

BN_mpi2bn(pch, p - pch, this);

294.

295.

void setuint256(uint256 n)

296.

297.

unsigned char pch[sizeof(n) + 6];

298.

unsigned char* p = pch + 4;

299.

bool fLeadingZeroes = true;

300.

unsigned char* pbegin = (unsigned char*)&n;

301.

unsigned char* psrc = pbegin + sizeof(n);

302.

while (psrc != pbegin)

303.

304.

unsigned char c = *(--psrc);

305.

if (fLeadingZeroes)

306.

307.

if (c == 0)

308.

continue;

309.

if (c & 0x80)

310.

*p++ = 0;

311.

fLeadingZeroes = false;

312.

313.

*p++ = c;

314.

315.

unsigned int nSize = p - (pch + 4);

316.

pch[0] = (nSize >> 24) & 0xff;

317.

pch[1] = (nSize >> 16) & 0xff;

318.

pch[2] = (nSize >> 8) & 0xff;

319.

pch[3] = (nSize >> 0) & 0xff;

320.

BN_mpi2bn(pch, p - pch, this);

321.

322.

uint256 getuint256()

323.

324.

unsigned int nSize = BN_bn2mpi(this, NULL);

325.

if (nSize < 4)

326.

return 0;

327.

std::vector<unsigned char> vch(nSize);

328.

BN_bn2mpi(this, &vch[0]);

329.

if (vch.size() > 4)

330.

vch[4] &= 0x7f;

331.

uint256 n = 0;

332.

for (int i = 0, j = vch.size()-1; i < sizeof(n) && j >= 4; i++, j--)

333.

((unsigned char*)&n)[i] = vch[j];

334.

return n;

335.

336.

void setvch(const std::vector<unsigned char>& vch)

337.

338.

std::vector<unsigned char> vch2(vch.size() + 4);

339.

unsigned int nSize = vch.size();

340.

vch2[0] = (nSize >> 24) & 0xff;

341.

vch2[1] = (nSize >> 16) & 0xff;

342.

vch2[2] = (nSize >> 8) & 0xff;

343.

vch2[3] = (nSize >> 0) & 0xff;

344.

reverse_copy(vch.begin(), vch.end(), vch2.begin() + 4);

345.

BN_mpi2bn(&vch2[0], vch2.size(), this);

346.

347.

std::vector<unsigned char> getvch() const

348.

349.

unsigned int nSize = BN_bn2mpi(this, NULL);

350.

if (nSize < 4)

351.

return std::vector<unsigned char>();

352.

std::vector<unsigned char> vch(nSize);

353.

BN_bn2mpi(this, &vch[0]);

354.

vch.erase(vch.begin(), vch.begin() + 4);

355.

reverse(vch.begin(), vch.end());

356.

return vch;

357.

358.

CBigNum& SetCompact(unsigned int nCompact)

359.

360.

unsigned int nSize = nCompact >> 24;

361.

std::vector<unsigned char> vch(4 + nSize);

362.

vch[3] = nSize;

363.

if (nSize >= 1) vch[4] = (nCompact >> 16) & 0xff;

364.

if (nSize >= 2) vch[5] = (nCompact >> 8) & 0xff;

365.

if (nSize >= 3) vch[6] = (nCompact >> 0) & 0xff;

366.

BN_mpi2bn(&vch[0], vch.size(), this);

367.

return *this;

368.

369.

unsigned int GetCompact() const

370.

371.

unsigned int nSize = BN_bn2mpi(this, NULL);

372.

std::vector<unsigned char> vch(nSize);

373.

nSize -= 4;

374.

BN_bn2mpi(this, &vch[0]);

375.

unsigned int nCompact = nSize << 24;

376.

if (nSize >= 1) nCompact |= (vch[4] << 16);

377.

if (nSize >= 2) nCompact |= (vch[5] << 8);

378.

if (nSize >= 3) nCompact |= (vch[6] << 0);

379.

return nCompact;

380.

381.

void SetHex(const std::string& str)

382.

383.

const char* psz = str.c_str();

384.

while (isspace(*psz))

385.

psz++;

386.

bool fNegative = false;

387.

if (*psz == '-')

388.

389.

fNegative = true;

390.

psz++;

391.

392.

if (psz[0] == '0' && tolower(psz[1]) == 'x')

393.

psz += 2;

394.

while (isspace(*psz))

395.

psz++;

396.

static char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,


0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0
};

397.

*this = 0;

398.

while (isxdigit(*psz))

399.

400.

*this <<= 4;

401.

int n = phexdigit[*psz++];

402.

*this += n;

403.

404.

if (fNegative)

405.

*this = 0 - *this;

406.

407.

unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const

408.

409.

return ::GetSerializeSize(getvch(), nType, nVersion);

410.

411.

template<typename Stream>

412.

void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const

413.

414.

::Serialize(s, getvch(), nType, nVersion);

415.

416.

template<typename Stream>

417.

void Unserialize(Stream& s, int nType=0, int nVersion=VERSION)

418.

419.

vector<unsigned char> vch;

420.

::Unserialize(s, vch, nType, nVersion);

421.

setvch(vch);

422.

423.

bool operator!() const

424.

425.

return BN_is_zero(this);

426.

427.

CBigNum& operator+=(const CBigNum& b)

428.

429.

if (!BN_add(this, this, &b))

430.

throw bignum_error("CBigNum::operator+= : BN_add failed");

431.

return *this;

432.

433.

CBigNum& operator-=(const CBigNum& b)

434.

435.

*this = *this - b;

436.

return *this;

437.

438.

CBigNum& operator*=(const CBigNum& b)

439.

440.

CAutoBN_CTX pctx;

441.

if (!BN_mul(this, this, &b, pctx))

442.

throw bignum_error("CBigNum::operator*= : BN_mul failed");

443.

return *this;

444.

445.

CBigNum& operator/=(const CBigNum& b)

446.

447.

*this = *this / b;

448.

return *this;

449.

450.

CBigNum& operator%=(const CBigNum& b)

451.

452.

*this = *this % b;

453.

return *this;

454.

455.

CBigNum& operator<<=(unsigned int shift)

456.

457.

if (!BN_lshift(this, this, shift))

458.

throw bignum_error("CBigNum:operator<<= : BN_lshift failed");

459.

return *this;

460.

461.

CBigNum& operator>>=(unsigned int shift)

462.

463.

if (!BN_rshift(this, this, shift))

464.

throw bignum_error("CBigNum:operator>>= : BN_rshift failed");

465.

return *this;

466.

467.

CBigNum& operator++()

468.

469.

if (!BN_add(this, this, BN_value_one()))

470.

throw bignum_error("CBigNum::operator++ : BN_add failed");

471.

return *this;

472.

473.

const CBigNum operator++(int)

474.

475.

const CBigNum ret = *this;

476.

++(*this);

477.

return ret;

478.

479.

CBigNum& operator--()

480.

481.

CBigNum r;

482.

if (!BN_sub(&r, this, BN_value_one()))

483.

throw bignum_error("CBigNum::operator-- : BN_sub failed");

484.

*this = r;

485.

return *this;

486.

487.

const CBigNum operator--(int)

488.

489.

const CBigNum ret = *this;

490.

--(*this);

491.

return ret;

492.

493.

friend inline const CBigNum operator-(const CBigNum& a, const CBigNum& b);

494.

friend inline const CBigNum operator/(const CBigNum& a, const CBigNum& b);

495.

friend inline const CBigNum operator%(const CBigNum& a, const CBigNum& b);

496. };
497. inline const CBigNum operator+(const CBigNum& a, const CBigNum& b)
498. {
499.

CBigNum r;

500.

if (!BN_add(&r, &a, &b))

501.
502.

throw bignum_error("CBigNum::operator+ : BN_add failed");


return r;

503. }
504. inline const CBigNum operator-(const CBigNum& a, const CBigNum& b)
505. {
506.

CBigNum r;

507.

if (!BN_sub(&r, &a, &b))

508.
509.

throw bignum_error("CBigNum::operator- : BN_sub failed");


return r;

510. }
511. inline const CBigNum operator-(const CBigNum& a)
512. {
513.

CBigNum r(a);

514.

BN_set_negative(&r, !BN_is_negative(&r));

515.

return r;

516. }
517. inline const CBigNum operator*(const CBigNum& a, const CBigNum& b)
518. {
519.

CAutoBN_CTX pctx;

520.

CBigNum r;

521.

if (!BN_mul(&r, &a, &b, pctx))

522.
523.

throw bignum_error("CBigNum::operator* : BN_mul failed");


return r;

524. }
525. inline const CBigNum operator/(const CBigNum& a, const CBigNum& b)
526. {
527.

CAutoBN_CTX pctx;

528.

CBigNum r;

529.

if (!BN_div(&r, NULL, &a, &b, pctx))

530.
531.

throw bignum_error("CBigNum::operator/ : BN_div failed");


return r;

532. }
533. inline const CBigNum operator%(const CBigNum& a, const CBigNum& b)
534. {
535.

CAutoBN_CTX pctx;

536.

CBigNum r;

537.

if (!BN_mod(&r, &a, &b, pctx))

538.
539.

throw bignum_error("CBigNum::operator% : BN_div failed");


return r;

540. }
541. inline const CBigNum operator<<(const CBigNum& a, unsigned int shift)
542. {
543.

CBigNum r;

544.

if (!BN_lshift(&r, &a, shift))

545.
546.

throw bignum_error("CBigNum:operator<< : BN_lshift failed");


return r;

547. }
548. inline const CBigNum operator>>(const CBigNum& a, unsigned int shift)
549. {
550.

CBigNum r;

551.

if (!BN_rshift(&r, &a, shift))

552.
553.

throw bignum_error("CBigNum:operator>> : BN_rshift failed");


return r;

554. }
555. inline bool operator==(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) == 0); }
556. inline bool operator!=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) != 0); }
557. inline bool operator<=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) <= 0); }
558. inline bool operator>=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) >= 0); }
559. inline bool operator<(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) < 0); }
560. inline bool operator>(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) > 0); }
561. #include "headers.h"
562. static CCriticalSection cs_db;

563. static bool fDbEnvInit = false;


564. DbEnv dbenv(0);
565. static map<string, int> mapFileUseCount;
566. class CDBInit
567. {
568. public:
569.

CDBInit()

570.

571.

572.

~CDBInit()

573.

574.

if (fDbEnvInit)

575.

576.

dbenv.close(0);

577.

fDbEnvInit = false;

578.
579.

}
}

580. }
581. instance_of_cdbinit;
582. CDB::CDB(const char* pszFile, const char* pszMode, bool fTxn) : pdb(NULL)
583. {
584.

int ret;

585.

if (pszFile == NULL)

586.

return;

587.
588.

bool fCreate = strchr(pszMode, 'c');

589.

bool fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w'));

590.

unsigned int nFlags = DB_THREAD;

591.

if (fCreate)

592.
593.

nFlags |= DB_CREATE;
else if (fReadOnly)

594.
595.

nFlags |= DB_RDONLY;
if (!fReadOnly || fTxn)

596.

nFlags |= DB_AUTO_COMMIT;

597.

CRITICAL_BLOCK(cs_db)

598.

599.

if (!fDbEnvInit)

600.

601.

string strAppDir = GetAppDir();

602.

string strLogDir = strAppDir + "\\database";

603.

_mkdir(strLogDir.c_str());

604.

printf("dbenv.open strAppDir=%s\n", strAppDir.c_str());

605.

dbenv.set_lg_dir(strLogDir.c_str());

606.

dbenv.set_lg_max(10000000);

607.

dbenv.set_lk_max_locks(10000);

608.

dbenv.set_lk_max_objects(10000);

609.

dbenv.set_errfile(fopen("db.log", "a"));

610.

ret = dbenv.open(strAppDir.c_str(),

611.

DB_CREATE

612.

DB_INIT_LOCK |

613.

DB_INIT_LOG |

614.

DB_INIT_MPOOL |

615.

DB_INIT_TXN |

616.

DB_THREAD

617.

DB_PRIVATE

618.

DB_RECOVER,

619.

0);

620.

if (ret > 0)

621.

throw runtime_error(strprintf("CDB() : error %d opening database environment\n", ret));

622.

fDbEnvInit = true;

623.

624.

strFile = pszFile;

625.

++mapFileUseCount[strFile];

626.

627.

pdb = new Db(&dbenv, 0);

628.

ret = pdb->open(NULL,

629.

pszFile,

630.

"main",

631.

DB_BTREE,

632.

nFlags,

633.

0);

634.

if (ret > 0)

635.

636.

delete pdb;

637.

pdb = NULL;

638.

CRITICAL_BLOCK(cs_db)

639.

--mapFileUseCount[strFile];

640.

strFile = "";

641.

throw runtime_error(strprintf("CDB() : can't open database file %s, error %d\n", pszFile, ret));

642.

643.

if (fCreate && !Exists(string("version")))

644.
645.

WriteVersion(VERSION);
RandAddSeed();

646. }
647. void CDB::Close()
648. {
649.

if (!pdb)

650.
651.

return;
if (!vTxn.empty())

652.

vTxn.front()->abort();

653.

vTxn.clear();

654.

pdb->close(0);

655.

delete pdb;

656.

pdb = NULL;

657.

dbenv.txn_checkpoint(0, 0, 0);

658.

CRITICAL_BLOCK(cs_db)

659.
660.

--mapFileUseCount[strFile];
RandAddSeed();

661. }
662. void DBFlush(bool fShutdown)
663. {
664.

printf("DBFlush(%s)\n", fShutdown ? "true" : "false");

665.

CRITICAL_BLOCK(cs_db)

666.

667.

dbenv.txn_checkpoint(0, 0, 0);

668.

map<string, int>::iterator mi = mapFileUseCount.begin();

669.

while (mi != mapFileUseCount.end())

670.

671.

string strFile = (*mi).first;

672.

int nRefCount = (*mi).second;

673.

if (nRefCount == 0)

674.

675.

dbenv.lsn_reset(strFile.c_str(), 0);

676.

mapFileUseCount.erase(mi++);

677.

678.

else

679.

mi++;

680.

681.

if (fShutdown)

682.

683.

char** listp;

684.

if (mapFileUseCount.empty())

685.

dbenv.log_archive(&listp, DB_ARCH_REMOVE);

686.

dbenv.close(0);

687.

fDbEnvInit = false;

688.
689.

}
}

690. }
691. bool CTxDB::ReadTxIndex(uint256 hash, CTxIndex& txindex)
692. {
693.

assert(!fClient);

694.

txindex.SetNull();

695.

return Read(make_pair(string("tx"), hash), txindex);

696. }
697. bool CTxDB::UpdateTxIndex(uint256 hash, const CTxIndex& txindex)
698. {
699.

assert(!fClient);

700.

return Write(make_pair(string("tx"), hash), txindex);

701. }
702. bool CTxDB::AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight)
703. {
704.

assert(!fClient);

705.

uint256 hash = tx.GetHash();

706.

CTxIndex txindex(pos, tx.vout.size());

707.

return Write(make_pair(string("tx"), hash), txindex);

708. }
709. bool CTxDB::EraseTxIndex(const CTransaction& tx)
710. {
711.

assert(!fClient);

712.

uint256 hash = tx.GetHash();

713.

return Erase(make_pair(string("tx"), hash));

714. }
715. bool CTxDB::ContainsTx(uint256 hash)
716. {
717.

assert(!fClient);

718.

return Exists(make_pair(string("tx"), hash));

719. }
720. bool CTxDB::ReadOwnerTxes(uint160 hash160, int nMinHeight, vector<CTransaction>& vtx)
721. {
722.

assert(!fClient);

723.

vtx.clear();

724.

Dbc* pcursor = GetCursor();

725.

if (!pcursor)

726.

return false;

727.

unsigned int fFlags = DB_SET_RANGE;

728.

loop

729.

730.

CDataStream ssKey;

731.

if (fFlags == DB_SET_RANGE)

732.

ssKey << string("owner") << hash160 << CDiskTxPos(0, 0, 0);

733.

CDataStream ssValue;

734.

int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags);

735.

fFlags = DB_NEXT;

736.

if (ret == DB_NOTFOUND)

737.

break;

738.

else if (ret != 0)

739.

return false;

740.

string strType;

741.

uint160 hashItem;

742.

CDiskTxPos pos;

743.

ssKey >> strType >> hashItem >> pos;

744.

int nItemHeight;

745.

ssValue >> nItemHeight;

746.

if (strType != "owner" || hashItem != hash160)

747.

break;

748.

if (nItemHeight >= nMinHeight)

749.

750.

vtx.resize(vtx.size()+1);

751.

if (!vtx.back().ReadFromDisk(pos))

752.

return false;

753.

754.

755.

return true;

756. }
757. bool CTxDB::ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex)
758. {
759.

assert(!fClient);

760.

tx.SetNull();

761.

if (!ReadTxIndex(hash, txindex))

762.
763.

return false;
return (tx.ReadFromDisk(txindex.pos));

764. }
765. bool CTxDB::ReadDiskTx(uint256 hash, CTransaction& tx)
766. {
767.

CTxIndex txindex;

768.

return ReadDiskTx(hash, tx, txindex);

769. }
770. bool CTxDB::ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex)
771. {
772.

return ReadDiskTx(outpoint.hash, tx, txindex);

773. }
774. bool CTxDB::ReadDiskTx(COutPoint outpoint, CTransaction& tx)
775. {
776.

CTxIndex txindex;

777.

return ReadDiskTx(outpoint.hash, tx, txindex);

778. }
779. bool CTxDB::WriteBlockIndex(const CDiskBlockIndex& blockindex)
780. {
781.

return Write(make_pair(string("blockindex"), blockindex.GetBlockHash()), blockindex);

782. }
783. bool CTxDB::EraseBlockIndex(uint256 hash)
784. {
785.

return Erase(make_pair(string("blockindex"), hash));

786. }
787. bool CTxDB::ReadHashBestChain(uint256& hashBestChain)
788. {
789.

return Read(string("hashBestChain"), hashBestChain);

790. }
791. bool CTxDB::WriteHashBestChain(uint256 hashBestChain)
792. {
793.

return Write(string("hashBestChain"), hashBestChain);

794. }
795. CBlockIndex* InsertBlockIndex(uint256 hash)
796. {
797.
798.

if (hash == 0)
return NULL;

799.

map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);

800.

if (mi != mapBlockIndex.end())

801.

return (*mi).second;

802.

CBlockIndex* pindexNew = new CBlockIndex();

803.

if (!pindexNew)

804.

throw runtime_error("LoadBlockIndex() : new CBlockIndex failed");

805.

mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;

806.

pindexNew->phashBlock = &((*mi).first);

807.

return pindexNew;

808. }
809. bool CTxDB::LoadBlockIndex()
810. {
811.

Dbc* pcursor = GetCursor();

812.

if (!pcursor)

813.

return false;

814.

unsigned int fFlags = DB_SET_RANGE;

815.

loop

816.

817.

CDataStream ssKey;

818.

if (fFlags == DB_SET_RANGE)

819.

ssKey << make_pair(string("blockindex"), uint256(0));

820.

CDataStream ssValue;

821.

int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags);

822.

fFlags = DB_NEXT;

823.

if (ret == DB_NOTFOUND)

824.

break;

825.

else if (ret != 0)

826.

return false;

827.

string strType;

828.

ssKey >> strType;

829.

if (strType == "blockindex")

830.

831.

CDiskBlockIndex diskindex;

832.

ssValue >> diskindex;

833.

CBlockIndex* pindexNew = InsertBlockIndex(diskindex.GetBlockHash());

834.

pindexNew->pprev

= InsertBlockIndex(diskindex.hashPrev);

835.

pindexNew->pnext

= InsertBlockIndex(diskindex.hashNext);

836.

pindexNew->nFile

= diskindex.nFile;

837.

pindexNew->nBlockPos

838.

pindexNew->nHeight

= diskindex.nHeight;

839.

pindexNew->nVersion

= diskindex.nVersion;

840.

pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot;

841.

pindexNew->nTime

842.

pindexNew->nBits

843.

pindexNew->nNonce

844.

if (pindexGenesisBlock == NULL && diskindex.GetBlockHash() == hashGenesisBlock)

845.

= diskindex.nBlockPos;

= diskindex.nTime;
= diskindex.nBits;
= diskindex.nNonce;

pindexGenesisBlock = pindexNew;

846.

847.

else

848.

849.

break;

850.

851.

852.

if (!ReadHashBestChain(hashBestChain))

853.

854.

if (pindexGenesisBlock == NULL)

855.

return true;

856.

return error("CTxDB::LoadBlockIndex() : hashBestChain not found\n");

857.

858.

if (!mapBlockIndex.count(hashBestChain))

859.

return error("CTxDB::LoadBlockIndex() : blockindex for hashBestChain not found\n");

860.

pindexBest = mapBlockIndex[hashBestChain];

861.

nBestHeight = pindexBest->nHeight;

862.

printf("LoadBlockIndex(): hashBestChain=%s height=%d\n", hashBestChain.ToString().substr(0,14).c_str(), nBestHeight);

863.

return true;

864. }
865. bool CAddrDB::WriteAddress(const CAddress& addr)
866. {
867.

return Write(make_pair(string("addr"), addr.GetKey()), addr);

868. }
869. bool CAddrDB::LoadAddresses()
870. {
871.

CRITICAL_BLOCK(cs_mapAddresses)

872.

873.

CAutoFile filein = fopen("addr.txt", "rt");

874.

if (filein)

875.

876.

try

877.

878.

char psz[1000];

879.

while (fgets(psz, sizeof(psz), filein))

880.

881.

CAddress addr(psz, NODE_NETWORK);

882.

if (addr.ip != 0)

883.

AddAddress(*this, addr);

884.

885.

886.

catch (...) { }

887.

888.

Dbc* pcursor = GetCursor();

889.

if (!pcursor)

890.

return false;

891.

loop

892.

893.

CDataStream ssKey;

894.

CDataStream ssValue;

895.

int ret = ReadAtCursor(pcursor, ssKey, ssValue);

896.

if (ret == DB_NOTFOUND)

897.

break;

898.

else if (ret != 0)

899.

return false;

900.

string strType;

901.

ssKey >> strType;

902.

if (strType == "addr")

903.

904.

CAddress addr;

905.

ssValue >> addr;

906.

mapAddresses.insert(make_pair(addr.GetKey(), addr));

907.

908.

909.

printf("mapAddresses:\n");

910.

foreach(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)

911.

item.second.print();

912.

printf("-----\n");

913.

914.

return true;

915. }
916. bool LoadAddresses()
917. {
918.

return CAddrDB("cr+").LoadAddresses();

919. }
920. bool CReviewDB::ReadReviews(uint256 hash, vector<CReview>& vReviews)
921. {
922.

vReviews.size();

923.

return Read(make_pair(string("reviews"), hash), vReviews);

924. }
925. bool CReviewDB::WriteReviews(uint256 hash, const vector<CReview>& vReviews)
926. {
927.

return Write(make_pair(string("reviews"), hash), vReviews);

928. }
929. bool CWalletDB::LoadWallet(vector<unsigned char>& vchDefaultKeyRet)
930. {
931.

vchDefaultKeyRet.clear();

932.

CRITICAL_BLOCK(cs_mapKeys)

933.

CRITICAL_BLOCK(cs_mapWallet)

934.

935.

Dbc* pcursor = GetCursor();

936.

if (!pcursor)

937.

return false;

938.

loop

939.

940.

CDataStream ssKey;

941.

CDataStream ssValue;

942.

int ret = ReadAtCursor(pcursor, ssKey, ssValue);

943.

if (ret == DB_NOTFOUND)

944.
945.

break;
else if (ret != 0)

946.

return false;

947.

string strType;

948.

ssKey >> strType;

949.

if (strType == "name")

950.

951.

string strAddress;

952.

ssKey >> strAddress;

953.

ssValue >> mapAddressBook[strAddress];

954.

955.

else if (strType == "tx")

956.

957.

uint256 hash;

958.

ssKey >> hash;

959.

CWalletTx& wtx = mapWallet[hash];

960.

ssValue >> wtx;

961.
962.

if (wtx.GetHash() != hash)

963.

printf("Error in wallet.dat, hash mismatch\n");

964.

965.

else if (strType == "key")

966.

967.

vector<unsigned char> vchPubKey;

968.

ssKey >> vchPubKey;

969.

CPrivKey vchPrivKey;

970.

ssValue >> vchPrivKey;

971.

mapKeys[vchPubKey] = vchPrivKey;

972.

mapPubKeys[Hash160(vchPubKey)] = vchPubKey;

973.

974.

else if (strType == "defaultkey")

975.

976.
977.

ssValue >> vchDefaultKeyRet;


}

978.

else if (strType == "setting")

979.

980.

string strKey;

981.

ssKey >> strKey;

982.

if (strKey == "fGenerateBitcoins") ssValue >> fGenerateBitcoins;

983.

if (strKey == "nTransactionFee")

984.

if (strKey == "addrIncoming")

985.

ssValue >> nTransactionFee;


ssValue >> addrIncoming;

986.

987.

988.

printf("fGenerateBitcoins = %d\n", fGenerateBitcoins);

989.

printf("nTransactionFee = %I64d\n", nTransactionFee);

990.

printf("addrIncoming = %s\n", addrIncoming.ToString().c_str());

991.

return true;

992. }
993. bool LoadWallet()
994. {
995.

vector<unsigned char> vchDefaultKey;

996.

if (!CWalletDB("cr").LoadWallet(vchDefaultKey))

997.

return false;

998.

if (mapKeys.count(vchDefaultKey))

999.

1000.

keyUser.SetPubKey(vchDefaultKey);

1001.

keyUser.SetPrivKey(mapKeys[vchDefaultKey]);

1002.

1003.

else

1004.

1005.

keyUser.MakeNewKey();

1006.

if (!AddKey(keyUser))

1007.

return false;

1008.

if (!SetAddressBookName(PubKeyToAddress(keyUser.GetPubKey()), "Your Address"))

1009.

return false;

1010.

CWalletDB().WriteDefaultKey(keyUser.GetPubKey());

1011.

1012.

return true;

1013. }
1014. #include <db_cxx.h>
1015. class CTransaction;
1016. class CTxIndex;
1017. class CDiskBlockIndex;
1018. class CDiskTxPos;
1019. class COutPoint;
1020. class CUser;
1021. class CReview;
1022. class CAddress;
1023. class CWalletTx;
1024. extern map<string, string> mapAddressBook;
1025. extern bool fClient;
1026. extern DbEnv dbenv;
1027. extern void DBFlush(bool fShutdown);
1028. class CDB
1029. {
1030. protected:
1031.

Db* pdb;

1032.

string strFile;

1033.

vector<DbTxn*> vTxn;

1034.

explicit CDB(const char* pszFile, const char* pszMode="r+", bool fTxn=false);

1035.

~CDB() { Close(); }

1036. public:
1037.

void Close();

1038. private:
1039.

CDB(const CDB&);

1040.

void operator=(const CDB&);

1041. protected:
1042.

template<typename K, typename T>

1043.

bool Read(const K& key, T& value)

1044.

1045.
1046.

if (!pdb)
return false;

1047.

CDataStream ssKey(SER_DISK);

1048.

ssKey.reserve(1000);

1049.

ssKey << key;

1050.

Dbt datKey(&ssKey[0], ssKey.size());

1051.

Dbt datValue;

1052.

datValue.set_flags(DB_DBT_MALLOC);

1053.

int ret = pdb->get(GetTxn(), &datKey, &datValue, 0);

1054.

memset(datKey.get_data(), 0, datKey.get_size());

1055.

if (datValue.get_data() == NULL)

1056.

return false;

1057.

CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK);

1058.

ssValue >> value;

1059.

memset(datValue.get_data(), 0, datValue.get_size());

1060.

free(datValue.get_data());

1061.

return (ret == 0);

1062.

1063.

template<typename K, typename T>

1064.

bool Write(const K& key, const T& value, bool fOverwrite=true)

1065.

1066.

if (!pdb)

1067.

return false;

1068.

CDataStream ssKey(SER_DISK);

1069.

ssKey.reserve(1000);

1070.

ssKey << key;

1071.

Dbt datKey(&ssKey[0], ssKey.size());

1072.

CDataStream ssValue(SER_DISK);

1073.

ssValue.reserve(10000);

1074.

ssValue << value;

1075.

Dbt datValue(&ssValue[0], ssValue.size());

1076.

int ret = pdb->put(GetTxn(), &datKey, &datValue, (fOverwrite ? 0 : DB_NOOVERWRITE));

1077.

memset(datKey.get_data(), 0, datKey.get_size());

1078.

memset(datValue.get_data(), 0, datValue.get_size());

1079.

return (ret == 0);

1080.

1081.

template<typename K>

1082.

bool Erase(const K& key)

1083.

1084.

if (!pdb)

1085.

return false;

1086.

CDataStream ssKey(SER_DISK);

1087.

ssKey.reserve(1000);

1088.

ssKey << key;

1089.

Dbt datKey(&ssKey[0], ssKey.size());

1090.

int ret = pdb->del(GetTxn(), &datKey, 0);

1091.

memset(datKey.get_data(), 0, datKey.get_size());

1092.

return (ret == 0 || ret == DB_NOTFOUND);

1093.

1094.

template<typename K>

1095.

bool Exists(const K& key)

1096.

1097.

if (!pdb)

1098.

return false;

1099.

CDataStream ssKey(SER_DISK);

1100.

ssKey.reserve(1000);

1101.

ssKey << key;

1102.

Dbt datKey(&ssKey[0], ssKey.size());

1103.

int ret = pdb->exists(GetTxn(), &datKey, 0);

1104.

memset(datKey.get_data(), 0, datKey.get_size());

1105.

return (ret == 0);

1106.

1107.

Dbc* GetCursor()

1108.

1109.

if (!pdb)

1110.

return NULL;

1111.

Dbc* pcursor = NULL;

1112.

int ret = pdb->cursor(NULL, &pcursor, 0);

1113.

if (ret != 0)

1114.

return NULL;

1115.

return pcursor;

1116.

1117.

int ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue, unsigned int fFlags=DB_NEXT)

1118.

1119.

Dbt datKey;

1120.

if (fFlags == DB_SET || fFlags == DB_SET_RANGE || fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)

1121.

1122.

datKey.set_data(&ssKey[0]);

1123.

datKey.set_size(ssKey.size());

1124.

1125.

Dbt datValue;

1126.

if (fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)

1127.

1128.

datValue.set_data(&ssValue[0]);

1129.

datValue.set_size(ssValue.size());

1130.

1131.

datKey.set_flags(DB_DBT_MALLOC);

1132.

datValue.set_flags(DB_DBT_MALLOC);

1133.

int ret = pcursor->get(&datKey, &datValue, fFlags);

1134.

if (ret != 0)

1135.
1136.
1137.

return ret;
else if (datKey.get_data() == NULL || datValue.get_data() == NULL)
return 99999;

1138.

ssKey.SetType(SER_DISK);

1139.

ssKey.clear();

1140.

ssKey.write((char*)datKey.get_data(), datKey.get_size());

1141.

ssValue.SetType(SER_DISK);

1142.

ssValue.clear();

1143.

ssValue.write((char*)datValue.get_data(), datValue.get_size());

1144.

memset(datKey.get_data(), 0, datKey.get_size());

1145.

memset(datValue.get_data(), 0, datValue.get_size());

1146.

free(datKey.get_data());

1147.

free(datValue.get_data());

1148.

return 0;

1149.

1150.

DbTxn* GetTxn()

1151.

1152.

if (!vTxn.empty())

1153.

return vTxn.back();

1154.

else

1155.
1156.

return NULL;
}

1157. public:
1158.

bool TxnBegin()

1159.

1160.

if (!pdb)

1161.

return false;

1162.

DbTxn* ptxn = NULL;

1163.

int ret = dbenv.txn_begin(GetTxn(), &ptxn, 0);

1164.

if (!ptxn || ret != 0)

1165.

return false;

1166.

vTxn.push_back(ptxn);

1167.

return true;

1168.

1169.

bool TxnCommit()

1170.

1171.

if (!pdb)

1172.

return false;

1173.

if (vTxn.empty())

1174.

return false;

1175.

int ret = vTxn.back()->commit(0);

1176.

vTxn.pop_back();

1177.

return (ret == 0);

1178.

1179.

bool TxnAbort()

1180.

1181.

if (!pdb)

1182.

return false;

1183.

if (vTxn.empty())

1184.

return false;

1185.

int ret = vTxn.back()->abort();

1186.

vTxn.pop_back();

1187.

return (ret == 0);

1188.

1189.

bool ReadVersion(int& nVersion)

1190.

1191.

nVersion = 0;

1192.

return Read(string("version"), nVersion);

1193.

1194.

bool WriteVersion(int nVersion)

1195.

1196.
1197.

return Write(string("version"), nVersion);


}

1198. };
1199. class CTxDB : public CDB
1200. {
1201. public:
1202.

CTxDB(const char* pszMode="r+", bool fTxn=false) : CDB(!fClient ? "blkindex.dat" : NULL, pszMode, fTxn) { }

1203. private:
1204.

CTxDB(const CTxDB&);

1205.

void operator=(const CTxDB&);

1206. public:
1207.

bool ReadTxIndex(uint256 hash, CTxIndex& txindex);

1208.

bool UpdateTxIndex(uint256 hash, const CTxIndex& txindex);

1209.

bool AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight);

1210.

bool EraseTxIndex(const CTransaction& tx);

1211.

bool ContainsTx(uint256 hash);

1212.

bool ReadOwnerTxes(uint160 hash160, int nHeight, vector<CTransaction>& vtx);

1213.

bool ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex);

1214.

bool ReadDiskTx(uint256 hash, CTransaction& tx);

1215.

bool ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex);

1216.

bool ReadDiskTx(COutPoint outpoint, CTransaction& tx);

1217.

bool WriteBlockIndex(const CDiskBlockIndex& blockindex);

1218.

bool EraseBlockIndex(uint256 hash);

1219.

bool ReadHashBestChain(uint256& hashBestChain);

1220.

bool WriteHashBestChain(uint256 hashBestChain);

1221.

bool LoadBlockIndex();

1222. };
1223. class CReviewDB : public CDB
1224. {
1225. public:
1226.

CReviewDB(const char* pszMode="r+", bool fTxn=false) : CDB("reviews.dat", pszMode, fTxn) { }

1227. private:
1228.

CReviewDB(const CReviewDB&);

1229.

void operator=(const CReviewDB&);

1230. public:
1231.

bool ReadUser(uint256 hash, CUser& user)

1232.

1233.

return Read(make_pair(string("user"), hash), user);

1234.

1235.

bool WriteUser(uint256 hash, const CUser& user)

1236.

1237.

return Write(make_pair(string("user"), hash), user);

1238.

1239.

bool ReadReviews(uint256 hash, vector<CReview>& vReviews);

1240.

bool WriteReviews(uint256 hash, const vector<CReview>& vReviews);

1241. };
1242. class CMarketDB : public CDB
1243. {
1244. public:
1245.

CMarketDB(const char* pszMode="r+", bool fTxn=false) : CDB("market.dat", pszMode, fTxn) { }

1246. private:
1247.

CMarketDB(const CMarketDB&);

1248.

void operator=(const CMarketDB&);

1249. };
1250. class CAddrDB : public CDB
1251. {
1252. public:
1253.

CAddrDB(const char* pszMode="r+", bool fTxn=false) : CDB("addr.dat", pszMode, fTxn) { }

1254. private:
1255.

CAddrDB(const CAddrDB&);

1256.

void operator=(const CAddrDB&);

1257. public:
1258.

bool WriteAddress(const CAddress& addr);

1259.

bool LoadAddresses();

1260. };
1261. bool LoadAddresses();
1262. class CWalletDB : public CDB
1263. {
1264. public:
1265.

CWalletDB(const char* pszMode="r+", bool fTxn=false) : CDB("wallet.dat", pszMode, fTxn) { }

1266. private:
1267.

CWalletDB(const CWalletDB&);

1268.

void operator=(const CWalletDB&);

1269. public:
1270.

bool ReadName(const string& strAddress, string& strName)

1271.

1272.

strName = "";

1273.

return Read(make_pair(string("name"), strAddress), strName);

1274.

1275.

bool WriteName(const string& strAddress, const string& strName)

1276.

1277.

mapAddressBook[strAddress] = strName;

1278.

return Write(make_pair(string("name"), strAddress), strName);

1279.

1280.

bool EraseName(const string& strAddress)

1281.

1282.

mapAddressBook.erase(strAddress);

1283.

return Erase(make_pair(string("name"), strAddress));

1284.

1285.

bool ReadTx(uint256 hash, CWalletTx& wtx)

1286.

1287.

return Read(make_pair(string("tx"), hash), wtx);

1288.

1289.

bool WriteTx(uint256 hash, const CWalletTx& wtx)

1290.

1291.

return Write(make_pair(string("tx"), hash), wtx);

1292.

1293.

bool EraseTx(uint256 hash)

1294.

1295.

return Erase(make_pair(string("tx"), hash));

1296.

1297.

bool ReadKey(const vector<unsigned char>& vchPubKey, CPrivKey& vchPrivKey)

1298.

1299.

vchPrivKey.clear();

1300.

return Read(make_pair(string("key"), vchPubKey), vchPrivKey);

1301.

1302.

bool WriteKey(const vector<unsigned char>& vchPubKey, const CPrivKey& vchPrivKey)

1303.

1304.

return Write(make_pair(string("key"), vchPubKey), vchPrivKey, false);

1305.

1306.

bool ReadDefaultKey(vector<unsigned char>& vchPubKey)

1307.

1308.

vchPubKey.clear();

1309.

return Read(string("defaultkey"), vchPubKey);

1310.

1311.

bool WriteDefaultKey(const vector<unsigned char>& vchPubKey)

1312.

1313.

return Write(string("defaultkey"), vchPubKey);

1314.

1315.

template<typename T>

1316.

bool ReadSetting(const string& strKey, T& value)

1317.

1318.

return Read(make_pair(string("setting"), strKey), value);

1319.

1320.

template<typename T>

1321.

bool WriteSetting(const string& strKey, const T& value)

1322.

1323.

return Write(make_pair(string("setting"), strKey), value);

1324.

1325.

bool LoadWallet(vector<unsigned char>& vchDefaultKeyRet);

1326. };
1327. bool LoadWallet();
1328. inline bool SetAddressBookName(const string& strAddress, const string& strName)
1329. {
1330.

return CWalletDB().WriteName(strAddress, strName);

1331. }
1332. #ifdef _MSC_VER
1333. #pragma warning(disable:4786)
1334. #pragma warning(disable:4804)
1335. #pragma warning(disable:4717)
1336. #endif
1337. #ifdef _WIN32_WINNT
1338. #undef _WIN32_WINNT
1339. #endif
1340. #define _WIN32_WINNT 0x0400
1341. #define WIN32_LEAN_AND_MEAN 1
1342. #include <wx/wx.h>
1343. #include <wx/clipbrd.h>
1344. #include <wx/snglinst.h>
1345. #include <openssl/ecdsa.h>
1346. #include <openssl/evp.h>
1347. #include <openssl/rand.h>
1348. #include <openssl/sha.h>
1349. #include <openssl/ripemd.h>
1350. #include <windows.h>
1351. #include <winsock2.h>
1352. #include <mswsock.h>
1353. #include <stdio.h>
1354. #include <stdlib.h>
1355. #include <io.h>
1356. #include <math.h>
1357. #include <limits.h>
1358. #include <float.h>
1359. #include <assert.h>
1360. #include <process.h>
1361. #include <malloc.h>
1362. #include <memory>
1363. #define BOUNDSCHECK 1
1364. #include <sstream>
1365. #include <string>
1366. #include <vector>
1367. #include <list>
1368. #include <deque>
1369. #include <map>
1370. #include <set>
1371. #include <algorithm>
1372. #include <numeric>
1373. #include <boost/foreach.hpp>
1374. #include <boost/lexical_cast.hpp>
1375. #include <boost/tuple/tuple.hpp>
1376. #include <boost/tuple/tuple_comparison.hpp>
1377. #include <boost/tuple/tuple_io.hpp>
1378. #include <boost/array.hpp>
1379. #pragma hdrstop
1380. using namespace std;
1381. using namespace boost;
1382. #include "serialize.h"
1383. #include "uint256.h"
1384. #include "util.h"
1385. #include "key.h"
1386. #include "bignum.h"
1387. #include "base58.h"
1388. #include "script.h"
1389. #include "db.h"
1390. #include "net.h"
1391. #include "irc.h"
1392. #include "main.h"

1393. #include "market.h"


1394. #include "uibase.h"
1395. #include "ui.h"
1396. #include "headers.h"
1397. #pragma pack(1)
1398. struct ircaddr
1399. {
1400.

int ip;

1401.

short port;

1402. };
1403. string EncodeAddress(const CAddress& addr)
1404. {
1405.

struct ircaddr tmp;

1406.

tmp.ip

1407.

tmp.port = addr.port;

1408.
1409.

= addr.ip;

vector<unsigned char> vch(UBEGIN(tmp), UEND(tmp));


return string("u") + EncodeBase58Check(vch);

1410. }
1411. bool DecodeAddress(string str, CAddress& addr)
1412. {
1413.

vector<unsigned char> vch;

1414.

if (!DecodeBase58Check(str.substr(1), vch))

1415.

return false;

1416.

struct ircaddr tmp;

1417.

if (vch.size() != sizeof(tmp))

1418.

return false;

1419.

memcpy(&tmp, &vch[0], sizeof(tmp));

1420.

addr = CAddress(tmp.ip, tmp.port);

1421.

return true;

1422. }
1423. static bool Send(SOCKET hSocket, const char* pszSend)
1424. {
1425.

if (strstr(pszSend, "PONG") != pszSend)

1426.

printf("SENDING: %s\n", pszSend);

1427.

const char* psz = pszSend;

1428.

const char* pszEnd = psz + strlen(psz);

1429.

while (psz < pszEnd)

1430.

1431.

int ret = send(hSocket, psz, pszEnd - psz, 0);

1432.

if (ret < 0)

1433.

return false;

1434.

psz += ret;

1435.

1436.

return true;

1437. }
1438. bool RecvLine(SOCKET hSocket, string& strLine)
1439. {
1440.

strLine = "";

1441.

loop

1442.

1443.

char c;

1444.

int nBytes = recv(hSocket, &c, 1, 0);

1445.

if (nBytes > 0)

1446.

1447.

if (c == '\n')

1448.

continue;

1449.

if (c == '\r')

1450.

return true;

1451.

strLine += c;

1452.

1453.

else if (nBytes <= 0)

1454.

1455.

if (!strLine.empty())

1456.

return true;

1457.

printf("IRC socket closed\n");

1458.

return false;

1459.

1460.

else

1461.

1462.

int nErr = WSAGetLastError();

1463.

if (nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)

1464.

1465.

printf("IRC recv failed: %d\n", nErr);

1466.

return false;

1467.

1468.
1469.

}
}

1470. }
1471. bool RecvLineIRC(SOCKET hSocket, string& strLine)
1472. {
1473.

loop

1474.

1475.

bool fRet = RecvLine(hSocket, strLine);

1476.

if (fRet)

1477.

1478.

if (fShutdown)

1479.

return false;

1480.

vector<string> vWords;

1481.

ParseString(strLine, ' ', vWords);

1482.

if (vWords[0] == "PING")

1483.

1484.

strLine[1] = 'O';

1485.

strLine += '\r';

1486.

Send(hSocket, strLine.c_str());

1487.

continue;

1488.

1489.

1490.
1491.

return fRet;
}

1492. }
1493. bool RecvUntil(SOCKET hSocket, const char* psz1, const char* psz2=NULL, const char* psz3=NULL)
1494. {
1495.

loop

1496.

1497.

string strLine;

1498.

if (!RecvLineIRC(hSocket, strLine))

1499.

return false;

1500.

printf("IRC %s\n", strLine.c_str());

1501.

if (psz1 && strLine.find(psz1) != -1)

1502.

return true;

1503.

if (psz2 && strLine.find(psz2) != -1)

1504.

return true;

1505.

if (psz3 && strLine.find(psz3) != -1)

1506.
1507.

return true;
}

1508. }
1509. bool fRestartIRCSeed = false;
1510. void ThreadIRCSeed(void* parg)
1511. {
1512.

loop

1513.

1514.

struct hostent* phostent = gethostbyname("chat.freenode.net");

1515.

CAddress addrConnect(*(u_long*)phostent->h_addr_list[0], htons(6667));

1516.

SOCKET hSocket;

1517.

if (!ConnectSocket(addrConnect, hSocket))

1518.

1519.

printf("IRC connect failed\n");

1520.

return;

1521.

1522.

if (!RecvUntil(hSocket, "Found your hostname", "using your IP address instead", "Couldn't look up your hostname"))

1523.

1524.

closesocket(hSocket);

1525.

return;

1526.

1527.

string strMyName = EncodeAddress(addrLocalHost);

1528.

if (!addrLocalHost.IsRoutable())

1529.

strMyName = strprintf("x%u", GetRand(1000000000));

1530.

Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str());

1531.

Send(hSocket, strprintf("USER %s 8 * : %s\r", strMyName.c_str(), strMyName.c_str()).c_str());

1532.

if (!RecvUntil(hSocket, " 004 "))

1533.

1534.

closesocket(hSocket);

1535.

return;

1536.

1537.

Sleep(500);

1538.

Send(hSocket, "JOIN #bitcoin\r");

1539.

Send(hSocket, "WHO #bitcoin\r");

1540.

while (!fRestartIRCSeed)

1541.

1542.

string strLine;

1543.

if (fShutdown || !RecvLineIRC(hSocket, strLine))

1544.

1545.

closesocket(hSocket);

1546.

return;

1547.

1548.

if (strLine.empty() || strLine[0] != ':')

1549.

continue;

1550.

printf("IRC %s\n", strLine.c_str());

1551.

vector<string> vWords;

1552.

ParseString(strLine, ' ', vWords);

1553.

if (vWords.size() < 2)

1554.

continue;

1555.

char pszName[10000];

1556.

pszName[0] = '\0';

1557.

if (vWords[1] == "352" && vWords.size() >= 8)

1558.

1559.

strcpy(pszName, vWords[7].c_str());

1560.

printf("GOT WHO: [%s] ", pszName);

1561.

1562.

if (vWords[1] == "JOIN")

1563.

1564.

strcpy(pszName, vWords[0].c_str() + 1);

1565.

if (strchr(pszName, '!'))

1566.

*strchr(pszName, '!') = '\0';

1567.

printf("GOT JOIN: [%s] ", pszName);

1568.

1569.

if (pszName[0] == 'u')

1570.

1571.

CAddress addr;

1572.

if (DecodeAddress(pszName, addr))

1573.

1574.

CAddrDB addrdb;

1575.

if (AddAddress(addrdb, addr))

1576.

printf("new ");

1577.

addr.print();

1578.

1579.

else

1580.

1581.

printf("decode failed\n");

1582.

1583.

1584.

1585.

fRestartIRCSeed = false;

1586.
1587.

closesocket(hSocket);
}

1588. }
1589. #ifdef TEST
1590. int main(int argc, char *argv[])
1591. {
1592.

WSADATA wsadata;

1593.

if (WSAStartup(MAKEWORD(2,2), &wsadata) != NO_ERROR)

1594.

1595.

printf("Error at WSAStartup()\n");

1596.

return false;

1597.

1598.

ThreadIRCSeed(NULL);

1599.

WSACleanup();

1600.

return 0;

1601. }
1602. #endif
1603. extern bool RecvLine(SOCKET hSocket, string& strLine);
1604. extern void ThreadIRCSeed(void* parg);
1605. extern bool fRestartIRCSeed;
1606. class key_error : public std::runtime_error
1607. {
1608. public:
1609.

explicit key_error(const std::string& str) : std::runtime_error(str) {}

1610. };
1611. typedef vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
1612. class CKey
1613. {
1614. protected:
1615.

EC_KEY* pkey;

1616. public:
1617.

CKey()

1618.

1619.

pkey = EC_KEY_new_by_curve_name(NID_secp256k1);

1620.

if (pkey == NULL)

1621.

throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed");

1622.

1623.

CKey(const CKey& b)

1624.

1625.

pkey = EC_KEY_dup(b.pkey);

1626.

if (pkey == NULL)

1627.

throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed");

1628.

1629.

CKey& operator=(const CKey& b)

1630.

1631.

if (!EC_KEY_copy(pkey, b.pkey))

1632.

throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed");

1633.

return (*this);

1634.

1635.

~CKey()

1636.

1637.

EC_KEY_free(pkey);

1638.

1639.

void MakeNewKey()

1640.

1641.

if (!EC_KEY_generate_key(pkey))

1642.

throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed");

1643.

1644.

bool SetPrivKey(const CPrivKey& vchPrivKey)

1645.

1646.

const unsigned char* pbegin = &vchPrivKey[0];

1647.

if (!d2i_ECPrivateKey(&pkey, &pbegin, vchPrivKey.size()))

1648.

return false;

1649.

return true;

1650.

1651.

CPrivKey GetPrivKey() const

1652.

1653.

unsigned int nSize = i2d_ECPrivateKey(pkey, NULL);

1654.

if (!nSize)

1655.

throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey failed");

1656.

CPrivKey vchPrivKey(nSize, 0);

1657.

unsigned char* pbegin = &vchPrivKey[0];

1658.

if (i2d_ECPrivateKey(pkey, &pbegin) != nSize)

1659.

throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey returned unexpected size");

1660.
1661.

return vchPrivKey;
}

1662.
1663.

bool SetPubKey(const vector<unsigned char>& vchPubKey)


{

1664.

const unsigned char* pbegin = &vchPubKey[0];

1665.

if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size()))

1666.

return false;

1667.
1668.

return true;
}

1669.
1670.

vector<unsigned char> GetPubKey() const


{

1671.

unsigned int nSize = i2o_ECPublicKey(pkey, NULL);

1672.

if (!nSize)

1673.

throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed");

1674.

vector<unsigned char> vchPubKey(nSize, 0);

1675.

unsigned char* pbegin = &vchPubKey[0];

1676.

if (i2o_ECPublicKey(pkey, &pbegin) != nSize)

1677.

throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size");

1678.
1679.

return vchPubKey;
}

1680.
1681.

bool Sign(uint256 hash, vector<unsigned char>& vchSig)


{

1682.

vchSig.clear();

1683.

unsigned char pchSig[10000];

1684.

unsigned int nSize = 0;

1685.

if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), pchSig, &nSize, pkey))

1686.

return false;

1687.

vchSig.resize(nSize);

1688.

memcpy(&vchSig[0], pchSig, nSize);

1689.
1690.

return true;
}

1691.
1692.

bool Verify(uint256 hash, const vector<unsigned char>& vchSig)


{

1693.

if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1)

1694.

return false;

1695.
1696.

return true;
}

1697.
1698.

static bool Sign(const CPrivKey& vchPrivKey, uint256 hash, vector<unsigned char>& vchSig)
{

1699.

CKey key;

1700.

if (!key.SetPrivKey(vchPrivKey))

1701.

return false;

1702.
1703.

return key.Sign(hash, vchSig);


}

1704.
1705.

static bool Verify(const vector<unsigned char>& vchPubKey, uint256 hash, const vector<unsigned char>& vchSig)
{

1706.

CKey key;

1707.

if (!key.SetPubKey(vchPubKey))

1708.

return false;

1709.
1710.

return key.Verify(hash, vchSig);


}

1711. };
1712. #include "headers.h"
1713. #include "sha.h"
1714. CCriticalSection cs_main;
1715. map<uint256, CTransaction> mapTransactions;
1716. CCriticalSection cs_mapTransactions;
1717. unsigned int nTransactionsUpdated = 0;
1718. map<COutPoint, CInPoint> mapNextTx;
1719. map<uint256, CBlockIndex*> mapBlockIndex;
1720. const uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f");
1721. CBlockIndex* pindexGenesisBlock = NULL;
1722. int nBestHeight = -1;
1723. uint256 hashBestChain = 0;
1724. CBlockIndex* pindexBest = NULL;

1725. map<uint256, CBlock*> mapOrphanBlocks;


1726. multimap<uint256, CBlock*> mapOrphanBlocksByPrev;
1727. map<uint256, CDataStream*> mapOrphanTransactions;
1728. multimap<uint256, CDataStream*> mapOrphanTransactionsByPrev;
1729. map<uint256, CWalletTx> mapWallet;
1730. vector<pair<uint256, bool> > vWalletUpdated;
1731. CCriticalSection cs_mapWallet;
1732. map<vector<unsigned char>, CPrivKey> mapKeys;
1733. map<uint160, vector<unsigned char> > mapPubKeys;
1734. CCriticalSection cs_mapKeys;
1735. CKey keyUser;
1736. string strSetDataDir;
1737. int nDropMessagesTest = 0;
1738. int fGenerateBitcoins;
1739. int64 nTransactionFee = 0;
1740. CAddress addrIncoming;
1741. bool AddKey(const CKey& key)
1742. {
1743.

CRITICAL_BLOCK(cs_mapKeys)

1744.

1745.

mapKeys[key.GetPubKey()] = key.GetPrivKey();

1746.

mapPubKeys[Hash160(key.GetPubKey())] = key.GetPubKey();

1747.

1748.

return CWalletDB().WriteKey(key.GetPubKey(), key.GetPrivKey());

1749. }
1750. vector<unsigned char> GenerateNewKey()
1751. {
1752.

CKey key;

1753.

key.MakeNewKey();

1754.

if (!AddKey(key))

1755.
1756.

throw runtime_error("GenerateNewKey() : AddKey failed\n");


return key.GetPubKey();

1757. }
1758. bool AddToWallet(const CWalletTx& wtxIn)
1759. {
1760.

uint256 hash = wtxIn.GetHash();

1761.

CRITICAL_BLOCK(cs_mapWallet)

1762.

1763.

pair<map<uint256, CWalletTx>::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn));

1764.

CWalletTx& wtx = (*ret.first).second;

1765.

bool fInsertedNew = ret.second;

1766.

if (fInsertedNew)

1767.

wtx.nTimeReceived = GetAdjustedTime();

1768.

printf("AddToWallet %s %s\n", wtxIn.GetHash().ToString().substr(0,6).c_str(), fInsertedNew ? "new" : "update");

1769.

if (!fInsertedNew)

1770.

1771.

bool fUpdated = false;

1772.

if (wtxIn.hashBlock != 0 && wtxIn.hashBlock != wtx.hashBlock)

1773.

1774.

wtx.hashBlock = wtxIn.hashBlock;

1775.

fUpdated = true;

1776.

1777.

if (wtxIn.nIndex != -1 && (wtxIn.vMerkleBranch != wtx.vMerkleBranch || wtxIn.nIndex != wtx.nIndex))

1778.

1779.

wtx.vMerkleBranch = wtxIn.vMerkleBranch;

1780.

wtx.nIndex = wtxIn.nIndex;

1781.

fUpdated = true;

1782.

1783.

if (wtxIn.fFromMe && wtxIn.fFromMe != wtx.fFromMe)

1784.

1785.

wtx.fFromMe = wtxIn.fFromMe;

1786.

fUpdated = true;

1787.

1788.

if (wtxIn.fSpent && wtxIn.fSpent != wtx.fSpent)

1789.

1790.

wtx.fSpent = wtxIn.fSpent;

1791.

fUpdated = true;

1792.

1793.

if (!fUpdated)

1794.

return true;

1795.

1796.

if (!wtx.WriteToDisk())

1797.

return false;

1798.

vWalletUpdated.push_back(make_pair(hash, fInsertedNew));

1799.

1800.

MainFrameRepaint();

1801.

return true;

1802. }
1803. bool AddToWalletIfMine(const CTransaction& tx, const CBlock* pblock)
1804. {
1805.

if (tx.IsMine() || mapWallet.count(tx.GetHash()))

1806.

1807.

CWalletTx wtx(tx);

1808.

if (pblock)

1809.

wtx.SetMerkleBranch(pblock);

1810.

return AddToWallet(wtx);

1811.

1812.

return true;

1813. }
1814. bool EraseFromWallet(uint256 hash)
1815. {
1816.

CRITICAL_BLOCK(cs_mapWallet)

1817.

1818.

if (mapWallet.erase(hash))

1819.

CWalletDB().EraseTx(hash);

1820.

1821.

return true;

1822. }
1823. void AddOrphanTx(const CDataStream& vMsg)
1824. {
1825.

CTransaction tx;

1826.

CDataStream(vMsg) >> tx;

1827.

uint256 hash = tx.GetHash();

1828.

if (mapOrphanTransactions.count(hash))

1829.

return;

1830.

CDataStream* pvMsg = mapOrphanTransactions[hash] = new CDataStream(vMsg);

1831.

foreach(const CTxIn& txin, tx.vin)

1832.

mapOrphanTransactionsByPrev.insert(make_pair(txin.prevout.hash, pvMsg));

1833. }
1834. void EraseOrphanTx(uint256 hash)
1835. {
1836.

if (!mapOrphanTransactions.count(hash))

1837.

return;

1838.

const CDataStream* pvMsg = mapOrphanTransactions[hash];

1839.

CTransaction tx;

1840.

CDataStream(*pvMsg) >> tx;

1841.

foreach(const CTxIn& txin, tx.vin)

1842.

1843.

for (multimap<uint256, CDataStream*>::iterator mi = mapOrphanTransactionsByPrev.lower_bound(txin.prevout.hash);

1844.

mi != mapOrphanTransactionsByPrev.upper_bound(txin.prevout.hash);)

1845.

1846.

if ((*mi).second == pvMsg)

1847.

mapOrphanTransactionsByPrev.erase(mi++);

1848.

else

1849.

mi++;

1850.

1851.

1852.

delete pvMsg;

1853.

mapOrphanTransactions.erase(hash);

1854. }
1855. bool CTxIn::IsMine() const
1856. {
1857.

CRITICAL_BLOCK(cs_mapWallet)

1858.

1859.

map<uint256, CWalletTx>::iterator mi = mapWallet.find(prevout.hash);

1860.

if (mi != mapWallet.end())

1861.

1862.

const CWalletTx& prev = (*mi).second;

1863.

if (prevout.n < prev.vout.size())

1864.

if (prev.vout[prevout.n].IsMine())

1865.

return true;

1866.

1867.

1868.

return false;

1869. }
1870. int64 CTxIn::GetDebit() const
1871. {
1872.

CRITICAL_BLOCK(cs_mapWallet)

1873.

1874.

map<uint256, CWalletTx>::iterator mi = mapWallet.find(prevout.hash);

1875.

if (mi != mapWallet.end())

1876.

1877.

const CWalletTx& prev = (*mi).second;

1878.

if (prevout.n < prev.vout.size())

1879.

if (prev.vout[prevout.n].IsMine())

1880.

return prev.vout[prevout.n].nValue;

1881.

1882.

1883.

return 0;

1884. }
1885. int64 CWalletTx::GetTxTime() const
1886. {
1887.

if (!fTimeReceivedIsTxTime && hashBlock != 0)

1888.

1889.

map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);

1890.

if (mi != mapBlockIndex.end())

1891.

1892.

CBlockIndex* pindex = (*mi).second;

1893.

if (pindex)

1894.

return pindex->GetMedianTime();

1895.

1896.

1897.

return nTimeReceived;

1898. }
1899. int CMerkleTx::SetMerkleBranch(const CBlock* pblock)
1900. {
1901.

if (fClient)

1902.

1903.

if (hashBlock == 0)

1904.

return 0;

1905.

1906.

else

1907.

1908.

CBlock blockTmp;

1909.

if (pblock == NULL)

1910.

1911.

CTxIndex txindex;

1912.

if (!CTxDB("r").ReadTxIndex(GetHash(), txindex))

1913.

return 0;

1914.

if (!blockTmp.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, true))

1915.

return 0;

1916.

pblock = &blockTmp;

1917.

1918.

hashBlock = pblock->GetHash();

1919.

for (nIndex = 0; nIndex < pblock->vtx.size(); nIndex++)

1920.

if (pblock->vtx[nIndex] == *(CTransaction*)this)

1921.

break;

1922.

if (nIndex == pblock->vtx.size())

1923.

1924.

vMerkleBranch.clear();

1925.

nIndex = -1;

1926.

printf("ERROR: SetMerkleBranch() : couldn't find tx in block\n");

1927.

return 0;

1928.

1929.

vMerkleBranch = pblock->GetMerkleBranch(nIndex);

1930.

1931.

map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);

1932.

if (mi == mapBlockIndex.end())

1933.

return 0;

1934.

CBlockIndex* pindex = (*mi).second;

1935.

if (!pindex || !pindex->IsInMainChain())

1936.
1937.

return 0;
return pindexBest->nHeight - pindex->nHeight + 1;

1938. }
1939. void CWalletTx::AddSupportingTransactions(CTxDB& txdb)
1940. {
1941.

vtxPrev.clear();

1942.

const int COPY_DEPTH = 3;

1943.

if (SetMerkleBranch() < COPY_DEPTH)

1944.

1945.

vector<uint256> vWorkQueue;

1946.

foreach(const CTxIn& txin, vin)

1947.

vWorkQueue.push_back(txin.prevout.hash);

1948.

CRITICAL_BLOCK(cs_mapWallet)

1949.

1950.

map<uint256, const CMerkleTx*> mapWalletPrev;

1951.

set<uint256> setAlreadyDone;

1952.

for (int i = 0; i < vWorkQueue.size(); i++)

1953.

1954.

uint256 hash = vWorkQueue[i];

1955.

if (setAlreadyDone.count(hash))

1956.

continue;

1957.

setAlreadyDone.insert(hash);

1958.

CMerkleTx tx;

1959.

if (mapWallet.count(hash))

1960.

1961.

tx = mapWallet[hash];

1962.

foreach(const CMerkleTx& txWalletPrev, mapWallet[hash].vtxPrev)

1963.

mapWalletPrev[txWalletPrev.GetHash()] = &txWalletPrev;

1964.

1965.

else if (mapWalletPrev.count(hash))

1966.

1967.

tx = *mapWalletPrev[hash];

1968.

1969.

else if (!fClient && txdb.ReadDiskTx(hash, tx))

1970.

1971.

1972.

1973.

else

1974.

1975.

printf("ERROR: AddSupportingTransactions() : unsupported transaction\n");

1976.

continue;

1977.

1978.

int nDepth = tx.SetMerkleBranch();

1979.

vtxPrev.push_back(tx);

1980.

if (nDepth < COPY_DEPTH)

1981.

foreach(const CTxIn& txin, tx.vin)

1982.

vWorkQueue.push_back(txin.prevout.hash);

1983.

1984.

1985.

1986.

reverse(vtxPrev.begin(), vtxPrev.end());

1987. }
1988. bool CTransaction::AcceptTransaction(CTxDB& txdb, bool fCheckInputs, bool* pfMissingInputs)
1989. {
1990.

if (pfMissingInputs)

1991.
1992.

*pfMissingInputs = false;
if (IsCoinBase())

1993.
1994.

return error("AcceptTransaction() : coinbase as individual tx");


if (!CheckTransaction())

1995.

return error("AcceptTransaction() : CheckTransaction failed");

1996.

uint256 hash = GetHash();

1997.

CRITICAL_BLOCK(cs_mapTransactions)

1998.

if (mapTransactions.count(hash))

1999.

return false;

2000.

if (fCheckInputs)

2001.

if (txdb.ContainsTx(hash))

2002.

return false;

2003.

CTransaction* ptxOld = NULL;

2004.

for (int i = 0; i < vin.size(); i++)

2005.

2006.

COutPoint outpoint = vin[i].prevout;

2007.

if (mapNextTx.count(outpoint))

2008.

2009.

if (i != 0)

2010.

return false;

2011.

ptxOld = mapNextTx[outpoint].ptx;

2012.

if (!IsNewerThan(*ptxOld))

2013.

return false;

2014.

for (int i = 0; i < vin.size(); i++)

2015.

2016.

COutPoint outpoint = vin[i].prevout;

2017.

if (!mapNextTx.count(outpoint) || mapNextTx[outpoint].ptx != ptxOld)

2018.

return false;

2019.

2020.

break;

2021.

2022.

2023.

map<uint256, CTxIndex> mapUnused;

2024.

int64 nFees = 0;

2025.

if (fCheckInputs && !ConnectInputs(txdb, mapUnused, CDiskTxPos(1,1,1), 0, nFees, false, false))

2026.

2027.

if (pfMissingInputs)

2028.

*pfMissingInputs = true;

2029.

return error("AcceptTransaction() : ConnectInputs failed %s", hash.ToString().substr(0,6).c_str());

2030.

2031.

CRITICAL_BLOCK(cs_mapTransactions)

2032.

2033.

if (ptxOld)

2034.

2035.

printf("mapTransaction.erase(%s) replacing with new version\n", ptxOld->GetHash().ToString().c_str());

2036.

mapTransactions.erase(ptxOld->GetHash());

2037.

2038.

AddToMemoryPool();

2039.

2040.

if (ptxOld)

2041.

EraseFromWallet(ptxOld->GetHash());

2042.

printf("AcceptTransaction(): accepted %s\n", hash.ToString().substr(0,6).c_str());

2043.

return true;

2044. }
2045. bool CTransaction::AddToMemoryPool()
2046. {
2047.

CRITICAL_BLOCK(cs_mapTransactions)

2048.

2049.

uint256 hash = GetHash();

2050.

mapTransactions[hash] = *this;

2051.

for (int i = 0; i < vin.size(); i++)

2052.

mapNextTx[vin[i].prevout] = CInPoint(&mapTransactions[hash], i);

2053.

nTransactionsUpdated++;

2054.

2055.

return true;

2056. }

2057. bool CTransaction::RemoveFromMemoryPool()


2058. {
2059.

CRITICAL_BLOCK(cs_mapTransactions)

2060.

2061.

foreach(const CTxIn& txin, vin)

2062.

mapNextTx.erase(txin.prevout);

2063.

mapTransactions.erase(GetHash());

2064.

nTransactionsUpdated++;

2065.

2066.

return true;

2067. }
2068. int CMerkleTx::GetDepthInMainChain() const
2069. {
2070.

if (hashBlock == 0 || nIndex == -1)

2071.

return 0;

2072.

map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);

2073.

if (mi == mapBlockIndex.end())

2074.

return 0;

2075.

CBlockIndex* pindex = (*mi).second;

2076.

if (!pindex || !pindex->IsInMainChain())

2077.

return 0;

2078.

if (!fMerkleVerified)

2079.

2080.

if (CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex) != pindex->hashMerkleRoot)

2081.

return 0;

2082.

fMerkleVerified = true;

2083.

2084.

return pindexBest->nHeight - pindex->nHeight + 1;

2085. }
2086. int CMerkleTx::GetBlocksToMaturity() const
2087. {
2088.

if (!IsCoinBase())

2089.
2090.

return 0;
return max(0, (COINBASE_MATURITY+20) - GetDepthInMainChain());

2091. }
2092. bool CMerkleTx::AcceptTransaction(CTxDB& txdb, bool fCheckInputs)
2093. {
2094.

if (fClient)

2095.

2096.

if (!IsInMainChain() && !ClientConnectInputs())

2097.

return false;

2098.

return CTransaction::AcceptTransaction(txdb, false);

2099.

2100.

else

2101.

2102.
2103.

return CTransaction::AcceptTransaction(txdb, fCheckInputs);


}

2104. }
2105. bool CWalletTx::AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs)
2106. {
2107.

CRITICAL_BLOCK(cs_mapTransactions)

2108.

2109.

foreach(CMerkleTx& tx, vtxPrev)

2110.

2111.

if (!tx.IsCoinBase())

2112.

2113.

uint256 hash = tx.GetHash();

2114.

if (!mapTransactions.count(hash) && !txdb.ContainsTx(hash))

2115.

tx.AcceptTransaction(txdb, fCheckInputs);

2116.

2117.

2118.

if (!IsCoinBase())

2119.

return AcceptTransaction(txdb, fCheckInputs);

2120.

2121.

return true;

2122. }
2123. void ReacceptWalletTransactions()
2124. {
2125.

CTxDB txdb("r");

2126.

CRITICAL_BLOCK(cs_mapWallet)

2127.

2128.

foreach(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)

2129.

2130.

CWalletTx& wtx = item.second;

2131.

if (!wtx.IsCoinBase() && !txdb.ContainsTx(wtx.GetHash()))

2132.

wtx.AcceptWalletTransaction(txdb, false);

2133.
2134.

}
}

2135. }
2136. void CWalletTx::RelayWalletTransaction(CTxDB& txdb)
2137. {
2138.

foreach(const CMerkleTx& tx, vtxPrev)

2139.

2140.

if (!tx.IsCoinBase())

2141.

2142.

uint256 hash = tx.GetHash();

2143.

if (!txdb.ContainsTx(hash))

2144.

RelayMessage(CInv(MSG_TX, hash), (CTransaction)tx);

2145.

2146.

2147.

if (!IsCoinBase())

2148.

2149.

uint256 hash = GetHash();

2150.

if (!txdb.ContainsTx(hash))

2151.

2152.

printf("Relaying wtx %s\n", hash.ToString().substr(0,6).c_str());

2153.

RelayMessage(CInv(MSG_TX, hash), (CTransaction)*this);

2154.
2155.

}
}

2156. }
2157. void RelayWalletTransactions()
2158. {
2159.

static int64 nLastTime;

2160.

if (GetTime() - nLastTime < 10 * 60)

2161.

return;

2162.

nLastTime = GetTime();

2163.

printf("RelayWalletTransactions()\n");

2164.

CTxDB txdb("r");

2165.

CRITICAL_BLOCK(cs_mapWallet)

2166.

2167.

multimap<unsigned int, CWalletTx*> mapSorted;

2168.

foreach(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)

2169.

2170.

CWalletTx& wtx = item.second;

2171.

mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx));

2172.

2173.

foreach(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted)

2174.

2175.

CWalletTx& wtx = *item.second;

2176.

wtx.RelayWalletTransaction(txdb);

2177.
2178.

}
}

2179. }
2180. bool CBlock::ReadFromDisk(const CBlockIndex* pblockindex, bool fReadTransactions)
2181. {
2182.

return ReadFromDisk(pblockindex->nFile, pblockindex->nBlockPos, fReadTransactions);

2183. }
2184. uint256 GetOrphanRoot(const CBlock* pblock)
2185. {
2186.
2187.
2188.

while (mapOrphanBlocks.count(pblock->hashPrevBlock))
pblock = mapOrphanBlocks[pblock->hashPrevBlock];
return pblock->GetHash();

2189. }
2190. int64 CBlock::GetBlockValue(int64 nFees) const
2191. {
2192.

int64 nSubsidy = 50 * COIN;

2193.

nSubsidy >>= (nBestHeight / 210000);

2194.

return nSubsidy + nFees;

2195. }
2196. unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast)
2197. {
2198.

const unsigned int nTargetTimespan = 14 * 24 * 60 * 60;

2199.

const unsigned int nTargetSpacing = 10 * 60;

2200.

const unsigned int nInterval = nTargetTimespan / nTargetSpacing;

2201.

if (pindexLast == NULL)

2202.

return bnProofOfWorkLimit.GetCompact();

2203.

if ((pindexLast->nHeight+1) % nInterval != 0)

2204.

return pindexLast->nBits;

2205.

const CBlockIndex* pindexFirst = pindexLast;

2206.

for (int i = 0; pindexFirst && i < nInterval-1; i++)

2207.

pindexFirst = pindexFirst->pprev;

2208.

assert(pindexFirst);

2209.

unsigned int nActualTimespan = pindexLast->nTime - pindexFirst->nTime;

2210.

printf(" nActualTimespan = %d before bounds\n", nActualTimespan);

2211.

if (nActualTimespan < nTargetTimespan/4)

2212.
2213.
2214.

nActualTimespan = nTargetTimespan/4;
if (nActualTimespan > nTargetTimespan*4)
nActualTimespan = nTargetTimespan*4;

2215.

CBigNum bnNew;

2216.

bnNew.SetCompact(pindexLast->nBits);

2217.

bnNew *= nActualTimespan;

2218.

bnNew /= nTargetTimespan;

2219.

if (bnNew > bnProofOfWorkLimit)

2220.

bnNew = bnProofOfWorkLimit;

2221.

printf("\n\n\nGetNextWorkRequired RETARGET *****\n");

2222.

printf("nTargetTimespan = %d

nActualTimespan = %d\n", nTargetTimespan, nActualTimespan);

2223.

printf("Before: %08x %s\n", pindexLast->nBits, CBigNum().SetCompact(pindexLast->nBits).getuint256().ToString().c_str());

2224.

printf("After: %08x %s\n", bnNew.GetCompact(), bnNew.getuint256().ToString().c_str());

2225.

return bnNew.GetCompact();

2226. }
2227. bool CTransaction::DisconnectInputs(CTxDB& txdb)
2228. {
2229.

if (!IsCoinBase())

2230.

2231.

foreach(const CTxIn& txin, vin)

2232.

2233.

COutPoint prevout = txin.prevout;

2234.

CTxIndex txindex;

2235.

if (!txdb.ReadTxIndex(prevout.hash, txindex))

2236.

return error("DisconnectInputs() : ReadTxIndex failed");

2237.

if (prevout.n >= txindex.vSpent.size())

2238.

return error("DisconnectInputs() : prevout.n out of range");

2239.

txindex.vSpent[prevout.n].SetNull();

2240.

txdb.UpdateTxIndex(prevout.hash, txindex);

2241.

2242.

2243.

if (!txdb.EraseTxIndex(*this))

2244.

return error("DisconnectInputs() : EraseTxPos failed");

2245.

return true;

2246. }
2247. bool CTransaction::ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPool, CDiskTxPos posThisTx, int nHeight, int64& nFees, bool
fBlock, bool fMiner, int64 nMinFee)
2248. {
2249.

if (!IsCoinBase())

2250.

2251.

int64 nValueIn = 0;

2252.

for (int i = 0; i < vin.size(); i++)

2253.

2254.

COutPoint prevout = vin[i].prevout;

2255.

CTxIndex txindex;

2256.

bool fFound = true;

2257.

if (fMiner && mapTestPool.count(prevout.hash))

2258.

2259.

txindex = mapTestPool[prevout.hash];

2260.

2261.

else

2262.

2263.

fFound = txdb.ReadTxIndex(prevout.hash, txindex);

2264.

2265.

if (!fFound && (fBlock || fMiner))

2266.

return fMiner ? false : error("ConnectInputs() : %s prev tx %s index entry not found", GetHash().ToString().substr(0,6).c_str(),
prevout.hash.ToString().substr(0,6).c_str());

2267.

CTransaction txPrev;

2268.

if (!fFound || txindex.pos == CDiskTxPos(1,1,1))

2269.

2270.

CRITICAL_BLOCK(cs_mapTransactions)

2271.

2272.

if (!mapTransactions.count(prevout.hash))

2273.

return error("ConnectInputs() : %s mapTransactions prev not found %s", GetHash().ToString().substr(0,6).c_str(),


prevout.hash.ToString().substr(0,6).c_str());

2274.

txPrev = mapTransactions[prevout.hash];

2275.

2276.

if (!fFound)

2277.

txindex.vSpent.resize(txPrev.vout.size());

2278.

2279.

else

2280.

2281.

if (!txPrev.ReadFromDisk(txindex.pos))

2282.

return error("ConnectInputs() : %s ReadFromDisk prev tx %s failed", GetHash().ToString().substr(0,6).c_str(),


prevout.hash.ToString().substr(0,6).c_str());

2283.

2284.

if (prevout.n >= txPrev.vout.size() || prevout.n >= txindex.vSpent.size())

2285.

return error("ConnectInputs() : %s prevout.n out of range %d %d %d", GetHash().ToString().substr(0,6).c_str(), prevout.n, txPrev.vout.size(),


txindex.vSpent.size());

2286.
2287.
2288.
2289.
2290.
2291.
2292.
2293.

if (txPrev.IsCoinBase())
for (CBlockIndex* pindex = pindexBest; pindex && nBestHeight - pindex->nHeight < COINBASE_MATURITY-1; pindex = pindex->pprev)
if (pindex->nBlockPos == txindex.pos.nBlockPos && pindex->nFile == txindex.pos.nFile)
return error("ConnectInputs() : tried to spend coinbase at depth %d", nBestHeight - pindex->nHeight);
if (!VerifySignature(txPrev, *this, i))
return error("ConnectInputs() : %s VerifySignature failed", GetHash().ToString().substr(0,6).c_str());
if (!txindex.vSpent[prevout.n].IsNull())
return fMiner ? false : error("ConnectInputs() : %s prev tx already used at %s", GetHash().ToString().substr(0,6).c_str(),
txindex.vSpent[prevout.n].ToString().c_str());

2294.

txindex.vSpent[prevout.n] = posThisTx;

2295.

if (fBlock)

2296.
2297.

txdb.UpdateTxIndex(prevout.hash, txindex);
else if (fMiner)

2298.

mapTestPool[prevout.hash] = txindex;

2299.

nValueIn += txPrev.vout[prevout.n].nValue;

2300.

2301.

int64 nTxFee = nValueIn - GetValueOut();

2302.

if (nTxFee < 0)

2303.

return error("ConnectInputs() : %s nTxFee < 0", GetHash().ToString().substr(0,6).c_str());

2304.

if (nTxFee < nMinFee)

2305.

return false;

2306.

nFees += nTxFee;

2307.

2308.

if (fBlock)

2309.

2310.

if (!txdb.AddTxIndex(*this, posThisTx, nHeight))

2311.

return error("ConnectInputs() : AddTxPos failed");

2312.

2313.

else if (fMiner)

2314.

2315.

mapTestPool[GetHash()] = CTxIndex(CDiskTxPos(1,1,1), vout.size());

2316.

2317.

return true;

2318. }
2319. bool CTransaction::ClientConnectInputs()
2320. {
2321.

if (IsCoinBase())

2322.

return false;

2323.

CRITICAL_BLOCK(cs_mapTransactions)

2324.

2325.

int64 nValueIn = 0;

2326.

for (int i = 0; i < vin.size(); i++)

2327.

2328.

COutPoint prevout = vin[i].prevout;

2329.

if (!mapTransactions.count(prevout.hash))

2330.

return false;

2331.

CTransaction& txPrev = mapTransactions[prevout.hash];

2332.

if (prevout.n >= txPrev.vout.size())

2333.

return false;

2334.

if (!VerifySignature(txPrev, *this, i))

2335.

return error("ConnectInputs() : VerifySignature failed");

2336.

nValueIn += txPrev.vout[prevout.n].nValue;

2337.

2338.

if (GetValueOut() > nValueIn)

2339.

return false;

2340.

2341.

return true;

2342. }
2343. bool CBlock::DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex)
2344. {
2345.

for (int i = vtx.size()-1; i >= 0; i--)

2346.

if (!vtx[i].DisconnectInputs(txdb))

2347.

return false;

2348.

if (pindex->pprev)

2349.

2350.

CDiskBlockIndex blockindexPrev(pindex->pprev);

2351.

blockindexPrev.hashNext = 0;

2352.

txdb.WriteBlockIndex(blockindexPrev);

2353.

2354.

return true;

2355. }
2356. bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex)
2357. {
2358.

unsigned int nTxPos = pindex->nBlockPos + ::GetSerializeSize(CBlock(), SER_DISK) - 1 + GetSizeOfCompactSize(vtx.size());

2359.

map<uint256, CTxIndex> mapUnused;

2360.

int64 nFees = 0;

2361.

foreach(CTransaction& tx, vtx)

2362.

2363.

CDiskTxPos posThisTx(pindex->nFile, pindex->nBlockPos, nTxPos);

2364.

nTxPos += ::GetSerializeSize(tx, SER_DISK);

2365.

if (!tx.ConnectInputs(txdb, mapUnused, posThisTx, pindex->nHeight, nFees, true, false))

2366.

return false;

2367.

2368.

if (vtx[0].GetValueOut() > GetBlockValue(nFees))

2369.

return false;

2370.

if (pindex->pprev)

2371.

2372.

CDiskBlockIndex blockindexPrev(pindex->pprev);

2373.

blockindexPrev.hashNext = pindex->GetBlockHash();

2374.

txdb.WriteBlockIndex(blockindexPrev);

2375.

2376.

foreach(CTransaction& tx, vtx)

2377.
2378.

AddToWalletIfMine(tx, this);
return true;

2379. }
2380. bool Reorganize(CTxDB& txdb, CBlockIndex* pindexNew)
2381. {
2382.

printf("*** REORGANIZE ***\n");

2383.

CBlockIndex* pfork = pindexBest;

2384.

CBlockIndex* plonger = pindexNew;

2385.

while (pfork != plonger)

2386.

2387.

if (!(pfork = pfork->pprev))

2388.

return error("Reorganize() : pfork->pprev is null");

2389.

while (plonger->nHeight > pfork->nHeight)

2390.

if (!(plonger = plonger->pprev))

2391.

return error("Reorganize() : plonger->pprev is null");

2392.

2393.

vector<CBlockIndex*> vDisconnect;

2394.

for (CBlockIndex* pindex = pindexBest; pindex != pfork; pindex = pindex->pprev)

2395.

vDisconnect.push_back(pindex);

2396.

vector<CBlockIndex*> vConnect;

2397.

for (CBlockIndex* pindex = pindexNew; pindex != pfork; pindex = pindex->pprev)

2398.

vConnect.push_back(pindex);

2399.

reverse(vConnect.begin(), vConnect.end());

2400.

vector<CTransaction> vResurrect;

2401.

foreach(CBlockIndex* pindex, vDisconnect)

2402.

2403.

CBlock block;

2404.

if (!block.ReadFromDisk(pindex->nFile, pindex->nBlockPos, true))

2405.

return error("Reorganize() : ReadFromDisk for disconnect failed");

2406.

if (!block.DisconnectBlock(txdb, pindex))

2407.

return error("Reorganize() : DisconnectBlock failed");

2408.

foreach(const CTransaction& tx, block.vtx)

2409.

if (!tx.IsCoinBase())

2410.

vResurrect.push_back(tx);

2411.

2412.

vector<CTransaction> vDelete;

2413.

for (int i = 0; i < vConnect.size(); i++)

2414.

2415.

CBlockIndex* pindex = vConnect[i];

2416.

CBlock block;

2417.

if (!block.ReadFromDisk(pindex->nFile, pindex->nBlockPos, true))

2418.

return error("Reorganize() : ReadFromDisk for connect failed");

2419.

if (!block.ConnectBlock(txdb, pindex))

2420.

2421.

txdb.TxnAbort();

2422.

for (int j = i; j < vConnect.size(); j++)

2423.

2424.

CBlockIndex* pindex = vConnect[j];

2425.

pindex->EraseBlockFromDisk();

2426.

txdb.EraseBlockIndex(pindex->GetBlockHash());

2427.

mapBlockIndex.erase(pindex->GetBlockHash());

2428.

delete pindex;

2429.

2430.

return error("Reorganize() : ConnectBlock failed");

2431.

2432.

foreach(const CTransaction& tx, block.vtx)

2433.

vDelete.push_back(tx);

2434.

2435.

if (!txdb.WriteHashBestChain(pindexNew->GetBlockHash()))

2436.

return error("Reorganize() : WriteHashBestChain failed");

2437.

txdb.TxnCommit();

2438.

foreach(CBlockIndex* pindex, vDisconnect)

2439.

if (pindex->pprev)

2440.

pindex->pprev->pnext = NULL;

2441.

foreach(CBlockIndex* pindex, vConnect)

2442.

if (pindex->pprev)

2443.
2444.

pindex->pprev->pnext = pindex;
foreach(CTransaction& tx, vResurrect)

2445.

tx.AcceptTransaction(txdb, false);

2446.

foreach(CTransaction& tx, vDelete)

2447.
2448.

tx.RemoveFromMemoryPool();
return true;

2449. }
2450. bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
2451. {
2452.

uint256 hash = GetHash();

2453.

if (mapBlockIndex.count(hash))

2454.

return error("AddToBlockIndex() : %s already exists", hash.ToString().substr(0,14).c_str());

2455.

CBlockIndex* pindexNew = new CBlockIndex(nFile, nBlockPos, *this);

2456.

if (!pindexNew)

2457.

return error("AddToBlockIndex() : new CBlockIndex failed");

2458.

map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;

2459.

pindexNew->phashBlock = &((*mi).first);

2460.

map<uint256, CBlockIndex*>::iterator miPrev = mapBlockIndex.find(hashPrevBlock);

2461.

if (miPrev != mapBlockIndex.end())

2462.

2463.

pindexNew->pprev = (*miPrev).second;

2464.
2465.

pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
}

2466.

CTxDB txdb;

2467.

txdb.TxnBegin();

2468.

txdb.WriteBlockIndex(CDiskBlockIndex(pindexNew));

2469.

if (pindexNew->nHeight > nBestHeight)

2470.

2471.

if (pindexGenesisBlock == NULL && hash == hashGenesisBlock)

2472.

2473.

pindexGenesisBlock = pindexNew;

2474.

txdb.WriteHashBestChain(hash);

2475.

2476.

else if (hashPrevBlock == hashBestChain)

2477.

2478.

if (!ConnectBlock(txdb, pindexNew) || !txdb.WriteHashBestChain(hash))

2479.

2480.

txdb.TxnAbort();

2481.

pindexNew->EraseBlockFromDisk();

2482.

mapBlockIndex.erase(pindexNew->GetBlockHash());

2483.

delete pindexNew;

2484.

return error("AddToBlockIndex() : ConnectBlock failed");

2485.

2486.

txdb.TxnCommit();

2487.

pindexNew->pprev->pnext = pindexNew;

2488.

foreach(CTransaction& tx, vtx)

2489.

tx.RemoveFromMemoryPool();

2490.

2491.

else

2492.

2493.

if (!Reorganize(txdb, pindexNew))

2494.

2495.

txdb.TxnAbort();

2496.

return error("AddToBlockIndex() : Reorganize failed");

2497.

2498.

2499.

hashBestChain = hash;

2500.

pindexBest = pindexNew;

2501.

nBestHeight = pindexBest->nHeight;

2502.

nTransactionsUpdated++;

2503.

printf("AddToBlockIndex: new best=%s height=%d\n", hashBestChain.ToString().substr(0,14).c_str(), nBestHeight);

2504.

2505.

txdb.TxnCommit();

2506.

txdb.Close();

2507.

if (pindexNew == pindexBest)

2508.

RelayWalletTransactions();

2509.

MainFrameRepaint();

2510.

return true;

2511. }
2512. bool CBlock::CheckBlock() const
2513. {
2514.
2515.
2516.
2517.
2518.
2519.
2520.
2521.
2522.
2523.
2524.
2525.
2526.

if (vtx.empty() || vtx.size() > MAX_SIZE || ::GetSerializeSize(*this, SER_DISK) > MAX_SIZE)


return error("CheckBlock() : size limits failed");
if (nTime > GetAdjustedTime() + 2 * 60 * 60)
return error("CheckBlock() : block timestamp too far in the future");
if (vtx.empty() || !vtx[0].IsCoinBase())
return error("CheckBlock() : first tx is not coinbase");
for (int i = 1; i < vtx.size(); i++)
if (vtx[i].IsCoinBase())
return error("CheckBlock() : more than one coinbase");
foreach(const CTransaction& tx, vtx)
if (!tx.CheckTransaction())
return error("CheckBlock() : CheckTransaction failed");
if (CBigNum().SetCompact(nBits) > bnProofOfWorkLimit)

2527.

return error("CheckBlock() : nBits below minimum work");

2528.

if (GetHash() > CBigNum().SetCompact(nBits).getuint256())

2529.
2530.
2531.
2532.

return error("CheckBlock() : hash doesn't match nBits");


if (hashMerkleRoot != BuildMerkleTree())
return error("CheckBlock() : hashMerkleRoot mismatch");
return true;

2533. }
2534. bool CBlock::AcceptBlock()
2535. {
2536.

uint256 hash = GetHash();

2537.

if (mapBlockIndex.count(hash))

2538.

return error("AcceptBlock() : block already in mapBlockIndex");

2539.

map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashPrevBlock);

2540.

if (mi == mapBlockIndex.end())

2541.

return error("AcceptBlock() : prev block not found");

2542.

CBlockIndex* pindexPrev = (*mi).second;

2543.

if (nTime <= pindexPrev->GetMedianTimePast())

2544.
2545.
2546.

return error("AcceptBlock() : block's timestamp is too early");


if (nBits != GetNextWorkRequired(pindexPrev))
return error("AcceptBlock() : incorrect proof of work");

2547.

unsigned int nFile;

2548.

unsigned int nBlockPos;

2549.

if (!WriteToDisk(!fClient, nFile, nBlockPos))

2550.
2551.

return error("AcceptBlock() : WriteToDisk failed");


if (!AddToBlockIndex(nFile, nBlockPos))

2552.
2553.

return error("AcceptBlock() : AddToBlockIndex failed");


if (hashBestChain == hash)

2554.
2555.

RelayInventory(CInv(MSG_BLOCK, hash));
return true;

2556. }
2557. bool ProcessBlock(CNode* pfrom, CBlock* pblock)
2558. {
2559.

uint256 hash = pblock->GetHash();

2560.

if (mapBlockIndex.count(hash))

2561.
2562.

return error("ProcessBlock() : already have block %d %s", mapBlockIndex[hash]->nHeight, hash.ToString().substr(0,14).c_str());


if (mapOrphanBlocks.count(hash))

2563.

return error("ProcessBlock() : already have block (orphan) %s", hash.ToString().substr(0,14).c_str());

2564.

if (!pblock->CheckBlock())

2565.

2566.

delete pblock;

2567.

return error("ProcessBlock() : CheckBlock FAILED");

2568.

2569.

if (!mapBlockIndex.count(pblock->hashPrevBlock))

2570.

2571.

printf("ProcessBlock: ORPHAN BLOCK, prev=%s\n", pblock->hashPrevBlock.ToString().substr(0,14).c_str());

2572.

mapOrphanBlocks.insert(make_pair(hash, pblock));

2573.

mapOrphanBlocksByPrev.insert(make_pair(pblock->hashPrevBlock, pblock));

2574.

if (pfrom)

2575.

pfrom->PushMessage("getblocks", CBlockLocator(pindexBest), GetOrphanRoot(pblock));

2576.

return true;

2577.

2578.

if (!pblock->AcceptBlock())

2579.

2580.

delete pblock;

2581.

return error("ProcessBlock() : AcceptBlock FAILED");

2582.

2583.

delete pblock;

2584.

vector<uint256> vWorkQueue;

2585.

vWorkQueue.push_back(hash);

2586.

for (int i = 0; i < vWorkQueue.size(); i++)

2587.

2588.

uint256 hashPrev = vWorkQueue[i];

2589.

for (multimap<uint256, CBlock*>::iterator mi = mapOrphanBlocksByPrev.lower_bound(hashPrev);

2590.

mi != mapOrphanBlocksByPrev.upper_bound(hashPrev);

2591.

++mi)

2592.

2593.

CBlock* pblockOrphan = (*mi).second;

2594.

if (pblockOrphan->AcceptBlock())

2595.

vWorkQueue.push_back(pblockOrphan->GetHash());

2596.

mapOrphanBlocks.erase(pblockOrphan->GetHash());

2597.

delete pblockOrphan;

2598.

2599.

mapOrphanBlocksByPrev.erase(hashPrev);

2600.

2601.

printf("ProcessBlock: ACCEPTED\n");

2602.

return true;

2603. }
2604. template<typename Stream>
2605. bool ScanMessageStart(Stream& s)
2606. {
2607.

s.clear(0);

2608.

short prevmask = s.exceptions(0);

2609.

const char* p = BEGIN(pchMessageStart);

2610.

try

2611.

2612.

loop

2613.

2614.

char c;

2615.

s.read(&c, 1);

2616.

if (s.fail())

2617.

2618.

s.clear(0);

2619.

s.exceptions(prevmask);

2620.

return false;

2621.

2622.

if (*p != c)

2623.

p = BEGIN(pchMessageStart);

2624.

if (*p == c)

2625.

2626.

if (++p == END(pchMessageStart))

2627.

2628.

s.clear(0);

2629.

s.exceptions(prevmask);

2630.
2631.

return true;
}

2632.

2633.

2634.

2635.

catch (...)

2636.

2637.

s.clear(0);

2638.

s.exceptions(prevmask);

2639.
2640.

return false;
}

2641. }
2642. string GetAppDir()
2643. {
2644.

string strDir;

2645.

if (!strSetDataDir.empty())

2646.

2647.

strDir = strSetDataDir;

2648.

2649.

else if (getenv("APPDATA"))

2650.

2651.

strDir = strprintf("%s\\Bitcoin", getenv("APPDATA"));

2652.

2653.

else if (getenv("USERPROFILE"))

2654.

2655.

string strAppData = strprintf("%s\\Application Data", getenv("USERPROFILE"));

2656.

static bool fMkdirDone;

2657.

if (!fMkdirDone)

2658.

2659.

fMkdirDone = true;

2660.

_mkdir(strAppData.c_str());

2661.

2662.

strDir = strprintf("%s\\Bitcoin", strAppData.c_str());

2663.

2664.

else

2665.

2666.

return ".";

2667.

2668.

static bool fMkdirDone;

2669.

if (!fMkdirDone)

2670.

2671.

fMkdirDone = true;

2672.

_mkdir(strDir.c_str());

2673.

2674.

return strDir;

2675. }
2676. FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode)
2677. {
2678.

if (nFile == -1)

2679.

return NULL;

2680.

FILE* file = fopen(strprintf("%s\\blk%04d.dat", GetAppDir().c_str(), nFile).c_str(), pszMode);

2681.

if (!file)

2682.

return NULL;

2683.

if (nBlockPos != 0 && !strchr(pszMode, 'a') && !strchr(pszMode, 'w'))

2684.

2685.

if (fseek(file, nBlockPos, SEEK_SET) != 0)

2686.

2687.

fclose(file);

2688.

return NULL;

2689.

2690.

2691.

return file;

2692. }
2693. static unsigned int nCurrentBlockFile = 1;
2694. FILE* AppendBlockFile(unsigned int& nFileRet)
2695. {
2696.

nFileRet = 0;

2697.

loop

2698.

2699.

FILE* file = OpenBlockFile(nCurrentBlockFile, 0, "ab");

2700.

if (!file)

2701.

return NULL;

2702.

if (fseek(file, 0, SEEK_END) != 0)

2703.

return NULL;

2704.

if (ftell(file) < 0x7F000000 - MAX_SIZE)

2705.

2706.

nFileRet = nCurrentBlockFile;

2707.

return file;

2708.

2709.

fclose(file);

2710.
2711.

nCurrentBlockFile++;
}

2712. }
2713. bool LoadBlockIndex(bool fAllowNew)
2714. {

2715.

CTxDB txdb("cr");

2716.

if (!txdb.LoadBlockIndex())

2717.

return false;

2718.

txdb.Close();

2719.

if (mapBlockIndex.empty())

2720.

2721.

if (!fAllowNew)

2722.

return false;

2723.

char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks";

2724.

CTransaction txNew;

2725.

txNew.vin.resize(1);

2726.

txNew.vout.resize(1);

2727.

txNew.vin[0].scriptSig

= CScript() << 486604799 << CBigNum(4) << vector<unsigned char>((unsigned char*)pszTimestamp, (unsigned

char*)pszTimestamp + strlen(pszTimestamp));
2728.

txNew.vout[0].nValue

2729.

txNew.vout[0].scriptPubKey = CScript() <<

= 50 * COIN;

CBigNum("0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704"
<< OP_CHECKSIG;
2730.

CBlock block;

2731.

block.vtx.push_back(txNew);

2732.

block.hashPrevBlock = 0;

2733.

block.hashMerkleRoot = block.BuildMerkleTree();

2734.

block.nVersion = 1;

2735.

block.nTime

2736.

block.nBits

2737.

block.nNonce = 2083236893;

= 1231006505;
= 0x1d00ffff;

2738.

printf("%s\n", block.GetHash().ToString().c_str());

2739.

printf("%s\n", block.hashMerkleRoot.ToString().c_str());

2740.

printf("%s\n", hashGenesisBlock.ToString().c_str());

2741.

txNew.vout[0].scriptPubKey.print();

2742.

block.print();

2743.

assert(block.hashMerkleRoot == uint256("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));

2744.

assert(block.GetHash() == hashGenesisBlock);

2745.

unsigned int nFile;

2746.

unsigned int nBlockPos;

2747.

if (!block.WriteToDisk(!fClient, nFile, nBlockPos))

2748.

return error("LoadBlockIndex() : writing genesis block to disk failed");

2749.

if (!block.AddToBlockIndex(nFile, nBlockPos))

2750.

return error("LoadBlockIndex() : genesis block not accepted");

2751.

2752.

return true;

2753. }
2754. void PrintBlockTree()
2755. {
2756.

map<CBlockIndex*, vector<CBlockIndex*> > mapNext;

2757.

for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi)

2758.

2759.

CBlockIndex* pindex = (*mi).second;

2760.

mapNext[pindex->pprev].push_back(pindex);

2761.

2762.

vector<pair<int, CBlockIndex*> > vStack;

2763.

vStack.push_back(make_pair(0, pindexGenesisBlock));

2764.

int nPrevCol = 0;

2765.

while (!vStack.empty())

2766.

2767.

int nCol = vStack.back().first;

2768.

CBlockIndex* pindex = vStack.back().second;

2769.

vStack.pop_back();

2770.

if (nCol > nPrevCol)

2771.

2772.

for (int i = 0; i < nCol-1; i++)

2773.

printf("| ");

2774.

printf("|\\\n");

2775.

2776.

else if (nCol < nPrevCol)

2777.

2778.

for (int i = 0; i < nCol; i++)

2779.

printf("| ");

2780.

printf("|\n");

2781.

2782.

nPrevCol = nCol;

2783.

for (int i = 0; i < nCol; i++)

2784.

printf("| ");

2785.

CBlock block;

2786.

block.ReadFromDisk(pindex, true);

2787.

printf("%d (%u,%u) %s %s tx %d",

2788.

pindex->nHeight,

2789.

pindex->nFile,

2790.

pindex->nBlockPos,

2791.

block.GetHash().ToString().substr(0,14).c_str(),

2792.

DateTimeStr(block.nTime).c_str(),

2793.
2794.

block.vtx.size());
CRITICAL_BLOCK(cs_mapWallet)

2795.

2796.

if (mapWallet.count(block.vtx[0].GetHash()))

2797.

2798.

CWalletTx& wtx = mapWallet[block.vtx[0].GetHash()];

2799.

printf(" mine: %d %d %d", wtx.GetDepthInMainChain(), wtx.GetBlocksToMaturity(), wtx.GetCredit());

2800.

2801.

2802.

printf("\n");

2803.

vector<CBlockIndex*>& vNext = mapNext[pindex];

2804.

for (int i = 0; i < vNext.size(); i++)

2805.

2806.

if (vNext[i]->pnext)

2807.

2808.

swap(vNext[0], vNext[i]);

2809.

break;

2810.

2811.

2812.

for (int i = 0; i < vNext.size(); i++)

2813.

vStack.push_back(make_pair(nCol+i, vNext[i]));

2814.

2815. }bool AlreadyHave(CTxDB& txdb, const CInv& inv)


2816. {
2817.

switch (inv.type)

2818.

2819.

case MSG_TX:

2820.

case MSG_BLOCK:

2821.

case MSG_REVIEW: return true;

2822.

case MSG_PRODUCT: return mapProducts.count(inv.hash);

2823.

2824.

return true;

return mapTransactions.count(inv.hash) || txdb.ContainsTx(inv.hash);


return mapBlockIndex.count(inv.hash) || mapOrphanBlocks.count(inv.hash);

2825. }
2826. bool ProcessMessages(CNode* pfrom)
2827. {
2828.

CDataStream& vRecv = pfrom->vRecv;

2829.

if (vRecv.empty())

2830.

return true;

2831.

printf("ProcessMessages(%d bytes)\n", vRecv.size());

2832.

loop

2833.

2834.

CDataStream::iterator pstart = search(vRecv.begin(), vRecv.end(), BEGIN(pchMessageStart), END(pchMessageStart));

2835.

if (vRecv.end() - pstart < sizeof(CMessageHeader))

2836.

2837.

if (vRecv.size() > sizeof(CMessageHeader))

2838.

2839.

printf("\n\nPROCESSMESSAGE MESSAGESTART NOT FOUND\n\n");

2840.

vRecv.erase(vRecv.begin(), vRecv.end() - sizeof(CMessageHeader));

2841.

2842.

break;

2843.

2844.

if (pstart - vRecv.begin() > 0)

2845.

printf("\n\nPROCESSMESSAGE SKIPPED %d BYTES\n\n", pstart - vRecv.begin());

2846.

vRecv.erase(vRecv.begin(), pstart);

2847.

CMessageHeader hdr;

2848.

vRecv >> hdr;

2849.

if (!hdr.IsValid())

2850.

2851.

printf("\n\nPROCESSMESSAGE: ERRORS IN HEADER %s\n\n\n", hdr.GetCommand().c_str());

2852.

continue;

2853.

2854.

string strCommand = hdr.GetCommand();

2855.

unsigned int nMessageSize = hdr.nMessageSize;

2856.

if (nMessageSize > vRecv.size())

2857.

2858.

printf("MESSAGE-BREAK 2\n");

2859.

vRecv.insert(vRecv.begin(), BEGIN(hdr), END(hdr));

2860.

Sleep(100);

2861.

break;

2862.

2863.

CDataStream vMsg(vRecv.begin(), vRecv.begin() + nMessageSize, vRecv.nType, vRecv.nVersion);

2864.

vRecv.ignore(nMessageSize);

2865.

bool fRet = false;

2866.

try

2867.

2868.

CheckForShutdown(2);

2869.

CRITICAL_BLOCK(cs_main)

2870.

fRet = ProcessMessage(pfrom, strCommand, vMsg);

2871.

CheckForShutdown(2);

2872.

2873.

CATCH_PRINT_EXCEPTION("ProcessMessage()")

2874.

if (!fRet)

2875.

printf("ProcessMessage(%s, %d bytes) from %s to %s FAILED\n", strCommand.c_str(), nMessageSize, pfrom->addr.ToString().c_str(),


addrLocalHost.ToString().c_str());

2876.

2877.

vRecv.Compact();

2878.

return true;

2879. }
2880. bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
2881. {
2882.

static map<unsigned int, vector<unsigned char> > mapReuseKey;

2883.

printf("received: %-12s (%d bytes) ", strCommand.c_str(), vRecv.size());

2884.

for (int i = 0; i < min(vRecv.size(), (unsigned int)25); i++)

2885.

printf("%02x ", vRecv[i] & 0xff);

2886.

printf("\n");

2887.

if (nDropMessagesTest > 0 && GetRand(nDropMessagesTest) == 0)

2888.

2889.

printf("dropmessages DROPPING RECV MESSAGE\n");

2890.

return true;

2891.

2892.

if (strCommand == "version")

2893.

2894.

if (pfrom->nVersion != 0)

2895.

return false;

2896.

int64 nTime;

2897.

CAddress addrMe;

2898.

vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe;

2899.

if (pfrom->nVersion == 0)

2900.

return false;

2901.

pfrom->vSend.SetVersion(min(pfrom->nVersion, VERSION));

2902.

pfrom->vRecv.SetVersion(min(pfrom->nVersion, VERSION));

2903.

pfrom->fClient = !(pfrom->nServices & NODE_NETWORK);

2904.

if (pfrom->fClient)

2905.

2906.

pfrom->vSend.nType |= SER_BLOCKHEADERONLY;

2907.

pfrom->vRecv.nType |= SER_BLOCKHEADERONLY;

2908.

2909.

AddTimeData(pfrom->addr.ip, nTime);

2910.

static bool fAskedForBlocks;

2911.

if (!fAskedForBlocks && !pfrom->fClient)

2912.

2913.

fAskedForBlocks = true;

2914.

pfrom->PushMessage("getblocks", CBlockLocator(pindexBest), uint256(0));

2915.

2916.

printf("version addrMe = %s\n", addrMe.ToString().c_str());

2917.

2918.

else if (pfrom->nVersion == 0)

2919.

2920.

return false;

2921.

2922.

else if (strCommand == "addr")

2923.

2924.

vector<CAddress> vAddr;

2925.

vRecv >> vAddr;

2926.

CAddrDB addrdb;

2927.

foreach(const CAddress& addr, vAddr)

2928.

2929.

if (fShutdown)

2930.

return true;

2931.

if (AddAddress(addrdb, addr))

2932.

2933.

pfrom->setAddrKnown.insert(addr);

2934.

CRITICAL_BLOCK(cs_vNodes)

2935.

foreach(CNode* pnode, vNodes)

2936.

if (!pnode->setAddrKnown.count(addr))

2937.

pnode->vAddrToSend.push_back(addr);

2938.

2939.

2940.

2941.

else if (strCommand == "inv")

2942.

2943.

vector<CInv> vInv;

2944.

vRecv >> vInv;

2945.

CTxDB txdb("r");

2946.

foreach(const CInv& inv, vInv)

2947.

2948.

if (fShutdown)

2949.

return true;

2950.

pfrom->AddInventoryKnown(inv);

2951.
2952.

bool fAlreadyHave = AlreadyHave(txdb, inv);

2953.

printf(" got inventory: %s %s\n", inv.ToString().c_str(), fAlreadyHave ? "have" : "new");

2954.

if (!fAlreadyHave)

2955.

pfrom->AskFor(inv);

2956.

else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash))

2957.

pfrom->PushMessage("getblocks", CBlockLocator(pindexBest), GetOrphanRoot(mapOrphanBlocks[inv.hash]));

2958.
2959.

}
}

2960.

else if (strCommand == "getdata")

2961.

2962.

vector<CInv> vInv;

2963.

vRecv >> vInv;

2964.

foreach(const CInv& inv, vInv)

2965.

2966.

if (fShutdown)

2967.

return true;

2968.

printf("received getdata for: %s\n", inv.ToString().c_str());

2969.

if (inv.type == MSG_BLOCK)

2970.

2971.

map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(inv.hash);

2972.

if (mi != mapBlockIndex.end())

2973.

2974.

CBlock block;

2975.

block.ReadFromDisk((*mi).second, !pfrom->fClient);

2976.

pfrom->PushMessage("block", block);

2977.

2978.

2979.

else if (inv.IsKnownType())

2980.

2981.

CRITICAL_BLOCK(cs_mapRelay)

2982.

2983.

map<CInv, CDataStream>::iterator mi = mapRelay.find(inv);

2984.

if (mi != mapRelay.end())

2985.

pfrom->PushMessage(inv.GetCommand(), (*mi).second);

2986.

2987.

2988.

2989.

2990.

else if (strCommand == "getblocks")

2991.

2992.

CBlockLocator locator;

2993.

uint256 hashStop;

2994.

vRecv >> locator >> hashStop;

2995.

CBlockIndex* pindex = locator.GetBlockIndex();

2996.

if (pindex)

2997.

pindex = pindex->pnext;

2998.

printf("getblocks %d to %s\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,14).c_str());

2999.

for (; pindex; pindex = pindex->pnext)

3000.

3001.

if (pindex->GetBlockHash() == hashStop)

3002.

3003.

printf(" getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,14).c_str());

3004.

break;

3005.

3006.

CRITICAL_BLOCK(pfrom->cs_inventory)

3007.

3008.

CInv inv(MSG_BLOCK, pindex->GetBlockHash());

3009.

if (pfrom->setInventoryKnown2.insert(inv).second)

3010.

3011.

pfrom->setInventoryKnown.erase(inv);

3012.

pfrom->vInventoryToSend.push_back(inv);

3013.

3014.

3015.

3016.

3017.

else if (strCommand == "tx")

3018.

3019.

vector<uint256> vWorkQueue;

3020.

CDataStream vMsg(vRecv);

3021.

CTransaction tx;

3022.

vRecv >> tx;

3023.

CInv inv(MSG_TX, tx.GetHash());

3024.

pfrom->AddInventoryKnown(inv);

3025.

bool fMissingInputs = false;

3026.

if (tx.AcceptTransaction(true, &fMissingInputs))

3027.

3028.

AddToWalletIfMine(tx, NULL);

3029.

RelayMessage(inv, vMsg);

3030.

mapAlreadyAskedFor.erase(inv);

3031.

vWorkQueue.push_back(inv.hash);

3032.

for (int i = 0; i < vWorkQueue.size(); i++)

3033.

3034.

uint256 hashPrev = vWorkQueue[i];

3035.

for (multimap<uint256, CDataStream*>::iterator mi = mapOrphanTransactionsByPrev.lower_bound(hashPrev);

3036.

mi != mapOrphanTransactionsByPrev.upper_bound(hashPrev);

3037.
3038.

++mi)
{

3039.

const CDataStream& vMsg = *((*mi).second);

3040.

CTransaction tx;

3041.

CDataStream(vMsg) >> tx;

3042.

CInv inv(MSG_TX, tx.GetHash());

3043.

if (tx.AcceptTransaction(true))

3044.

3045.

printf(" accepted orphan tx %s\n", inv.hash.ToString().substr(0,6).c_str());

3046.

AddToWalletIfMine(tx, NULL);

3047.

RelayMessage(inv, vMsg);

3048.

mapAlreadyAskedFor.erase(inv);

3049.

vWorkQueue.push_back(inv.hash);

3050.

3051.

3052.

3053.

foreach(uint256 hash, vWorkQueue)

3054.

EraseOrphanTx(hash);

3055.

3056.

else if (fMissingInputs)

3057.

3058.

printf("storing orphan tx %s\n", inv.hash.ToString().substr(0,6).c_str());

3059.

AddOrphanTx(vMsg);

3060.

3061.

3062.

else if (strCommand == "review")

3063.

3064.

CDataStream vMsg(vRecv);

3065.

CReview review;

3066.

vRecv >> review;

3067.

CInv inv(MSG_REVIEW, review.GetHash());

3068.

pfrom->AddInventoryKnown(inv);

3069.

if (review.AcceptReview())

3070.

3071.

RelayMessage(inv, vMsg);

3072.

mapAlreadyAskedFor.erase(inv);

3073.

3074.

3075.

else if (strCommand == "block")

3076.

3077.

auto_ptr<CBlock> pblock(new CBlock);

3078.

vRecv >> *pblock;

3079.

printf("received block:\n"); pblock->print();

3080.

CInv inv(MSG_BLOCK, pblock->GetHash());

3081.

pfrom->AddInventoryKnown(inv);

3082.

if (ProcessBlock(pfrom, pblock.release()))

3083.

mapAlreadyAskedFor.erase(inv);

3084.

3085.

else if (strCommand == "getaddr")

3086.

3087.

pfrom->vAddrToSend.clear();

3088.

int64 nSince = GetAdjustedTime() - 60 * 60;

3089.

CRITICAL_BLOCK(cs_mapAddresses)

3090.

3091.

foreach(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)

3092.

3093.

if (fShutdown)

3094.

return true;

3095.

const CAddress& addr = item.second;

3096.

if (addr.nTime > nSince)

3097.

pfrom->vAddrToSend.push_back(addr);

3098.

3099.

3100.

3101.

else if (strCommand == "checkorder")

3102.

3103.

uint256 hashReply;

3104.

CWalletTx order;

3105.

vRecv >> hashReply >> order;

3106.

if (!mapReuseKey.count(pfrom->addr.ip))

3107.

mapReuseKey[pfrom->addr.ip] = GenerateNewKey();

3108.

CScript scriptPubKey;

3109.

scriptPubKey << mapReuseKey[pfrom->addr.ip] << OP_CHECKSIG;

3110.

pfrom->PushMessage("reply", hashReply, (int)0, scriptPubKey);

3111.

3112.

else if (strCommand == "submitorder")

3113.

3114.

uint256 hashReply;

3115.

CWalletTx wtxNew;

3116.

vRecv >> hashReply >> wtxNew;

3117.

if (!wtxNew.AcceptWalletTransaction())

3118.

3119.

pfrom->PushMessage("reply", hashReply, (int)1);

3120.

return error("submitorder AcceptWalletTransaction() failed, returning error 1");

3121.

3122.

wtxNew.fTimeReceivedIsTxTime = true;

3123.

AddToWallet(wtxNew);

3124.

wtxNew.RelayWalletTransaction();

3125.

mapReuseKey.erase(pfrom->addr.ip);

3126.

pfrom->PushMessage("reply", hashReply, (int)0);

3127.

3128.

else if (strCommand == "reply")

3129.

3130.

uint256 hashReply;

3131.

vRecv >> hashReply;

3132.

CRequestTracker tracker;

3133.

CRITICAL_BLOCK(pfrom->cs_mapRequests)

3134.

3135.

map<uint256, CRequestTracker>::iterator mi = pfrom->mapRequests.find(hashReply);

3136.

if (mi != pfrom->mapRequests.end())

3137.

3138.

tracker = (*mi).second;

3139.

pfrom->mapRequests.erase(mi);

3140.

3141.

3142.

if (!tracker.IsNull())

3143.

tracker.fn(tracker.param1, vRecv);

3144.

3145.

else

3146.

3147.

printf("ProcessMessage(%s) : Ignored unknown message\n", strCommand.c_str());

3148.

3149.

if (!vRecv.empty())

3150.
3151.

printf("ProcessMessage(%s) : %d extra bytes\n", strCommand.c_str(), vRecv.size());


return true;

3152. }
3153. bool SendMessages(CNode* pto)
3154. {
3155.

CheckForShutdown(2);

3156.

CRITICAL_BLOCK(cs_main)

3157.

3158.

if (pto->nVersion == 0)

3159.

return true;

3160.

vector<CAddress> vAddrToSend;

3161.

vAddrToSend.reserve(pto->vAddrToSend.size());

3162.

foreach(const CAddress& addr, pto->vAddrToSend)

3163.

if (!pto->setAddrKnown.count(addr))

3164.

vAddrToSend.push_back(addr);

3165.

pto->vAddrToSend.clear();

3166.

if (!vAddrToSend.empty())

3167.

pto->PushMessage("addr", vAddrToSend);

3168.

vector<CInv> vInventoryToSend;

3169.

CRITICAL_BLOCK(pto->cs_inventory)

3170.

3171.

vInventoryToSend.reserve(pto->vInventoryToSend.size());

3172.

foreach(const CInv& inv, pto->vInventoryToSend)

3173.

3174.

if (pto->setInventoryKnown.insert(inv).second)

3175.

vInventoryToSend.push_back(inv);

3176.

3177.

pto->vInventoryToSend.clear();

3178.

pto->setInventoryKnown2.clear();

3179.

3180.

if (!vInventoryToSend.empty())

3181.

pto->PushMessage("inv", vInventoryToSend);

3182.

vector<CInv> vAskFor;

3183.

int64 nNow = GetTime() * 1000000;

3184.

CTxDB txdb("r");

3185.

while (!pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow)

3186.

3187.

const CInv& inv = (*pto->mapAskFor.begin()).second;

3188.

printf("sending getdata: %s\n", inv.ToString().c_str());

3189.

if (!AlreadyHave(txdb, inv))

3190.

vAskFor.push_back(inv);

3191.

pto->mapAskFor.erase(pto->mapAskFor.begin());

3192.

3193.

if (!vAskFor.empty())

3194.

pto->PushMessage("getdata", vAskFor);

3195.

3196.

return true;

3197. }
3198. int FormatHashBlocks(void* pbuffer, unsigned int len)
3199. {
3200.

unsigned char* pdata = (unsigned char*)pbuffer;

3201.

unsigned int blocks = 1 + ((len + 8) / 64);

3202.

unsigned char* pend = pdata + 64 * blocks;

3203.

memset(pdata + len, 0, 64 * blocks - len);

3204.

pdata[len] = 0x80;

3205.

unsigned int bits = len * 8;

3206.

pend[-1] = (bits >> 0) & 0xff;

3207.

pend[-2] = (bits >> 8) & 0xff;

3208.

pend[-3] = (bits >> 16) & 0xff;

3209.

pend[-4] = (bits >> 24) & 0xff;

3210.

return blocks;

3211. }
3212. using CryptoPP::ByteReverse;
3213. static int detectlittleendian = 1;
3214. void BlockSHA256(const void* pin, unsigned int nBlocks, void* pout)
3215. {
3216.

unsigned int* pinput = (unsigned int*)pin;

3217.

unsigned int* pstate = (unsigned int*)pout;

3218.

CryptoPP::SHA256::InitState(pstate);

3219.

if (*(char*)&detectlittleendian != 0)

3220.

3221.

for (int n = 0; n < nBlocks; n++)

3222.

3223.

unsigned int pbuf[16];

3224.

for (int i = 0; i < 16; i++)

3225.

pbuf[i] = ByteReverse(pinput[n * 16 + i]);

3226.

CryptoPP::SHA256::Transform(pstate, pbuf);

3227.

3228.

for (int i = 0; i < 8; i++)

3229.

pstate[i] = ByteReverse(pstate[i]);

3230.

3231.

else

3232.

3233.

for (int n = 0; n < nBlocks; n++)

3234.
3235.

CryptoPP::SHA256::Transform(pstate, pinput + n * 16);


}

3236. }
3237. bool BitcoinMiner()
3238. {

printf("BitcoinMiner started\n");

3239.

SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST);

3240.

CKey key;

3241.

key.MakeNewKey();

3242.

CBigNum bnExtraNonce = 0;

3243.

while (fGenerateBitcoins)

3244.

3245.

Sleep(50);

3246.

CheckForShutdown(3);

3247.

while (vNodes.empty())

3248.

3249.

Sleep(1000);

3250.

CheckForShutdown(3);

3251.

3252.

unsigned int nTransactionsUpdatedLast = nTransactionsUpdated;

3253.

CBlockIndex* pindexPrev = pindexBest;

3254.

unsigned int nBits = GetNextWorkRequired(pindexPrev);

3255.

CTransaction txNew;

3256.

txNew.vin.resize(1);

3257.

txNew.vin[0].prevout.SetNull();

3258.

txNew.vin[0].scriptSig << nBits << ++bnExtraNonce;

3259.

txNew.vout.resize(1);

3260.

txNew.vout[0].scriptPubKey << key.GetPubKey() << OP_CHECKSIG;

3261.

auto_ptr<CBlock> pblock(new CBlock());

3262.

if (!pblock.get())

3263.
3264.

return false;
pblock->vtx.push_back(txNew);

3265.

int64 nFees = 0;

3266.

CRITICAL_BLOCK(cs_main)

3267.

CRITICAL_BLOCK(cs_mapTransactions)

3268.

3269.

CTxDB txdb("r");

3270.

map<uint256, CTxIndex> mapTestPool;

3271.

vector<char> vfAlreadyAdded(mapTransactions.size());

3272.

bool fFoundSomething = true;

3273.

unsigned int nBlockSize = 0;

3274.

while (fFoundSomething && nBlockSize < MAX_SIZE/2)

3275.

3276.

fFoundSomething = false;

3277.

unsigned int n = 0;

3278.

for (map<uint256, CTransaction>::iterator mi = mapTransactions.begin(); mi != mapTransactions.end(); ++mi, ++n)

3279.

3280.
3281.

if (vfAlreadyAdded[n])
continue;

3282.

CTransaction& tx = (*mi).second;

3283.

if (tx.IsCoinBase() || !tx.IsFinal())

3284.
3285.

continue;
int64 nMinFee = tx.GetMinFee(pblock->vtx.size() < 100);

3286.
3287.

map<uint256, CTxIndex> mapTestPoolTmp(mapTestPool);

3288.

if (!tx.ConnectInputs(txdb, mapTestPoolTmp, CDiskTxPos(1,1,1), 0, nFees, false, true, nMinFee))

3289.
3290.
3291.

continue;
swap(mapTestPool, mapTestPoolTmp);

3292.

pblock->vtx.push_back(tx);

3293.

nBlockSize += ::GetSerializeSize(tx, SER_NETWORK);

3294.

vfAlreadyAdded[n] = true;

3295.

fFoundSomething = true;

3296.

3297.

3298.

3299.

pblock->nBits = nBits;

3300.

pblock->vtx[0].vout[0].nValue = pblock->GetBlockValue(nFees);

3301.

printf("\n\nRunning BitcoinMiner with %d transactions in block\n", pblock->vtx.size());

3302.

struct unnamed1

3303.

3304.

struct unnamed2

3305.

3306.

int nVersion;

3307.

uint256 hashPrevBlock;

3308.

uint256 hashMerkleRoot;

3309.

unsigned int nTime;

3310.

unsigned int nBits;

3311.

unsigned int nNonce;

3312.

3313.

block;

3314.

unsigned char pchPadding0[64];

3315.

uint256 hash1;

3316.

unsigned char pchPadding1[64];

3317.

3318.

tmp;

3319.

tmp.block.nVersion

3320.

tmp.block.hashPrevBlock = pblock->hashPrevBlock = (pindexPrev ? pindexPrev->GetBlockHash() : 0);

3321.

tmp.block.hashMerkleRoot = pblock->hashMerkleRoot = pblock->BuildMerkleTree();

3322.

tmp.block.nTime

3323.

tmp.block.nBits

3324.

tmp.block.nNonce

3325.

unsigned int nBlocks0 = FormatHashBlocks(&tmp.block, sizeof(tmp.block));

3326.

unsigned int nBlocks1 = FormatHashBlocks(&tmp.hash1, sizeof(tmp.hash1));

3327.

unsigned int nStart = GetTime();

3328.

uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();

3329.

uint256 hash;

3330.

loop

3331.

= pblock->nVersion;

= pblock->nTime
= pblock->nBits

= max((pindexPrev ? pindexPrev->GetMedianTimePast()+1 : 0), GetAdjustedTime());


= nBits;

= pblock->nNonce

= 1;

3332.

BlockSHA256(&tmp.block, nBlocks0, &tmp.hash1);

3333.

BlockSHA256(&tmp.hash1, nBlocks1, &hash);

3334.

if (hash <= hashTarget)

3335.

3336.

pblock->nNonce = tmp.block.nNonce;

3337.

assert(hash == pblock->GetHash());

3338.

printf("BitcoinMiner:\n");

3339.

printf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str());

3340.

pblock->print();

3341.
3342.

SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);

3343.

CRITICAL_BLOCK(cs_main)

3344.

3345.

if (!AddKey(key))

3346.

return false;

3347.

key.MakeNewKey();

3348.

if (!ProcessBlock(NULL, pblock.release()))

3349.

printf("ERROR in BitcoinMiner, ProcessBlock, block not accepted\n");

3350.

3351.

SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST);

3352.

Sleep(500);

3353.

break;

3354.

3355.

if ((++tmp.block.nNonce & 0x3ffff) == 0)

3356.

3357.

CheckForShutdown(3);

3358.

if (tmp.block.nNonce == 0)

3359.

break;

3360.

if (pindexPrev != pindexBest)

3361.

break;

3362.

if (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60)

3363.

break;

3364.

if (!fGenerateBitcoins)

3365.

break;

3366.

tmp.block.nTime = pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());

3367.

3368.

3369.

3370.

return true;

3371. }
3372. int64 GetBalance()
3373. {
3374.

int64 nStart, nEnd;

3375.

QueryPerformanceCounter((LARGE_INTEGER*)&nStart);

3376.

int64 nTotal = 0;

3377.

CRITICAL_BLOCK(cs_mapWallet)

3378.

3379.

for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)

3380.

3381.

CWalletTx* pcoin = &(*it).second;

3382.

if (!pcoin->IsFinal() || pcoin->fSpent)

3383.

continue;

3384.

nTotal += pcoin->GetCredit();

3385.

3386.

3387.

QueryPerformanceCounter((LARGE_INTEGER*)&nEnd);

3388.

return nTotal;

3389. }
3390. bool SelectCoins(int64 nTargetValue, set<CWalletTx*>& setCoinsRet)
3391. {
3392.

setCoinsRet.clear();

3393.

int64 nLowestLarger = _I64_MAX;

3394.

CWalletTx* pcoinLowestLarger = NULL;

3395.

vector<pair<int64, CWalletTx*> > vValue;

3396.

int64 nTotalLower = 0;

3397.

CRITICAL_BLOCK(cs_mapWallet)

3398.

3399.

for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)

3400.

3401.

CWalletTx* pcoin = &(*it).second;

3402.

if (!pcoin->IsFinal() || pcoin->fSpent)

3403.

continue;

3404.

int64 n = pcoin->GetCredit();

3405.

if (n <= 0)

3406.

continue;

3407.

if (n < nTargetValue)

3408.

3409.

vValue.push_back(make_pair(n, pcoin));

3410.

nTotalLower += n;

3411.

3412.

else if (n == nTargetValue)

3413.

3414.

setCoinsRet.insert(pcoin);

3415.

return true;

3416.

3417.

else if (n < nLowestLarger)

3418.

3419.

nLowestLarger = n;

3420.

pcoinLowestLarger = pcoin;

3421.

3422.

3423.

3424.

if (nTotalLower < nTargetValue)

3425.

3426.

if (pcoinLowestLarger == NULL)

3427.

return false;

3428.

setCoinsRet.insert(pcoinLowestLarger);

3429.

return true;

3430.

3431.

sort(vValue.rbegin(), vValue.rend());

3432.

vector<char> vfIncluded;

3433.

vector<char> vfBest(vValue.size(), true);

3434.

int64 nBest = nTotalLower;

3435.

for (int nRep = 0; nRep < 1000 && nBest != nTargetValue; nRep++)

3436.

3437.

vfIncluded.assign(vValue.size(), false);

3438.

int64 nTotal = 0;

3439.

bool fReachedTarget = false;

3440.

for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++)

3441.

3442.

for (int i = 0; i < vValue.size(); i++)

3443.

3444.

if (nPass == 0 ? rand() % 2 : !vfIncluded[i])

3445.

3446.

nTotal += vValue[i].first;

3447.

vfIncluded[i] = true;

3448.

if (nTotal >= nTargetValue)

3449.

3450.

fReachedTarget = true;

3451.

if (nTotal < nBest)

3452.

3453.

nBest = nTotal;

3454.

vfBest = vfIncluded;

3455.

3456.

nTotal -= vValue[i].first;

3457.

vfIncluded[i] = false;

3458.

3459.

3460.

3461.

3462.

3463.

if (pcoinLowestLarger && nLowestLarger - nTargetValue <= nBest - nTargetValue)

3464.

setCoinsRet.insert(pcoinLowestLarger);

3465.

else

3466.

3467.

for (int i = 0; i < vValue.size(); i++)

3468.

if (vfBest[i])

3469.

setCoinsRet.insert(vValue[i].second);

3470.
3471.

printf("SelectCoins() best subset: ");

3472.

for (int i = 0; i < vValue.size(); i++)

3473.

if (vfBest[i])

3474.

printf("%s ", FormatMoney(vValue[i].first).c_str());

3475.

printf("total %s\n", FormatMoney(nBest).c_str());

3476.

3477.

return true;

3478. }
3479. bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, int64& nFeeRequiredRet)
3480. {
3481.

nFeeRequiredRet = 0;

3482.

CRITICAL_BLOCK(cs_main)

3483.

3484.

CTxDB txdb("r");

3485.

CRITICAL_BLOCK(cs_mapWallet)

3486.

3487.

int64 nFee = nTransactionFee;

3488.

loop

3489.

3490.

wtxNew.vin.clear();

3491.

wtxNew.vout.clear();

3492.

if (nValue < 0)

3493.

return false;

3494.

int64 nValueOut = nValue;

3495.

nValue += nFee;

3496.
3497.

set<CWalletTx*> setCoins;

3498.

if (!SelectCoins(nValue, setCoins))

3499.

return false;

3500.

int64 nValueIn = 0;

3501.

foreach(CWalletTx* pcoin, setCoins)

3502.

nValueIn += pcoin->GetCredit();

3503.

wtxNew.vout.push_back(CTxOut(nValueOut, scriptPubKey));

3504.

if (nValueIn > nValue)

3505.

3506.

vector<unsigned char> vchPubKey;

3507.

CTransaction& txFirst = *(*setCoins.begin());

3508.

foreach(const CTxOut& txout, txFirst.vout)

3509.

if (txout.IsMine())

3510.

if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey))

3511.

break;

3512.

if (vchPubKey.empty())

3513.

return false;

3514.

CScript scriptPubKey;

3515.

scriptPubKey << vchPubKey << OP_CHECKSIG;

3516.

wtxNew.vout.push_back(CTxOut(nValueIn - nValue, scriptPubKey));

3517.

3518.

foreach(CWalletTx* pcoin, setCoins)

3519.

for (int nOut = 0; nOut < pcoin->vout.size(); nOut++)

3520.

if (pcoin->vout[nOut].IsMine())

3521.

wtxNew.vin.push_back(CTxIn(pcoin->GetHash(), nOut));

3522.

int nIn = 0;

3523.

foreach(CWalletTx* pcoin, setCoins)

3524.

for (int nOut = 0; nOut < pcoin->vout.size(); nOut++)

3525.

if (pcoin->vout[nOut].IsMine())

3526.

SignSignature(*pcoin, wtxNew, nIn++);

3527.

if (nFee < wtxNew.GetMinFee(true))

3528.

3529.

nFee = nFeeRequiredRet = wtxNew.GetMinFee(true);

3530.

continue;

3531.

3532.

wtxNew.AddSupportingTransactions(txdb);

3533.

wtxNew.fTimeReceivedIsTxTime = true;

3534.

break;

3535.

3536.

3537.

3538.

return true;

3539. }
3540. bool CommitTransactionSpent(const CWalletTx& wtxNew)

3541. {
3542.

CRITICAL_BLOCK(cs_main)

3543.

CRITICAL_BLOCK(cs_mapWallet)

3544.

3545.

AddToWallet(wtxNew);

3546.

set<CWalletTx*> setCoins;

3547.

foreach(const CTxIn& txin, wtxNew.vin)

3548.

setCoins.insert(&mapWallet[txin.prevout.hash]);

3549.

foreach(CWalletTx* pcoin, setCoins)

3550.

3551.

pcoin->fSpent = true;

3552.

pcoin->WriteToDisk();

3553.

vWalletUpdated.push_back(make_pair(pcoin->GetHash(), false));

3554.

3555.

3556.

MainFrameRepaint();

3557.

return true;

3558. }
3559. bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew)
3560. {
3561.

CRITICAL_BLOCK(cs_main)

3562.

3563.

int64 nFeeRequired;

3564.

if (!CreateTransaction(scriptPubKey, nValue, wtxNew, nFeeRequired))

3565.

3566.

string strError;

3567.

if (nValue + nFeeRequired > GetBalance())

3568.

strError = strprintf("Error: This is an oversized transaction that requires a transaction fee of %s ", FormatMoney(nFeeRequired).c_str());

3569.

else

3570.

strError = "Error: Transaction creation failed ";

3571.

wxMessageBox(strError, "Sending...");

3572.

return error("SendMoney() : %s\n", strError.c_str());

3573.

3574.

if (!CommitTransactionSpent(wtxNew))

3575.

3576.

wxMessageBox("Error finalizing transaction", "Sending...");

3577.

return error("SendMoney() : Error finalizing transaction");

3578.

3579.

printf("SendMoney: %s\n", wtxNew.GetHash().ToString().substr(0,6).c_str());

3580.

if (!wtxNew.AcceptTransaction())

3581.

3582.

throw runtime_error("SendMoney() : wtxNew.AcceptTransaction() failed\n");

3583.

wxMessageBox("Error: Transaction not valid", "Sending...");

3584.

return error("SendMoney() : Error: Transaction not valid");

3585.

3586.

wtxNew.RelayWalletTransaction();

3587.

3588.

MainFrameRepaint();

3589.

return true;

3590. }
3591. class COutPoint;
3592. class CInPoint;
3593. class CDiskTxPos;
3594. class CCoinBase;
3595. class CTxIn;
3596. class CTxOut;
3597. class CTransaction;
3598. class CBlock;
3599. class CBlockIndex;
3600. class CWalletTx;
3601. class CKeyItem;
3602. static const unsigned int MAX_SIZE = 0x02000000;
3603. static const int64 COIN = 100000000;
3604. static const int64 CENT = 1000000;
3605. static const int COINBASE_MATURITY = 100;
3606. static const CBigNum bnProofOfWorkLimit(~uint256(0) >> 32);
3607. extern CCriticalSection cs_main;
3608. extern map<uint256, CBlockIndex*> mapBlockIndex;
3609. extern const uint256 hashGenesisBlock;
3610. extern CBlockIndex* pindexGenesisBlock;
3611. extern int nBestHeight;
3612. extern uint256 hashBestChain;
3613. extern CBlockIndex* pindexBest;
3614. extern unsigned int nTransactionsUpdated;
3615. extern string strSetDataDir;
3616. extern int nDropMessagesTest;
3617. extern int fGenerateBitcoins;
3618. extern int64 nTransactionFee;
3619. extern CAddress addrIncoming;
3620. string GetAppDir();
3621. FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb");
3622. FILE* AppendBlockFile(unsigned int& nFileRet);
3623. bool AddKey(const CKey& key);

3624. vector<unsigned char> GenerateNewKey();


3625. bool AddToWallet(const CWalletTx& wtxIn);
3626. void ReacceptWalletTransactions();
3627. void RelayWalletTransactions();
3628. bool LoadBlockIndex(bool fAllowNew=true);
3629. void PrintBlockTree();
3630. bool BitcoinMiner();
3631. bool ProcessMessages(CNode* pfrom);
3632. bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv);
3633. bool SendMessages(CNode* pto);
3634. int64 GetBalance();
3635. bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& txNew, int64& nFeeRequiredRet);
3636. bool CommitTransactionSpent(const CWalletTx& wtxNew);
3637. bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew);
3638. class CDiskTxPos
3639. {
3640. public:
3641.

unsigned int nFile;

3642.

unsigned int nBlockPos;

3643.

unsigned int nTxPos;

3644.

CDiskTxPos()

3645.

3646.

SetNull();

3647.

3648.

CDiskTxPos(unsigned int nFileIn, unsigned int nBlockPosIn, unsigned int nTxPosIn)

3649.

3650.

nFile = nFileIn;

3651.

nBlockPos = nBlockPosIn;

3652.

nTxPos = nTxPosIn;

3653.

3654.

IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); )

3655.

void SetNull() { nFile = -1; nBlockPos = 0; nTxPos = 0; }

3656.

bool IsNull() const { return (nFile == -1); }

3657.

friend bool operator==(const CDiskTxPos& a, const CDiskTxPos& b)

3658.

3659.

return (a.nFile

3660.

== b.nFile &&

a.nBlockPos == b.nBlockPos &&

3661.

a.nTxPos

== b.nTxPos);

3662.

3663.

friend bool operator!=(const CDiskTxPos& a, const CDiskTxPos& b)

3664.

3665.

return !(a == b);

3666.

3667.

string ToString() const

3668.

3669.

if (IsNull())

3670.

return strprintf("null");

3671.

else

3672.

return strprintf("(nFile=%d, nBlockPos=%d, nTxPos=%d)", nFile, nBlockPos, nTxPos);

3673.

3674.

void print() const

3675.

3676.
3677.

printf("%s", ToString().c_str());
}

3678. };
3679. class CInPoint
3680. {
3681. public:
3682.

CTransaction* ptx;

3683.

unsigned int n;

3684.

CInPoint() { SetNull(); }

3685.

CInPoint(CTransaction* ptxIn, unsigned int nIn) { ptx = ptxIn; n = nIn; }

3686.

void SetNull() { ptx = NULL; n = -1; }

3687.

bool IsNull() const { return (ptx == NULL && n == -1); }

3688. };
3689. class COutPoint
3690. {
3691. public:
3692.

uint256 hash;

3693.

unsigned int n;

3694.

COutPoint() { SetNull(); }

3695.

COutPoint(uint256 hashIn, unsigned int nIn) { hash = hashIn; n = nIn; }

3696.

IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); )

3697.

void SetNull() { hash = 0; n = -1; }

3698.

bool IsNull() const { return (hash == 0 && n == -1); }

3699.

friend bool operator<(const COutPoint& a, const COutPoint& b)

3700.

3701.

return (a.hash < b.hash || (a.hash == b.hash && a.n < b.n));

3702.

3703.

friend bool operator==(const COutPoint& a, const COutPoint& b)

3704.

3705.
3706.

return (a.hash == b.hash && a.n == b.n);


}

3707.

friend bool operator!=(const COutPoint& a, const COutPoint& b)

3708.

3709.

return !(a == b);

3710.

3711.

string ToString() const

3712.

3713.

return strprintf("COutPoint(%s, %d)", hash.ToString().substr(0,6).c_str(), n);

3714.

3715.

void print() const

3716.

3717.
3718.

printf("%s\n", ToString().c_str());
}

3719. };
3720. class CTxIn
3721. {
3722. public:
3723.

COutPoint prevout;

3724.

CScript scriptSig;

3725.

unsigned int nSequence;

3726.

CTxIn()

3727.

3728.

nSequence = UINT_MAX;

3729.

3730.

explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX)

3731.

3732.

prevout = prevoutIn;

3733.

scriptSig = scriptSigIn;

3734.

nSequence = nSequenceIn;

3735.

3736.

CTxIn(uint256 hashPrevTx, unsigned int nOut, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX)

3737.

3738.

prevout = COutPoint(hashPrevTx, nOut);

3739.

scriptSig = scriptSigIn;

3740.

nSequence = nSequenceIn;

3741.

3742.

IMPLEMENT_SERIALIZE

3743.

3744.

READWRITE(prevout);

3745.

READWRITE(scriptSig);

3746.

READWRITE(nSequence);

3747.

3748.

bool IsFinal() const

3749.

3750.

return (nSequence == UINT_MAX);

3751.

3752.

friend bool operator==(const CTxIn& a, const CTxIn& b)

3753.

3754.

return (a.prevout == b.prevout &&

3755.

a.scriptSig == b.scriptSig &&

3756.

a.nSequence == b.nSequence);

3757.

3758.

friend bool operator!=(const CTxIn& a, const CTxIn& b)

3759.

3760.

return !(a == b);

3761.

3762.

string ToString() const

3763.

3764.

string str;

3765.

str += strprintf("CTxIn(");

3766.

str += prevout.ToString();

3767.

if (prevout.IsNull())

3768.

str += strprintf(", coinbase %s", HexStr(scriptSig.begin(), scriptSig.end(), false).c_str());

3769.

else

3770.

str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24).c_str());

3771.

if (nSequence != UINT_MAX)

3772.

str += strprintf(", nSequence=%u", nSequence);

3773.

str += ")";

3774.

return str;

3775.

3776.

void print() const

3777.

3778.

printf("%s\n", ToString().c_str());

3779.

3780.

bool IsMine() const;

3781.

int64 GetDebit() const;

3782. };
3783. class CTxOut
3784. {
3785. public:
3786.

int64 nValue;

3787.

CScript scriptPubKey;

3788. public:
3789.

CTxOut()

3790.

3791.

SetNull();

3792.

3793.

CTxOut(int64 nValueIn, CScript scriptPubKeyIn)

3794.

3795.

nValue = nValueIn;

3796.

scriptPubKey = scriptPubKeyIn;

3797.

3798.

IMPLEMENT_SERIALIZE

3799.

3800.

READWRITE(nValue);

3801.

READWRITE(scriptPubKey);

3802.

3803.

void SetNull()

3804.

3805.

nValue = -1;

3806.

scriptPubKey.clear();

3807.

3808.

bool IsNull()

3809.

3810.

return (nValue == -1);

3811.

3812.

uint256 GetHash() const

3813.

3814.

return SerializeHash(*this);

3815.

3816.

bool IsMine() const

3817.

3818.

return ::IsMine(scriptPubKey);

3819.

3820.

int64 GetCredit() const

3821.

3822.

if (IsMine())

3823.

return nValue;

3824.

return 0;

3825.

3826.

friend bool operator==(const CTxOut& a, const CTxOut& b)

3827.

3828.

return (a.nValue

3829.

== b.nValue &&

a.scriptPubKey == b.scriptPubKey);

3830.

3831.

friend bool operator!=(const CTxOut& a, const CTxOut& b)

3832.

3833.

return !(a == b);

3834.

3835.

string ToString() const

3836.

3837.

if (scriptPubKey.size() < 6)

3838.

return "CTxOut(error)";

3839.

return strprintf("CTxOut(nValue=%I64d.%08I64d, scriptPubKey=%s)", nValue / COIN, nValue % COIN,


scriptPubKey.ToString().substr(0,24).c_str());

3840.

3841.

void print() const

3842.

3843.
3844.

printf("%s\n", ToString().c_str());
}

3845. };
3846. class CTransaction
3847. {
3848. public:
3849.

int nVersion;

3850.

vector<CTxIn> vin;

3851.

vector<CTxOut> vout;

3852.

int nLockTime;

3853.

CTransaction()

3854.

3855.

SetNull();

3856.

3857.

IMPLEMENT_SERIALIZE

3858.

3859.

READWRITE(this->nVersion);

3860.

nVersion = this->nVersion;

3861.

READWRITE(vin);

3862.

READWRITE(vout);

3863.

READWRITE(nLockTime);

3864.

3865.

void SetNull()

3866.

3867.

nVersion = 1;

3868.

vin.clear();

3869.

vout.clear();

3870.
3871.

nLockTime = 0;
}

3872.

bool IsNull() const

3873.

3874.

return (vin.empty() && vout.empty());

3875.

3876.

uint256 GetHash() const

3877.

3878.

return SerializeHash(*this);

3879.

3880.

bool IsFinal() const

3881.

3882.

if (nLockTime == 0 || nLockTime < nBestHeight)

3883.

return true;

3884.

foreach(const CTxIn& txin, vin)

3885.

if (!txin.IsFinal())

3886.

return false;

3887.

return true;

3888.

3889.

bool IsNewerThan(const CTransaction& old) const

3890.

3891.

if (vin.size() != old.vin.size())

3892.

return false;

3893.

for (int i = 0; i < vin.size(); i++)

3894.

if (vin[i].prevout != old.vin[i].prevout)

3895.

return false;

3896.

bool fNewer = false;

3897.

unsigned int nLowest = UINT_MAX;

3898.

for (int i = 0; i < vin.size(); i++)

3899.

3900.

if (vin[i].nSequence != old.vin[i].nSequence)

3901.

3902.

if (vin[i].nSequence <= nLowest)

3903.

3904.

fNewer = false;

3905.

nLowest = vin[i].nSequence;

3906.

3907.

if (old.vin[i].nSequence < nLowest)

3908.

3909.

fNewer = true;

3910.

nLowest = old.vin[i].nSequence;

3911.

3912.

3913.

3914.

return fNewer;

3915.

3916.

bool IsCoinBase() const

3917.

3918.

return (vin.size() == 1 && vin[0].prevout.IsNull());

3919.

3920.

bool CheckTransaction() const

3921.

3922.

if (vin.empty() || vout.empty())

3923.

return error("CTransaction::CheckTransaction() : vin or vout empty");

3924.

foreach(const CTxOut& txout, vout)

3925.

if (txout.nValue < 0)

3926.

return error("CTransaction::CheckTransaction() : txout.nValue negative");

3927.

if (IsCoinBase())

3928.

3929.

if (vin[0].scriptSig.size() < 2 || vin[0].scriptSig.size() > 100)

3930.

return error("CTransaction::CheckTransaction() : coinbase script size");

3931.

3932.

else

3933.

3934.

foreach(const CTxIn& txin, vin)

3935.

if (txin.prevout.IsNull())

3936.

return error("CTransaction::CheckTransaction() : prevout is null");

3937.

3938.

return true;

3939.

3940.

bool IsMine() const

3941.

3942.

foreach(const CTxOut& txout, vout)

3943.

if (txout.IsMine())

3944.

return true;

3945.

return false;

3946.

3947.

int64 GetDebit() const

3948.

3949.

int64 nDebit = 0;

3950.

foreach(const CTxIn& txin, vin)

3951.

nDebit += txin.GetDebit();

3952.

return nDebit;

3953.

3954.

int64 GetCredit() const

3955.

3956.

int64 nCredit = 0;

3957.

foreach(const CTxOut& txout, vout)

3958.

nCredit += txout.GetCredit();

3959.

return nCredit;

3960.

3961.

int64 GetValueOut() const

3962.

3963.

int64 nValueOut = 0;

3964.

foreach(const CTxOut& txout, vout)

3965.

3966.

if (txout.nValue < 0)

3967.

throw runtime_error("CTransaction::GetValueOut() : negative value");

3968.

nValueOut += txout.nValue;

3969.

3970.

return nValueOut;

3971.

3972.

int64 GetMinFee(bool fDiscount=false) const

3973.

3974.

unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK);

3975.

if (fDiscount && nBytes < 10000)

3976.

return 0;

3977.

return (1 + (int64)nBytes / 1000) * CENT;

3978.

3979.

bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL)

3980.

3981.

CAutoFile filein = OpenBlockFile(pos.nFile, 0, pfileRet ? "rb+" : "rb");

3982.

if (!filein)

3983.

return error("CTransaction::ReadFromDisk() : OpenBlockFile failed");

3984.

if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)

3985.

return error("CTransaction::ReadFromDisk() : fseek failed");

3986.

filein >> *this;

3987.

if (pfileRet)

3988.

3989.

if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)

3990.

return error("CTransaction::ReadFromDisk() : second fseek failed");

3991.

*pfileRet = filein.release();

3992.

3993.

return true;

3994.

3995.

friend bool operator==(const CTransaction& a, const CTransaction& b)

3996.

3997.

return (a.nVersion == b.nVersion &&

3998.

a.vin

3999.

a.vout

== b.vin &&

4000.

a.nLockTime == b.nLockTime);

== b.vout &&

4001.

4002.

friend bool operator!=(const CTransaction& a, const CTransaction& b)

4003.

4004.

return !(a == b);

4005.

4006.

string ToString() const

4007.

4008.

string str;

4009.

str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%d, vout.size=%d, nLockTime=%d)\n",

4010.

GetHash().ToString().substr(0,6).c_str(),

4011.

nVersion,

4012.

vin.size(),

4013.

vout.size(),

4014.

nLockTime);

4015.

for (int i = 0; i < vin.size(); i++)

4016.

str += " " + vin[i].ToString() + "\n";

4017.

for (int i = 0; i < vout.size(); i++)

4018.

str += " " + vout[i].ToString() + "\n";

4019.

return str;

4020.

4021.

void print() const

4022.

4023.

printf("%s", ToString().c_str());

4024.

4025.

bool DisconnectInputs(CTxDB& txdb);

4026.

bool ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPool, CDiskTxPos posThisTx, int nHeight, int64& nFees, bool fBlock, bool
fMiner, int64 nMinFee=0);

4027.

bool ClientConnectInputs();

4028.

bool AcceptTransaction(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL);

4029.

bool AcceptTransaction(bool fCheckInputs=true, bool* pfMissingInputs=NULL)

4030.

4031.

CTxDB txdb("r");

4032.
4033.

return AcceptTransaction(txdb, fCheckInputs, pfMissingInputs);


}

4034. protected:
4035.

bool AddToMemoryPool();

4036. public:

4037.

bool RemoveFromMemoryPool();

4038. };
4039. class CMerkleTx : public CTransaction
4040. {
4041. public:
4042.

uint256 hashBlock;

4043.

vector<uint256> vMerkleBranch;

4044.

int nIndex;

4045.

mutable bool fMerkleVerified;

4046.

CMerkleTx()

4047.

4048.

Init();

4049.

4050.

CMerkleTx(const CTransaction& txIn) : CTransaction(txIn)

4051.

4052.

Init();

4053.

4054.

void Init()

4055.

4056.

hashBlock = 0;

4057.

nIndex = -1;

4058.

fMerkleVerified = false;

4059.

4060.

int64 GetCredit() const

4061.

4062.

if (IsCoinBase() && GetBlocksToMaturity() > 0)

4063.

return 0;

4064.

return CTransaction::GetCredit();

4065.

4066.

IMPLEMENT_SERIALIZE

4067.

4068.

nSerSize += SerReadWrite(s, *(CTransaction*)this, nType, nVersion, ser_action);

4069.

nVersion = this->nVersion;

4070.

READWRITE(hashBlock);

4071.

READWRITE(vMerkleBranch);

4072.

READWRITE(nIndex);

4073.

4074.

int SetMerkleBranch(const CBlock* pblock=NULL);

4075.

int GetDepthInMainChain() const;

4076.

bool IsInMainChain() const { return GetDepthInMainChain() > 0; }

4077.

int GetBlocksToMaturity() const;

4078.

bool AcceptTransaction(CTxDB& txdb, bool fCheckInputs=true);

4079.

bool AcceptTransaction() { CTxDB txdb("r"); return AcceptTransaction(txdb); }

4080. };
4081. class CWalletTx : public CMerkleTx
4082. {
4083. public:
4084.

vector<CMerkleTx> vtxPrev;

4085.

map<string, string> mapValue;

4086.

vector<pair<string, string> > vOrderForm;

4087.

unsigned int fTimeReceivedIsTxTime;

4088.

unsigned int nTimeReceived;

4089.

char fFromMe;

4090.

char fSpent;

4091.

mutable unsigned int nTimeDisplayed;

4092.

CWalletTx()

4093.

4094.

Init();

4095.

4096.

CWalletTx(const CMerkleTx& txIn) : CMerkleTx(txIn)

4097.

4098.

Init();

4099.

4100.

CWalletTx(const CTransaction& txIn) : CMerkleTx(txIn)

4101.

4102.

Init();

4103.

4104.

void Init()

4105.

4106.

fTimeReceivedIsTxTime = false;

4107.

nTimeReceived = 0;

4108.

fFromMe = false;

4109.

fSpent = false;

4110.

nTimeDisplayed = 0;

4111.

4112.

IMPLEMENT_SERIALIZE

4113.

4114.

nSerSize += SerReadWrite(s, *(CMerkleTx*)this, nType, nVersion, ser_action);

4115.

nVersion = this->nVersion;

4116.

READWRITE(vtxPrev);

4117.

READWRITE(mapValue);

4118.

READWRITE(vOrderForm);

4119.

READWRITE(fTimeReceivedIsTxTime);

4120.

READWRITE(nTimeReceived);

4121.

READWRITE(fFromMe);

4122.

READWRITE(fSpent);

4123.

4124.

bool WriteToDisk()

4125.

4126.

return CWalletDB().WriteTx(GetHash(), *this);

4127.

4128.

int64 GetTxTime() const;

4129.

void AddSupportingTransactions(CTxDB& txdb);

4130.

bool AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs=true);

4131.

bool AcceptWalletTransaction() { CTxDB txdb("r"); return AcceptWalletTransaction(txdb); }

4132.

void RelayWalletTransaction(CTxDB& txdb);

4133.

void RelayWalletTransaction() { CTxDB txdb("r"); RelayWalletTransaction(txdb); }

4134. };
4135. class CTxIndex
4136. {
4137. public:
4138.

CDiskTxPos pos;

4139.

vector<CDiskTxPos> vSpent;

4140.

CTxIndex()

4141.

4142.

SetNull();

4143.

4144.

CTxIndex(const CDiskTxPos& posIn, unsigned int nOutputs)

4145.

4146.

pos = posIn;

4147.

vSpent.resize(nOutputs);

4148.

4149.

IMPLEMENT_SERIALIZE

4150.

4151.

if (!(nType & SER_GETHASH))

4152.

READWRITE(nVersion);

4153.

READWRITE(pos);

4154.

READWRITE(vSpent);

4155.

4156.

void SetNull()

4157.

4158.

pos.SetNull();

4159.

vSpent.clear();

4160.

4161.

bool IsNull()

4162.

4163.

return pos.IsNull();

4164.

4165.

friend bool operator==(const CTxIndex& a, const CTxIndex& b)

4166.

4167.

if (a.pos != b.pos || a.vSpent.size() != b.vSpent.size())

4168.

return false;

4169.

for (int i = 0; i < a.vSpent.size(); i++)

4170.

if (a.vSpent[i] != b.vSpent[i])

4171.

return false;

4172.

return true;

4173.

4174.

friend bool operator!=(const CTxIndex& a, const CTxIndex& b)

4175.

4176.
4177.

return !(a == b);


}

4178. };
4179. class CBlock
4180. {
4181. public:
4182.

int nVersion;

4183.

uint256 hashPrevBlock;

4184.

uint256 hashMerkleRoot;

4185.

unsigned int nTime;

4186.

unsigned int nBits;

4187.

unsigned int nNonce;

4188.

vector<CTransaction> vtx;

4189.

mutable vector<uint256> vMerkleTree;

4190.

CBlock()

4191.

4192.

SetNull();

4193.

4194.

IMPLEMENT_SERIALIZE

4195.

4196.

READWRITE(this->nVersion);

4197.

nVersion = this->nVersion;

4198.

READWRITE(hashPrevBlock);

4199.

READWRITE(hashMerkleRoot);

4200.

READWRITE(nTime);

4201.

READWRITE(nBits);

4202.

READWRITE(nNonce);

4203.

if (!(nType & (SER_GETHASH|SER_BLOCKHEADERONLY)))

4204.

READWRITE(vtx);

4205.

else if (fRead)

4206.

const_cast<CBlock*>(this)->vtx.clear();

4207.

4208.

void SetNull()

4209.

4210.

nVersion = 1;

4211.

hashPrevBlock = 0;

4212.

hashMerkleRoot = 0;

4213.

nTime = 0;

4214.

nBits = 0;

4215.

nNonce = 0;

4216.

vtx.clear();

4217.

vMerkleTree.clear();

4218.

4219.

bool IsNull() const

4220.

4221.

return (nBits == 0);

4222.

4223.

uint256 GetHash() const

4224.

4225.

return Hash(BEGIN(nVersion), END(nNonce));

4226.

4227.

uint256 BuildMerkleTree() const

4228.

4229.

vMerkleTree.clear();

4230.

foreach(const CTransaction& tx, vtx)

4231.

vMerkleTree.push_back(tx.GetHash());

4232.

int j = 0;

4233.

for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)

4234.

4235.

for (int i = 0; i < nSize; i += 2)

4236.

4237.

int i2 = min(i+1, nSize-1);

4238.

vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]), END(vMerkleTree[j+i]),

4239.

BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2])));

4240.

4241.

j += nSize;

4242.

4243.

return (vMerkleTree.empty() ? 0 : vMerkleTree.back());

4244.

4245.

vector<uint256> GetMerkleBranch(int nIndex) const

4246.

4247.

if (vMerkleTree.empty())

4248.

BuildMerkleTree();

4249.

vector<uint256> vMerkleBranch;

4250.

int j = 0;

4251.

for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)

4252.

4253.

int i = min(nIndex^1, nSize-1);

4254.

vMerkleBranch.push_back(vMerkleTree[j+i]);

4255.

nIndex >>= 1;

4256.

j += nSize;

4257.

4258.

return vMerkleBranch;

4259.

4260.

static uint256 CheckMerkleBranch(uint256 hash, const vector<uint256>& vMerkleBranch, int nIndex)

4261.

4262.

if (nIndex == -1)

4263.

return 0;

4264.

foreach(const uint256& otherside, vMerkleBranch)

4265.

4266.

if (nIndex & 1)

4267.

hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash));

4268.

else

4269.

hash = Hash(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside));

4270.

nIndex >>= 1;

4271.

4272.

return hash;

4273.

4274.

bool WriteToDisk(bool fWriteTransactions, unsigned int& nFileRet, unsigned int& nBlockPosRet)

4275.

4276.

CAutoFile fileout = AppendBlockFile(nFileRet);

4277.

if (!fileout)

4278.
4279.

return error("CBlock::WriteToDisk() : AppendBlockFile failed");


if (!fWriteTransactions)

4280.

fileout.nType |= SER_BLOCKHEADERONLY;

4281.

unsigned int nSize = fileout.GetSerializeSize(*this);

4282.

fileout << FLATDATA(pchMessageStart) << nSize;

4283.

nBlockPosRet = ftell(fileout);

4284.

if (nBlockPosRet == -1)

4285.

return error("CBlock::WriteToDisk() : ftell failed");

4286.

fileout << *this;

4287.

return true;

4288.

4289.

bool ReadFromDisk(unsigned int nFile, unsigned int nBlockPos, bool fReadTransactions)

4290.

4291.

SetNull();

4292.

CAutoFile filein = OpenBlockFile(nFile, nBlockPos, "rb");

4293.

if (!filein)

4294.

return error("CBlock::ReadFromDisk() : OpenBlockFile failed");

4295.

if (!fReadTransactions)

4296.

filein.nType |= SER_BLOCKHEADERONLY;

4297.

filein >> *this;

4298.

if (CBigNum().SetCompact(nBits) > bnProofOfWorkLimit)

4299.

return error("CBlock::ReadFromDisk() : nBits errors in block header");

4300.

if (GetHash() > CBigNum().SetCompact(nBits).getuint256())

4301.

return error("CBlock::ReadFromDisk() : GetHash() errors in block header");

4302.

return true;

4303.

4304.

void print() const

4305.

4306.

printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%d)\n",

4307.

GetHash().ToString().substr(0,14).c_str(),

4308.

nVersion,

4309.

hashPrevBlock.ToString().substr(0,14).c_str(),

4310.

hashMerkleRoot.ToString().substr(0,6).c_str(),

4311.

nTime, nBits, nNonce,

4312.

vtx.size());

4313.

for (int i = 0; i < vtx.size(); i++)

4314.

4315.

printf(" ");

4316.

vtx[i].print();

4317.

4318.

printf(" vMerkleTree: ");

4319.

for (int i = 0; i < vMerkleTree.size(); i++)

4320.

printf("%s ", vMerkleTree[i].ToString().substr(0,6).c_str());

4321.

printf("\n");

4322.

4323.

int64 GetBlockValue(int64 nFees) const;

4324.

bool DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex);

4325.

bool ConnectBlock(CTxDB& txdb, CBlockIndex* pindex);

4326.

bool ReadFromDisk(const CBlockIndex* blockindex, bool fReadTransactions);

4327.

bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos);

4328.

bool CheckBlock() const;

4329.

bool AcceptBlock();

4330. };
4331. class CBlockIndex
4332. {
4333. public:
4334.

const uint256* phashBlock;

4335.

CBlockIndex* pprev;

4336.

CBlockIndex* pnext;

4337.

unsigned int nFile;

4338.

unsigned int nBlockPos;

4339.

int nHeight;

4340.

int nVersion;

4341.

uint256 hashMerkleRoot;

4342.

unsigned int nTime;

4343.

unsigned int nBits;

4344.

unsigned int nNonce;

4345.

CBlockIndex()

4346.

4347.

phashBlock = NULL;

4348.

pprev = NULL;

4349.

pnext = NULL;

4350.

nFile = 0;

4351.

nBlockPos = 0;

4352.

nHeight = 0;

4353.

nVersion

4354.

hashMerkleRoot = 0;

4355.

nTime

4356.

nBits

4357.

= 0;
= 0;
= 0;

nNonce

= 0;

4358.

4359.

CBlockIndex(unsigned int nFileIn, unsigned int nBlockPosIn, CBlock& block)

4360.

4361.

phashBlock = NULL;

4362.

pprev = NULL;

4363.

pnext = NULL;

4364.

nFile = nFileIn;

4365.

nBlockPos = nBlockPosIn;

4366.

nHeight = 0;

4367.

nVersion

4368.

hashMerkleRoot = block.hashMerkleRoot;

= block.nVersion;

4369.

nTime

4370.

nBits

4371.

= block.nTime;
= block.nBits;

nNonce

= block.nNonce;

4372.

4373.

uint256 GetBlockHash() const

4374.

4375.

return *phashBlock;

4376.

4377.

bool IsInMainChain() const

4378.

4379.

return (pnext || this == pindexBest);

4380.

4381.

bool EraseBlockFromDisk()

4382.

4383.

CAutoFile fileout = OpenBlockFile(nFile, nBlockPos, "rb+");

4384.

if (!fileout)

4385.

return false;

4386.

CBlock block;

4387.

block.SetNull();

4388.

fileout << block;

4389.

return true;

4390.

4391.

enum { nMedianTimeSpan=11 };

4392.

int64 GetMedianTimePast() const

4393.

4394.

unsigned int pmedian[nMedianTimeSpan];

4395.

unsigned int* pbegin = &pmedian[nMedianTimeSpan];

4396.

unsigned int* pend = &pmedian[nMedianTimeSpan];

4397.

const CBlockIndex* pindex = this;

4398.

for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev)

4399.

*(--pbegin) = pindex->nTime;

4400.

sort(pbegin, pend);

4401.

return pbegin[(pend - pbegin)/2];

4402.

4403.

int64 GetMedianTime() const

4404.

4405.

const CBlockIndex* pindex = this;

4406.

for (int i = 0; i < nMedianTimeSpan/2; i++)

4407.

4408.

if (!pindex->pnext)

4409.

return nTime;

4410.

pindex = pindex->pnext;

4411.

4412.

return pindex->GetMedianTimePast();

4413.

4414.

string ToString() const

4415.

4416.

return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)",

4417.

pprev, pnext, nFile, nBlockPos, nHeight,

4418.

hashMerkleRoot.ToString().substr(0,6).c_str(),

4419.

GetBlockHash().ToString().substr(0,14).c_str());

4420.

4421.

void print() const

4422.

4423.
4424.

printf("%s\n", ToString().c_str());
}

4425. };
4426. class CDiskBlockIndex : public CBlockIndex
4427. {
4428. public:
4429.

uint256 hashPrev;

4430.

uint256 hashNext;

4431.

CDiskBlockIndex()

4432.

4433.

hashPrev = 0;

4434.

hashNext = 0;

4435.

4436.

explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex)

4437.

4438.

hashPrev = (pprev ? pprev->GetBlockHash() : 0);

4439.

hashNext = (pnext ? pnext->GetBlockHash() : 0);

4440.

4441.

IMPLEMENT_SERIALIZE

4442.

4443.

if (!(nType & SER_GETHASH))

4444.

READWRITE(nVersion);

4445.

READWRITE(hashNext);

4446.

READWRITE(nFile);

4447.

READWRITE(nBlockPos);

4448.

READWRITE(nHeight);

4449.

READWRITE(this->nVersion);

4450.

READWRITE(hashPrev);

4451.

READWRITE(hashMerkleRoot);

4452.

READWRITE(nTime);

4453.

READWRITE(nBits);

4454.

READWRITE(nNonce);

4455.

4456.

uint256 GetBlockHash() const

4457.

4458.

CBlock block;

4459.

block.nVersion

4460.

block.hashPrevBlock = hashPrev;

4461.

block.hashMerkleRoot = hashMerkleRoot;

4462.

block.nTime

4463.

block.nBits

4464.

block.nNonce

4465.

return block.GetHash();

= nVersion;

= nTime;
= nBits;
= nNonce;

4466.

4467.

string ToString() const

4468.

4469.

string str = "CDiskBlockIndex(";

4470.

str += CBlockIndex::ToString();

4471.

str += strprintf("\n

hashBlock=%s, hashPrev=%s, hashNext=%s)",

4472.

GetBlockHash().ToString().c_str(),

4473.

hashPrev.ToString().substr(0,14).c_str(),

4474.

hashNext.ToString().substr(0,14).c_str());

4475.

return str;

4476.

4477.

void print() const

4478.

4479.
4480.

printf("%s\n", ToString().c_str());
}

4481. };
4482. class CBlockLocator
4483. {
4484. protected:
4485.

vector<uint256> vHave;

4486. public:
4487.

CBlockLocator()

4488.

4489.

4490.

explicit CBlockLocator(const CBlockIndex* pindex)

4491.

4492.

Set(pindex);

4493.

4494.

explicit CBlockLocator(uint256 hashBlock)

4495.

4496.

map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);

4497.

if (mi != mapBlockIndex.end())

4498.

Set((*mi).second);

4499.

4500.

IMPLEMENT_SERIALIZE

4501.

4502.

if (!(nType & SER_GETHASH))

4503.

READWRITE(nVersion);

4504.

READWRITE(vHave);

4505.

4506.

void Set(const CBlockIndex* pindex)

4507.

4508.

vHave.clear();

4509.

int nStep = 1;

4510.

while (pindex)

4511.

4512.

vHave.push_back(pindex->GetBlockHash());

4513.
4514.

for (int i = 0; pindex && i < nStep; i++)

4515.

pindex = pindex->pprev;

4516.

if (vHave.size() > 10)

4517.

nStep *= 2;

4518.

4519.

vHave.push_back(hashGenesisBlock);

4520.

4521.

CBlockIndex* GetBlockIndex()

4522.

4523.

foreach(const uint256& hash, vHave)

4524.

4525.

map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);

4526.

if (mi != mapBlockIndex.end())

4527.

4528.

CBlockIndex* pindex = (*mi).second;

4529.

if (pindex->IsInMainChain())

4530.

return pindex;

4531.

4532.

4533.
4534.

return pindexGenesisBlock;
}

4535.

uint256 GetBlockHash()

4536.

4537.

foreach(const uint256& hash, vHave)

4538.

4539.

map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);

4540.

if (mi != mapBlockIndex.end())

4541.

4542.

CBlockIndex* pindex = (*mi).second;

4543.

if (pindex->IsInMainChain())

4544.

return hash;

4545.

4546.

4547.

return hashGenesisBlock;

4548.

4549.

int GetHeight()

4550.

4551.

CBlockIndex* pindex = GetBlockIndex();

4552.

if (!pindex)

4553.

return 0;

4554.
4555.

return pindex->nHeight;
}

4556. };
4557. extern map<uint256, CTransaction> mapTransactions;
4558. extern map<uint256, CWalletTx> mapWallet;
4559. extern vector<pair<uint256, bool> > vWalletUpdated;
4560. extern CCriticalSection cs_mapWallet;
4561. extern map<vector<unsigned char>, CPrivKey> mapKeys;
4562. extern map<uint160, vector<unsigned char> > mapPubKeys;
4563. extern CCriticalSection cs_mapKeys;
4564. extern CKey keyUser;
4565. #include "headers.h"
4566. map<uint256, CProduct> mapMyProducts;
4567. map<uint256, CProduct> mapProducts;
4568. CCriticalSection cs_mapProducts;
4569. bool AdvertInsert(const CProduct& product)
4570. {
4571.

uint256 hash = product.GetHash();

4572.

bool fNew = false;

4573.

bool fUpdated = false;

4574.

CRITICAL_BLOCK(cs_mapProducts)

4575.

4576.

pair<map<uint256, CProduct>::iterator, bool> item = mapProducts.insert(make_pair(hash, product));

4577.

CProduct* pproduct = &(*(item.first)).second;

4578.

fNew = item.second;

4579.

if (product.nSequence > pproduct->nSequence)

4580.

4581.

*pproduct = product;

4582.

fUpdated = true;

4583.

4584.

4585.

return (fNew || fUpdated);

4586. }
4587. void AdvertErase(const CProduct& product)
4588. {
4589.

uint256 hash = product.GetHash();

4590.

CRITICAL_BLOCK(cs_mapProducts)

4591.

mapProducts.erase(hash);

4592. }
4593. template<typename T>
4594. unsigned int Union(T& v1, T& v2)
4595. {
4596.

T vUnion;

4597.

vUnion.reserve(v1.size() + v2.size());

4598.

set_union(v1.begin(), v1.end(),

4599.

v2.begin(), v2.end(),

4600.

back_inserter(vUnion));

4601.

unsigned int nAdded = vUnion.size() - v1.size();

4602.

if (nAdded > 0)

4603.

v1 = vUnion;

4604.

return nAdded;

4605. }
4606. void CUser::AddAtom(unsigned short nAtom, bool fOrigin)
4607. {
4608.

if (binary_search(vAtomsIn.begin(), vAtomsIn.end(), nAtom) ||

4609.

find(vAtomsNew.begin(), vAtomsNew.end(), nAtom) != vAtomsNew.end())

4610.

return;

4611.

if (nAtom == 0 || fOrigin)

4612.

4613.

vector<unsigned short> vTmp(1, nAtom);

4614.

Union(vAtomsIn, vTmp);

4615.

if (fOrigin)

4616.
4617.

vAtomsOut.push_back(nAtom);
return;

4618.

4619.

vAtomsNew.push_back(nAtom);

4620.

if (vAtomsNew.size() >= nFlowthroughRate || vAtomsOut.empty())

4621.

4622.

vAtomsOut.push_back(vAtomsNew[GetRand(vAtomsNew.size())]);

4623.

sort(vAtomsNew.begin(), vAtomsNew.end());

4624.

Union(vAtomsIn, vAtomsNew);

4625.
4626.

vAtomsNew.clear();
}

4627. }
4628. bool AddAtomsAndPropagate(uint256 hashUserStart, const vector<unsigned short>& vAtoms, bool fOrigin)
4629. {
4630.

CReviewDB reviewdb;

4631.

map<uint256, vector<unsigned short> > pmapPropagate[2];

4632.

pmapPropagate[0][hashUserStart] = vAtoms;

4633.

for (int side = 0; !pmapPropagate[side].empty(); side = 1 - side)

4634.

4635.

map<uint256, vector<unsigned short> >& mapFrom = pmapPropagate[side];

4636.

map<uint256, vector<unsigned short> >& mapTo = pmapPropagate[1 - side];

4637.

for (map<uint256, vector<unsigned short> >::iterator mi = mapFrom.begin(); mi != mapFrom.end(); ++mi)

4638.

4639.

const uint256& hashUser = (*mi).first;

4640.

const vector<unsigned short>& vReceived = (*mi).second;

4641.

CUser user;

4642.

reviewdb.ReadUser(hashUser, user);

4643.

unsigned int nIn = user.vAtomsIn.size();

4644.

unsigned int nNew = user.vAtomsNew.size();

4645.

unsigned int nOut = user.vAtomsOut.size();

4646.

foreach(unsigned short nAtom, vReceived)

4647.

user.AddAtom(nAtom, fOrigin);

4648.

fOrigin = false;

4649.

if (user.vAtomsIn.size() == nIn && user.vAtomsNew.size() == nNew)

4650.

continue;

4651.

if (user.vAtomsOut.size() > nOut)

4652.

foreach(const uint256& hash, user.vLinksOut)

4653.

mapTo[hash].insert(mapTo[hash].end(), user.vAtomsOut.begin() + nOut, user.vAtomsOut.end());

4654.

if (!reviewdb.WriteUser(hashUser, user))

4655.

return false;

4656.

4657.

mapFrom.clear();

4658.

4659.

return true;

4660. }
4661. bool CReview::AcceptReview()
4662. {
4663.

nTime = GetTime();

4664.

if (!CKey::Verify(vchPubKeyFrom, GetSigHash(), vchSig))

4665.

return false;

4666.

CReviewDB reviewdb;

4667.

vector<CReview> vReviews;

4668.

reviewdb.ReadReviews(hashTo, vReviews);

4669.

vReviews.push_back(*this);

4670.

if (!reviewdb.WriteReviews(hashTo, vReviews))

4671.

return false;

4672.

CUser user;

4673.

uint256 hashFrom = Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end());

4674.

reviewdb.ReadUser(hashFrom, user);

4675.

user.vLinksOut.push_back(hashTo);

4676.

if (!reviewdb.WriteUser(hashFrom, user))

4677.

return false;

4678.

reviewdb.Close();

4679.

vector<unsigned short> vZeroAtom(1, 0);

4680.

if (!AddAtomsAndPropagate(hashTo, user.vAtomsOut.size() ? user.vAtomsOut : vZeroAtom, false))

4681.
4682.

return false;
return true;

4683. }
4684. bool CProduct::CheckSignature()
4685. {
4686.

return (CKey::Verify(vchPubKeyFrom, GetSigHash(), vchSig));

4687. }
4688. bool CProduct::CheckProduct()
4689. {
4690.
4691.
4692.
4693.

if (!CheckSignature())
return false;
if (!mapDetails.empty() || !vOrderForm.empty())
return false;

4694.

CReviewDB reviewdb("r");

4695.

CUser user;

4696.

reviewdb.ReadUser(GetUserHash(), user);

4697.

nAtoms = user.GetAtomCount();

4698.

reviewdb.Close();

4699.

return true;

4700. }

4701. class CUser;


4702. class CReview;
4703. class CProduct;
4704. static const unsigned int nFlowthroughRate = 2;
4705. bool AdvertInsert(const CProduct& product);
4706. void AdvertErase(const CProduct& product);
4707. bool AddAtomsAndPropagate(uint256 hashUserStart, const vector<unsigned short>& vAtoms, bool fOrigin);
4708. class CUser
4709. {
4710. public:
4711.

vector<unsigned short> vAtomsIn;

4712.

vector<unsigned short> vAtomsNew;

4713.

vector<unsigned short> vAtomsOut;

4714.

vector<uint256> vLinksOut;

4715.

CUser()

4716.

4717.

4718.

IMPLEMENT_SERIALIZE

4719.

4720.

if (!(nType & SER_GETHASH))

4721.

READWRITE(nVersion);

4722.

READWRITE(vAtomsIn);

4723.

READWRITE(vAtomsNew);

4724.

READWRITE(vAtomsOut);

4725.

READWRITE(vLinksOut);

4726.

4727.

void SetNull()

4728.

4729.

vAtomsIn.clear();

4730.

vAtomsNew.clear();

4731.

vAtomsOut.clear();

4732.

vLinksOut.clear();

4733.

4734.

uint256 GetHash() const { return SerializeHash(*this); }

4735.

int GetAtomCount() const

4736.

4737.

return (vAtomsIn.size() + vAtomsNew.size());

4738.

4739.

void AddAtom(unsigned short nAtom, bool fOrigin);

4740. };
4741. class CReview
4742. {
4743. public:
4744.

int nVersion;

4745.

uint256 hashTo;

4746.

map<string, string> mapValue;

4747.

vector<unsigned char> vchPubKeyFrom;

4748.

vector<unsigned char> vchSig;

4749.

unsigned int nTime;

4750.

int nAtoms;

4751.

CReview()

4752.

4753.

nVersion = 1;

4754.

hashTo = 0;

4755.

nTime = 0;

4756.

nAtoms = 0;

4757.

4758.

IMPLEMENT_SERIALIZE

4759.

4760.

READWRITE(this->nVersion);

4761.

nVersion = this->nVersion;

4762.

if (!(nType & SER_DISK))

4763.

READWRITE(hashTo);

4764.

READWRITE(mapValue);

4765.

READWRITE(vchPubKeyFrom);

4766.

if (!(nType & SER_GETHASH))

4767.

READWRITE(vchSig);

4768.

4769.

uint256 GetHash() const { return SerializeHash(*this); }

4770.

uint256 GetSigHash() const { return SerializeHash(*this, SER_GETHASH|SER_SKIPSIG); }

4771.

uint256 GetUserHash() const { return Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end()); }

4772.

bool AcceptReview();

4773. };
4774. class CProduct
4775. {
4776. public:
4777.

int nVersion;

4778.

CAddress addr;

4779.

map<string, string> mapValue;

4780.

map<string, string> mapDetails;

4781.

vector<pair<string, string> > vOrderForm;

4782.

unsigned int nSequence;

4783.

vector<unsigned char> vchPubKeyFrom;

4784.

vector<unsigned char> vchSig;

4785.

int nAtoms;

4786.

set<unsigned int> setSources;

4787.

CProduct()

4788.

4789.

nVersion = 1;

4790.

nAtoms = 0;

4791.

nSequence = 0;

4792.

4793.

IMPLEMENT_SERIALIZE

4794.

4795.

READWRITE(this->nVersion);

4796.

nVersion = this->nVersion;

4797.

READWRITE(addr);

4798.

READWRITE(mapValue);

4799.

if (!(nType & SER_GETHASH))

4800.

4801.

READWRITE(mapDetails);

4802.

READWRITE(vOrderForm);

4803.

READWRITE(nSequence);

4804.

4805.

READWRITE(vchPubKeyFrom);

4806.

if (!(nType & SER_GETHASH))

4807.

READWRITE(vchSig);

4808.

if (nType & SER_DISK)

4809.

READWRITE(nAtoms);

4810.

4811.

uint256 GetHash() const { return SerializeHash(*this); }

4812.

uint256 GetSigHash() const { return SerializeHash(*this, SER_GETHASH|SER_SKIPSIG); }

4813.

uint256 GetUserHash() const { return Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end()); }

4814.

bool CheckSignature();

4815.

bool CheckProduct();

4816. };
4817. extern map<uint256, CProduct> mapProducts;
4818. extern CCriticalSection cs_mapProducts;
4819. extern map<uint256, CProduct> mapMyProducts;
4820. #include "headers.h"
4821. #include <winsock2.h>
4822. void ThreadMessageHandler2(void* parg);
4823. void ThreadSocketHandler2(void* parg);
4824. void ThreadOpenConnections2(void* parg);
4825. bool fClient = false;
4826. uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
4827. CAddress addrLocalHost(0, DEFAULT_PORT, nLocalServices);
4828. CNode nodeLocalHost(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices));
4829. CNode* pnodeLocalHost = &nodeLocalHost;
4830. bool fShutdown = false;
4831. array<bool, 10> vfThreadRunning;
4832. vector<CNode*> vNodes;
4833. CCriticalSection cs_vNodes;
4834. map<vector<unsigned char>, CAddress> mapAddresses;
4835. CCriticalSection cs_mapAddresses;
4836. map<CInv, CDataStream> mapRelay;
4837. deque<pair<int64, CInv> > vRelayExpiration;
4838. CCriticalSection cs_mapRelay;
4839. map<CInv, int64> mapAlreadyAskedFor;
4840. CAddress addrProxy;
4841. bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet)
4842. {
4843.

hSocketRet = INVALID_SOCKET;

4844.

SOCKET hSocket = socket(AF_INET, SOCK_STREAM, 0);

4845.

if (hSocket == INVALID_SOCKET)

4846.

return false;

4847.

bool fRoutable = !(addrConnect.GetByte(3) == 10 || (addrConnect.GetByte(3) == 192 && addrConnect.GetByte(2) == 168));

4848.

bool fProxy = (addrProxy.ip && fRoutable);

4849.

struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr());

4850.

if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)

4851.

4852.

closesocket(hSocket);

4853.

return false;

4854.

4855.

if (fProxy)

4856.

4857.

printf("Proxy connecting to %s\n", addrConnect.ToString().c_str());

4858.

char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";

4859.

memcpy(pszSocks4IP + 2, &addrConnect.port, 2);

4860.

memcpy(pszSocks4IP + 4, &addrConnect.ip, 4);

4861.

char* pszSocks4 = pszSocks4IP;

4862.

int nSize = sizeof(pszSocks4IP);

4863.

int ret = send(hSocket, pszSocks4, nSize, 0);

4864.

if (ret != nSize)

4865.

4866.

closesocket(hSocket);

4867.

return error("Error sending to proxy\n");

4868.

4869.

char pchRet[8];

4870.

if (recv(hSocket, pchRet, 8, 0) != 8)

4871.

4872.

closesocket(hSocket);

4873.

return error("Error reading proxy response\n");

4874.

4875.

if (pchRet[1] != 0x5a)

4876.

4877.

closesocket(hSocket);

4878.

return error("Proxy returned error %d\n", pchRet[1]);

4879.

4880.

printf("Proxy connection established %s\n", addrConnect.ToString().c_str());

4881.

4882.

hSocketRet = hSocket;

4883.

return true;

4884. }
4885. bool GetMyExternalIP(unsigned int& ipRet)
4886. {
4887.

CAddress addrConnect("72.233.89.199:80");

4888.

SOCKET hSocket;

4889.

if (!ConnectSocket(addrConnect, hSocket))

4890.
4891.

return error("GetMyExternalIP() : connection to %s failed\n", addrConnect.ToString().c_str());


char* pszGet =

4892.

"GET /automation/n09230945.asp HTTP/1.1\r\n"

4893.

"Host: www.whatismyip.com\r\n"

4894.

"User-Agent: Bitcoin/0.1\r\n"

4895.

"Connection: close\r\n"

4896.

"\r\n";

4897.

send(hSocket, pszGet, strlen(pszGet), 0);

4898.

string strLine;

4899.

while (RecvLine(hSocket, strLine))

4900.

4901.

if (strLine.empty())

4902.

4903.

if (!RecvLine(hSocket, strLine))

4904.

4905.

closesocket(hSocket);

4906.

return false;

4907.

4908.

closesocket(hSocket);

4909.

CAddress addr(strLine.c_str());

4910.

printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());

4911.

if (addr.ip == 0)

4912.

return false;

4913.

ipRet = addr.ip;

4914.

return true;

4915.

4916.

4917.

closesocket(hSocket);

4918.

return error("GetMyExternalIP() : connection closed\n");

4919. }
4920. bool AddAddress(CAddrDB& addrdb, const CAddress& addr)
4921. {
4922.

if (!addr.IsRoutable())

4923.
4924.

return false;
if (addr.ip == addrLocalHost.ip)

4925.

return false;

4926.

CRITICAL_BLOCK(cs_mapAddresses)

4927.

4928.

map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());

4929.

if (it == mapAddresses.end())

4930.

4931.

mapAddresses.insert(make_pair(addr.GetKey(), addr));

4932.

addrdb.WriteAddress(addr);

4933.

return true;

4934.

4935.

else

4936.

4937.

CAddress& addrFound = (*it).second;

4938.

if ((addrFound.nServices | addr.nServices) != addrFound.nServices)

4939.

4940.

addrFound.nServices |= addr.nServices;

4941.

addrdb.WriteAddress(addrFound);

4942.

return true;

4943.

4944.

4945.

4946.

return false;

4947. }
4948. void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
4949. {

4950.

CRITICAL_BLOCK(cs_vNodes)

4951.

4952.

foreach(CNode* pnode, vNodes)

4953.

4954.

CRITICAL_BLOCK(pnode->cs_mapRequests)

4955.

4956.

for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)

4957.

4958.

CRequestTracker& tracker = (*mi).second;

4959.

if (tracker.fn == fn && tracker.param1 == param1)

4960.

pnode->mapRequests.erase(mi++);

4961.

else

4962.

mi++;

4963.

4964.

4965.
4966.

}
}

4967. }
4968. bool AnySubscribed(unsigned int nChannel)
4969. {
4970.

if (pnodeLocalHost->IsSubscribed(nChannel))

4971.
4972.

return true;
CRITICAL_BLOCK(cs_vNodes)

4973.

foreach(CNode* pnode, vNodes)

4974.

if (pnode->IsSubscribed(nChannel))

4975.
4976.

return true;
return false;

4977. }
4978. bool CNode::IsSubscribed(unsigned int nChannel)
4979. {
4980.

if (nChannel >= vfSubscribe.size())

4981.
4982.

return false;
return vfSubscribe[nChannel];

4983. }
4984. void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
4985. {
4986.

if (nChannel >= vfSubscribe.size())

4987.

return;

4988.

if (!AnySubscribed(nChannel))

4989.

4990.

CRITICAL_BLOCK(cs_vNodes)

4991.

foreach(CNode* pnode, vNodes)

4992.

if (pnode != this)

4993.

pnode->PushMessage("subscribe", nChannel, nHops);

4994.

4995.

vfSubscribe[nChannel] = true;

4996. }
4997. void CNode::CancelSubscribe(unsigned int nChannel)
4998. {
4999.

if (nChannel >= vfSubscribe.size())

5000.
5001.

return;
if (!vfSubscribe[nChannel])

5002.

return;

5003.

vfSubscribe[nChannel] = false;

5004.

if (!AnySubscribed(nChannel))

5005.

5006.

CRITICAL_BLOCK(cs_vNodes)

5007.

foreach(CNode* pnode, vNodes)

5008.

if (pnode != this)

5009.

pnode->PushMessage("sub-cancel", nChannel);

5010.
5011.

if (nChannel == MSG_PRODUCT)

5012.

CRITICAL_BLOCK(cs_mapProducts)

5013.
5014.

mapProducts.clear();
}

5015. }
5016. CNode* FindNode(unsigned int ip)
5017. {
5018.

CRITICAL_BLOCK(cs_vNodes)

5019.

5020.

foreach(CNode* pnode, vNodes)

5021.

if (pnode->addr.ip == ip)

5022.

return (pnode);

5023.

5024.

return NULL;

5025. }
5026. CNode* FindNode(CAddress addr)
5027. {
5028.

CRITICAL_BLOCK(cs_vNodes)

5029.

5030.
5031.
5032.

foreach(CNode* pnode, vNodes)


if (pnode->addr == addr)
return (pnode);

5033.

5034.

return NULL;

5035. }
5036. CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
5037. {
5038.

if (addrConnect.ip == addrLocalHost.ip)

5039.

return NULL;

5040.

CNode* pnode = FindNode(addrConnect.ip);

5041.

if (pnode)

5042.

5043.

if (nTimeout != 0)

5044.

pnode->AddRef(nTimeout);

5045.

else

5046.

pnode->AddRef();

5047.

return pnode;

5048.

5049.

printf("trying %s\n", addrConnect.ToString().c_str());

5050.

SOCKET hSocket;

5051.

if (ConnectSocket(addrConnect, hSocket))

5052.

5053.

printf("connected %s\n", addrConnect.ToString().c_str());

5054.

CNode* pnode = new CNode(hSocket, addrConnect, false);

5055.

if (nTimeout != 0)

5056.

pnode->AddRef(nTimeout);

5057.

else

5058.

pnode->AddRef();

5059.

CRITICAL_BLOCK(cs_vNodes)

5060.

vNodes.push_back(pnode);

5061.

CRITICAL_BLOCK(cs_mapAddresses)

5062.

mapAddresses[addrConnect.GetKey()].nLastFailed = 0;

5063.

return pnode;

5064.

5065.

else

5066.

5067.

CRITICAL_BLOCK(cs_mapAddresses)

5068.

mapAddresses[addrConnect.GetKey()].nLastFailed = GetTime();

5069.
5070.

return NULL;
}

5071. }
5072. void CNode::Disconnect()
5073. {
5074.

printf("disconnecting node %s\n", addr.ToString().c_str());

5075.

closesocket(hSocket);

5076.

CRITICAL_BLOCK(cs_mapProducts)

5077.

for (map<uint256, CProduct>::iterator mi = mapProducts.begin(); mi != mapProducts.end();)

5078.

AdvertRemoveSource(this, MSG_PRODUCT, 0, (*(mi++)).second);

5079.

for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)

5080.

if (vfSubscribe[nChannel])

5081.

CancelSubscribe(nChannel);

5082. }
5083. void ThreadSocketHandler(void* parg)
5084. {
5085.

IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));

5086.

loop

5087.

5088.

vfThreadRunning[0] = true;

5089.

CheckForShutdown(0);

5090.

try

5091.

5092.

ThreadSocketHandler2(parg);

5093.

5094.

CATCH_PRINT_EXCEPTION("ThreadSocketHandler()")

5095.

vfThreadRunning[0] = false;

5096.
5097.

Sleep(5000);
}

5098. }
5099. void ThreadSocketHandler2(void* parg)
5100. {
5101.

printf("ThreadSocketHandler started\n");

5102.

SOCKET hListenSocket = *(SOCKET*)parg;

5103.

list<CNode*> vNodesDisconnected;

5104.

int nPrevNodeCount = 0;

5105.

loop

5106.

5107.

CRITICAL_BLOCK(cs_vNodes)

5108.

5109.

map<unsigned int, CNode*> mapFirst;

5110.

foreach(CNode* pnode, vNodes)

5111.

5112.
5113.

if (pnode->fDisconnect)
continue;

5114.

unsigned int ip = pnode->addr.ip;

5115.

if (mapFirst.count(ip) && addrLocalHost.ip < ip)

5116.

5117.

CNode* pnodeExtra = mapFirst[ip];

5118.

if (pnodeExtra->GetRefCount() > (pnodeExtra->fNetworkNode ? 1 : 0))

5119.

swap(pnodeExtra, pnode);

5120.

if (pnodeExtra->GetRefCount() <= (pnodeExtra->fNetworkNode ? 1 : 0))

5121.

5122.

printf("(%d nodes) disconnecting duplicate: %s\n", vNodes.size(), pnodeExtra->addr.ToString().c_str());

5123.

if (pnodeExtra->fNetworkNode && !pnode->fNetworkNode)

5124.

5125.

pnode->AddRef();

5126.

swap(pnodeExtra->fNetworkNode, pnode->fNetworkNode);

5127.

pnodeExtra->Release();

5128.

5129.

pnodeExtra->fDisconnect = true;

5130.

5131.

5132.

mapFirst[ip] = pnode;

5133.

5134.

vector<CNode*> vNodesCopy = vNodes;

5135.

foreach(CNode* pnode, vNodesCopy)

5136.

5137.

if (pnode->ReadyToDisconnect() && pnode->vRecv.empty() && pnode->vSend.empty())

5138.

5139.

vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());

5140.

pnode->Disconnect();

5141.

pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 5 * 60);

5142.

if (pnode->fNetworkNode)

5143.

pnode->Release();

5144.

vNodesDisconnected.push_back(pnode);

5145.

5146.

5147.

list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;

5148.

foreach(CNode* pnode, vNodesDisconnectedCopy)

5149.

5150.

if (pnode->GetRefCount() <= 0)

5151.

5152.

bool fDelete = false;

5153.

TRY_CRITICAL_BLOCK(pnode->cs_vSend)

5154.

TRY_CRITICAL_BLOCK(pnode->cs_vRecv)

5155.

TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)

5156.

TRY_CRITICAL_BLOCK(pnode->cs_inventory)

5157.

fDelete = true;

5158.

if (fDelete)

5159.

5160.

vNodesDisconnected.remove(pnode);

5161.

delete pnode;

5162.

5163.

5164.

5165.

5166.

if (vNodes.size() != nPrevNodeCount)

5167.

5168.

nPrevNodeCount = vNodes.size();

5169.

MainFrameRepaint();

5170.

5171.

struct timeval timeout;

5172.

timeout.tv_sec = 0;

5173.

timeout.tv_usec = 50000;

5174.

struct fd_set fdsetRecv;

5175.

struct fd_set fdsetSend;

5176.

FD_ZERO(&fdsetRecv);

5177.

FD_ZERO(&fdsetSend);

5178.

SOCKET hSocketMax = 0;

5179.

FD_SET(hListenSocket, &fdsetRecv);

5180.

hSocketMax = max(hSocketMax, hListenSocket);

5181.

CRITICAL_BLOCK(cs_vNodes)

5182.

5183.

foreach(CNode* pnode, vNodes)

5184.

5185.

FD_SET(pnode->hSocket, &fdsetRecv);

5186.

hSocketMax = max(hSocketMax, pnode->hSocket);

5187.

TRY_CRITICAL_BLOCK(pnode->cs_vSend)

5188.

if (!pnode->vSend.empty())

5189.

FD_SET(pnode->hSocket, &fdsetSend);

5190.

5191.

5192.

vfThreadRunning[0] = false;

5193.

int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, NULL, &timeout);

5194.

vfThreadRunning[0] = true;

5195.

CheckForShutdown(0);

5196.

if (nSelect == SOCKET_ERROR)

5197.

5198.

int nErr = WSAGetLastError();

5199.

printf("select failed: %d\n", nErr);

5200.

for (int i = 0; i <= hSocketMax; i++)

5201.

5202.

FD_SET(i, &fdsetRecv);

5203.

FD_SET(i, &fdsetSend);

5204.

5205.

Sleep(timeout.tv_usec/1000);

5206.

5207.

RandAddSeed();

5208.

if (FD_ISSET(hListenSocket, &fdsetRecv))

5209.

5210.

struct sockaddr_in sockaddr;

5211.

int len = sizeof(sockaddr);

5212.

SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);

5213.

CAddress addr(sockaddr);

5214.

if (hSocket == INVALID_SOCKET)

5215.

5216.

if (WSAGetLastError() != WSAEWOULDBLOCK)

5217.

printf("ERROR ThreadSocketHandler accept failed: %d\n", WSAGetLastError());

5218.

5219.

else

5220.

5221.

printf("accepted connection from %s\n", addr.ToString().c_str());

5222.

CNode* pnode = new CNode(hSocket, addr, true);

5223.

pnode->AddRef();

5224.

CRITICAL_BLOCK(cs_vNodes)

5225.

vNodes.push_back(pnode);

5226.

5227.

5228.

vector<CNode*> vNodesCopy;

5229.

CRITICAL_BLOCK(cs_vNodes)

5230.

vNodesCopy = vNodes;

5231.

foreach(CNode* pnode, vNodesCopy)

5232.

5233.

CheckForShutdown(0);

5234.

SOCKET hSocket = pnode->hSocket;

5235.

if (FD_ISSET(hSocket, &fdsetRecv))

5236.

5237.

TRY_CRITICAL_BLOCK(pnode->cs_vRecv)

5238.

5239.

CDataStream& vRecv = pnode->vRecv;

5240.

unsigned int nPos = vRecv.size();

5241.

const unsigned int nBufSize = 0x10000;

5242.

vRecv.resize(nPos + nBufSize);

5243.

int nBytes = recv(hSocket, &vRecv[nPos], nBufSize, 0);

5244.

vRecv.resize(nPos + max(nBytes, 0));

5245.

if (nBytes == 0)

5246.

5247.

if (!pnode->fDisconnect)

5248.

printf("recv: socket closed\n");

5249.

pnode->fDisconnect = true;

5250.

5251.

else if (nBytes < 0)

5252.

5253.

int nErr = WSAGetLastError();

5254.

if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)

5255.

5256.

if (!pnode->fDisconnect)

5257.

printf("recv failed: %d\n", nErr);

5258.

pnode->fDisconnect = true;

5259.

5260.

5261.

5262.

5263.

if (FD_ISSET(hSocket, &fdsetSend))

5264.

5265.

TRY_CRITICAL_BLOCK(pnode->cs_vSend)

5266.

5267.

CDataStream& vSend = pnode->vSend;

5268.

if (!vSend.empty())

5269.

5270.

int nBytes = send(hSocket, &vSend[0], vSend.size(), 0);

5271.

if (nBytes > 0)

5272.

5273.

vSend.erase(vSend.begin(), vSend.begin() + nBytes);

5274.

5275.

else if (nBytes == 0)

5276.

5277.

if (pnode->ReadyToDisconnect())

5278.

pnode->vSend.clear();

5279.

5280.

else

5281.

5282.

printf("send error %d\n", nBytes);

5283.

if (pnode->ReadyToDisconnect())

5284.

pnode->vSend.clear();

5285.

5286.

5287.

5288.

5289.

5290.
5291.

Sleep(10);
}

5292. }
5293. void ThreadOpenConnections(void* parg)
5294. {
5295.

IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));

5296.

loop

5297.

5298.

vfThreadRunning[1] = true;

5299.

CheckForShutdown(1);

5300.

try

5301.

5302.

ThreadOpenConnections2(parg);

5303.

5304.

CATCH_PRINT_EXCEPTION("ThreadOpenConnections()")

5305.

vfThreadRunning[1] = false;

5306.
5307.

Sleep(5000);
}

5308. }
5309. void ThreadOpenConnections2(void* parg)
5310. {
5311.

printf("ThreadOpenConnections started\n");

5312.

const int nMaxConnections = 15;

5313.

loop

5314.

5315.

vfThreadRunning[1] = false;

5316.

Sleep(500);

5317.

while (vNodes.size() >= nMaxConnections || vNodes.size() >= mapAddresses.size())

5318.

5319.

CheckForShutdown(1);

5320.

Sleep(2000);

5321.

5322.

vfThreadRunning[1] = true;

5323.

CheckForShutdown(1);

5324.

unsigned char pchIPCMask[4] = { 0xff, 0xff, 0xff, 0x00 };

5325.

unsigned int nIPCMask = *(unsigned int*)pchIPCMask;

5326.

vector<unsigned int> vIPC;

5327.

CRITICAL_BLOCK(cs_mapAddresses)

5328.

5329.

vIPC.reserve(mapAddresses.size());

5330.

unsigned int nPrev = 0;

5331.

foreach(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)

5332.

5333.

const CAddress& addr = item.second;

5334.

if (!addr.IsIPv4())

5335.

continue;

5336.

unsigned int ipC = addr.ip & nIPCMask;

5337.

if (ipC != nPrev)

5338.

vIPC.push_back(nPrev = ipC);

5339.

5340.

5341.

bool fSuccess = false;

5342.

int nLimit = vIPC.size();

5343.

while (!fSuccess && nLimit-- > 0)

5344.

5345.

unsigned int ipC = vIPC[GetRand(vIPC.size())];

5346.

map<unsigned int, vector<CAddress> > mapIP;

5347.

CRITICAL_BLOCK(cs_mapAddresses)

5348.

5349.

unsigned int nDelay = ((30 * 60) << vNodes.size());

5350.

if (nDelay > 8 * 60 * 60)

5351.

nDelay = 8 * 60 * 60;

5352.

for (map<vector<unsigned char>, CAddress>::iterator mi = mapAddresses.lower_bound(CAddress(ipC, 0).GetKey());

5353.

mi != mapAddresses.upper_bound(CAddress(ipC | ~nIPCMask, 0xffff).GetKey());

5354.

++mi)

5355.

5356.

const CAddress& addr = (*mi).second;

5357.

unsigned int nRandomizer = (addr.nLastFailed * addr.ip * 7777U) % 20000;

5358.

if (GetTime() - addr.nLastFailed > nDelay * nRandomizer / 10000)

5359.

mapIP[addr.ip].push_back(addr);

5360.

5361.

5362.

if (mapIP.empty())

5363.
5364.

break;
map<unsigned int, vector<CAddress> >::iterator mi = mapIP.begin();

5365.

advance(mi, GetRand(mapIP.size()));

5366.

foreach(const CAddress& addrConnect, (*mi).second)

5367.

5368.

if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))

5369.

continue;

5370.

CNode* pnode = ConnectNode(addrConnect);

5371.

if (!pnode)

5372.

continue;

5373.

pnode->fNetworkNode = true;

5374.

if (addrLocalHost.IsRoutable())

5375.

5376.

vector<CAddress> vAddrToSend;

5377.

vAddrToSend.push_back(addrLocalHost);

5378.

pnode->PushMessage("addr", vAddrToSend);

5379.

5380.

pnode->PushMessage("getaddr");

5381.

const unsigned int nHops = 0;

5382.

for (unsigned int nChannel = 0; nChannel < pnodeLocalHost->vfSubscribe.size(); nChannel++)

5383.

if (pnodeLocalHost->vfSubscribe[nChannel])

5384.

pnode->PushMessage("subscribe", nChannel, nHops);

5385.

fSuccess = true;

5386.

break;

5387.

5388.
5389.

}
}

5390. }
5391. void ThreadMessageHandler(void* parg)
5392. {
5393.

IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));

5394.

loop

5395.

5396.

vfThreadRunning[2] = true;

5397.

CheckForShutdown(2);

5398.

try

5399.

5400.

ThreadMessageHandler2(parg);

5401.

5402.

CATCH_PRINT_EXCEPTION("ThreadMessageHandler()")

5403.

vfThreadRunning[2] = false;

5404.
5405.

Sleep(5000);
}

5406. }
5407. void ThreadMessageHandler2(void* parg)
5408. {
5409.

printf("ThreadMessageHandler started\n");

5410.

SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL);

5411.

loop

5412.

5413.

vector<CNode*> vNodesCopy;

5414.

CRITICAL_BLOCK(cs_vNodes)

5415.

vNodesCopy = vNodes;

5416.

foreach(CNode* pnode, vNodesCopy)

5417.

5418.

pnode->AddRef();

5419.

TRY_CRITICAL_BLOCK(pnode->cs_vRecv)

5420.

ProcessMessages(pnode);

5421.

TRY_CRITICAL_BLOCK(pnode->cs_vSend)

5422.

SendMessages(pnode);

5423.

pnode->Release();

5424.

5425.

vfThreadRunning[2] = false;

5426.

Sleep(100);

5427.

vfThreadRunning[2] = true;

5428.
5429.

CheckForShutdown(2);
}

5430. }
5431. void ThreadBitcoinMiner(void* parg)
5432. {
5433.

vfThreadRunning[3] = true;

5434.

CheckForShutdown(3);

5435.

try

5436.

5437.

bool fRet = BitcoinMiner();

5438.

printf("BitcoinMiner returned %s\n\n\n", fRet ? "true" : "false");

5439.

5440.

CATCH_PRINT_EXCEPTION("BitcoinMiner()")

5441.

vfThreadRunning[3] = false;

5442. }
5443. bool StartNode(string& strError)
5444. {
5445.

strError = "";

5446.

WSADATA wsadata;

5447.

int ret = WSAStartup(MAKEWORD(2,2), &wsadata);

5448.

if (ret != NO_ERROR)

5449.

5450.

strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);

5451.

printf("%s\n", strError.c_str());

5452.

return false;

5453.

5454.

char pszHostName[255];

5455.

if (gethostname(pszHostName, 255) == SOCKET_ERROR)

5456.

5457.

strError = strprintf("Error: Unable to get IP address of this computer (gethostname returned error %d)", WSAGetLastError());

5458.

printf("%s\n", strError.c_str());

5459.

return false;

5460.

5461.

struct hostent* pHostEnt = gethostbyname(pszHostName);

5462.

if (!pHostEnt)

5463.

5464.

strError = strprintf("Error: Unable to get IP address of this computer (gethostbyname returned error %d)", WSAGetLastError());

5465.

printf("%s\n", strError.c_str());

5466.

return false;

5467.

5468.

addrLocalHost = CAddress(*(long*)(pHostEnt->h_addr_list[0]),

5469.

DEFAULT_PORT,

5470.

nLocalServices);

5471.

printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());

5472.

SOCKET hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

5473.

if (hListenSocket == INVALID_SOCKET)

5474.

5475.

strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());

5476.

printf("%s\n", strError.c_str());

5477.

return false;

5478.

5479.

u_long nOne = 1;

5480.

if (ioctlsocket(hListenSocket, FIONBIO, &nOne) == SOCKET_ERROR)

5481.

5482.

strError = strprintf("Error: Couldn't set properties on socket for incoming connections (ioctlsocket returned error %d)", WSAGetLastError());

5483.

printf("%s\n", strError.c_str());

5484.

return false;

5485.

5486.

int nRetryLimit = 15;

5487.

struct sockaddr_in sockaddr = addrLocalHost.GetSockAddr();

5488.

if (bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)

5489.

5490.

int nErr = WSAGetLastError();

5491.

if (nErr == WSAEADDRINUSE)

5492.

strError = strprintf("Error: Unable to bind to port %s on this computer. The program is probably already running.",
addrLocalHost.ToString().c_str());

5493.

else

5494.

strError = strprintf("Error: Unable to bind to port %s on this computer (bind returned error %d)", addrLocalHost.ToString().c_str(), nErr);

5495.

printf("%s\n", strError.c_str());

5496.

return false;

5497.

5498.

printf("bound to addrLocalHost = %s\n\n", addrLocalHost.ToString().c_str());

5499.

if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)

5500.

5501.

strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());

5502.

printf("%s\n", strError.c_str());

5503.

return false;

5504.

5505.

if (addrIncoming.ip)

5506.

addrLocalHost.ip = addrIncoming.ip;

5507.

if (GetMyExternalIP(addrLocalHost.ip))

5508.

5509.

addrIncoming = addrLocalHost;

5510.

CWalletDB().WriteSetting("addrIncoming", addrIncoming);

5511.

5512.

if (_beginthread(ThreadIRCSeed, 0, NULL) == -1)

5513.

printf("Error: _beginthread(ThreadIRCSeed) failed\n");

5514.

if (_beginthread(ThreadSocketHandler, 0, new SOCKET(hListenSocket)) == -1)

5515.

5516.

strError = "Error: _beginthread(ThreadSocketHandler) failed";

5517.

printf("%s\n", strError.c_str());

5518.

return false;

5519.

5520.

if (_beginthread(ThreadOpenConnections, 0, NULL) == -1)

5521.

5522.

strError = "Error: _beginthread(ThreadOpenConnections) failed";

5523.

printf("%s\n", strError.c_str());

5524.

return false;

5525.

5526.

if (_beginthread(ThreadMessageHandler, 0, NULL) == -1)

5527.

5528.

strError = "Error: _beginthread(ThreadMessageHandler) failed";

5529.

printf("%s\n", strError.c_str());

5530.

return false;

5531.

5532.

return true;

5533. }
5534. bool StopNode()
5535. {
5536.

printf("StopNode()\n");

5537.

fShutdown = true;

5538.

nTransactionsUpdated++;

5539.

while (count(vfThreadRunning.begin(), vfThreadRunning.end(), true))

5540.

Sleep(10);

5541.

Sleep(50);

5542.

WSACleanup();

5543.

return true;

5544. }
5545. void CheckForShutdown(int n)
5546. {
5547.

if (fShutdown)

5548.

5549.

if (n != -1)

5550.

vfThreadRunning[n] = false;

5551.
5552.

_endthread();
}

5553. }
5554. class CMessageHeader;
5555. class CAddress;
5556. class CInv;
5557. class CRequestTracker;
5558. class CNode;
5559. static const unsigned short DEFAULT_PORT = htons(8333);
5560. static const unsigned int PUBLISH_HOPS = 5;
5561. enum
5562. {
5563.

NODE_NETWORK = (1 << 0),

5564. };
5565. bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet);
5566. bool GetMyExternalIP(unsigned int& ipRet);
5567. bool AddAddress(CAddrDB& addrdb, const CAddress& addr);
5568. CNode* FindNode(unsigned int ip);
5569. CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0);
5570. void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1);
5571. bool AnySubscribed(unsigned int nChannel);
5572. void ThreadBitcoinMiner(void* parg);
5573. bool StartNode(string& strError=REF(string()));
5574. bool StopNode();
5575. void CheckForShutdown(int n);
5576. static const char pchMessageStart[4] = { 0xf9, 0xbe, 0xb4, 0xd9 };
5577. class CMessageHeader
5578. {
5579. public:
5580.

enum { COMMAND_SIZE=12 };

5581.

char pchMessageStart[sizeof(::pchMessageStart)];

5582.

char pchCommand[COMMAND_SIZE];

5583.

unsigned int nMessageSize;

5584.

CMessageHeader()

5585.

5586.

memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart));

5587.

memset(pchCommand, 0, sizeof(pchCommand));

5588.

pchCommand[1] = 1;

5589.

nMessageSize = -1;

5590.

5591.

CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn)

5592.

5593.

memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart));

5594.

strncpy(pchCommand, pszCommand, COMMAND_SIZE);

5595.

nMessageSize = nMessageSizeIn;

5596.

5597.

IMPLEMENT_SERIALIZE

5598.

5599.

READWRITE(FLATDATA(pchMessageStart));

5600.

READWRITE(FLATDATA(pchCommand));

5601.

READWRITE(nMessageSize);

5602.

5603.

string GetCommand()

5604.

5605.

if (pchCommand[COMMAND_SIZE-1] == 0)

5606.

return string(pchCommand, pchCommand + strlen(pchCommand));

5607.

else

5608.

return string(pchCommand, pchCommand + COMMAND_SIZE);

5609.

5610.

bool IsValid()

5611.

5612.

if (memcmp(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)) != 0)

5613.

return false;

5614.

for (char* p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; p1++)

5615.

5616.

if (*p1 == 0)

5617.

5618.

for (; p1 < pchCommand + COMMAND_SIZE; p1++)

5619.

if (*p1 != 0)

5620.

return false;

5621.

5622.

else if (*p1 < ' ' || *p1 > 0x7E)

5623.

return false;

5624.

5625.

if (nMessageSize > 0x10000000)

5626.

5627.

printf("CMessageHeader::IsValid() : nMessageSize too large %u\n", nMessageSize);

5628.

return false;

5629.

5630.
5631.

return true;
}

5632. };
5633. static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
5634. class CAddress
5635. {
5636. public:
5637.

uint64 nServices;

5638.

unsigned char pchReserved[12];

5639.

unsigned int ip;

5640.

unsigned short port;

5641.

unsigned int nTime;

5642.

unsigned int nLastFailed;

5643.

CAddress()

5644.

5645.

nServices = 0;

5646.

memcpy(pchReserved, pchIPv4, sizeof(pchReserved));

5647.

ip = 0;

5648.

port = DEFAULT_PORT;

5649.

nTime = GetAdjustedTime();

5650.

nLastFailed = 0;

5651.

5652.

CAddress(unsigned int ipIn, unsigned short portIn, uint64 nServicesIn=0)

5653.

5654.

nServices = nServicesIn;

5655.

memcpy(pchReserved, pchIPv4, sizeof(pchReserved));

5656.

ip = ipIn;

5657.

port = portIn;

5658.

nTime = GetAdjustedTime();

5659.

nLastFailed = 0;

5660.

5661.

explicit CAddress(const struct sockaddr_in& sockaddr, uint64 nServicesIn=0)

5662.

5663.

nServices = nServicesIn;

5664.

memcpy(pchReserved, pchIPv4, sizeof(pchReserved));

5665.

ip = sockaddr.sin_addr.s_addr;

5666.

port = sockaddr.sin_port;

5667.

nTime = GetAdjustedTime();

5668.

nLastFailed = 0;

5669.

5670.

explicit CAddress(const char* pszIn, uint64 nServicesIn=0)

5671.

5672.

nServices = nServicesIn;

5673.

memcpy(pchReserved, pchIPv4, sizeof(pchReserved));

5674.

ip = 0;

5675.

port = DEFAULT_PORT;

5676.

nTime = GetAdjustedTime();

5677.

nLastFailed = 0;

5678.

char psz[100];

5679.

if (strlen(pszIn) > ARRAYLEN(psz)-1)

5680.

return;

5681.

strcpy(psz, pszIn);

5682.

unsigned int a, b, c, d, e;

5683.

if (sscanf(psz, "%u.%u.%u.%u:%u", &a, &b, &c, &d, &e) < 4)

5684.

return;

5685.

char* pszPort = strchr(psz, ':');

5686.

if (pszPort)

5687.

5688.

*pszPort++ = '\0';

5689.

port = htons(atoi(pszPort));

5690.

5691.

ip = inet_addr(psz);

5692.

5693.

IMPLEMENT_SERIALIZE

5694.

5695.

if (nType & SER_DISK)

5696.

5697.

READWRITE(nVersion);

5698.

READWRITE(nTime);

5699.

5700.

READWRITE(nServices);

5701.

READWRITE(FLATDATA(pchReserved));

5702.

READWRITE(ip);

5703.

READWRITE(port);

5704.

5705.

friend inline bool operator==(const CAddress& a, const CAddress& b)

5706.

5707.

return (memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved)) == 0 &&

5708.

a.ip == b.ip &&

5709.

a.port == b.port);

5710.

5711.

friend inline bool operator<(const CAddress& a, const CAddress& b)

5712.

5713.

int ret = memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved));

5714.

if (ret < 0)

5715.

return true;

5716.

else if (ret == 0)

5717.

5718.

if (ntohl(a.ip) < ntohl(b.ip))

5719.

return true;

5720.

else if (a.ip == b.ip)

5721.

return ntohs(a.port) < ntohs(b.port);

5722.

5723.

return false;

5724.

5725.

vector<unsigned char> GetKey() const

5726.

5727.

CDataStream ss;

5728.

ss.reserve(18);

5729.

ss << FLATDATA(pchReserved) << ip << port;

5730.
5731.

#if defined(_MSC_VER) && _MSC_VER < 1300

5732.

return vector<unsigned char>((unsigned char*)&ss.begin()[0], (unsigned char*)&ss.end()[0]);

5733.

#else

5734.

return vector<unsigned char>(ss.begin(), ss.end());

5735.

#endif

5736.

5737.

struct sockaddr_in GetSockAddr() const

5738.

5739.

struct sockaddr_in sockaddr;

5740.

sockaddr.sin_family = AF_INET;

5741.

sockaddr.sin_addr.s_addr = ip;

5742.

sockaddr.sin_port = port;

5743.

return sockaddr;

5744.

5745.

bool IsIPv4() const

5746.

5747.

return (memcmp(pchReserved, pchIPv4, sizeof(pchIPv4)) == 0);

5748.

5749.

bool IsRoutable() const

5750.

5751.

return !(GetByte(3) == 10 || (GetByte(3) == 192 && GetByte(2) == 168));

5752.

5753.

unsigned char GetByte(int n) const

5754.

5755.

return ((unsigned char*)&ip)[3-n];

5756.

5757.

string ToStringIPPort() const

5758.

5759.

return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port));

5760.

5761.

string ToStringIP() const

5762.

5763.

return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0));

5764.

5765.

string ToString() const

5766.

5767.

return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port));

5768.

5769.

void print() const

5770.

5771.
5772.

printf("CAddress(%s)\n", ToString().c_str());
}

5773. };
5774. enum
5775. {
5776.

MSG_TX = 1,

5777.

MSG_BLOCK,

5778.

MSG_REVIEW,

5779.

MSG_PRODUCT,

5780.

MSG_TABLE,

5781. };
5782. static const char* ppszTypeName[] =
5783. {
5784.

"ERROR",

5785.

"tx",

5786.

"block",

5787.

"review",

5788.

"product",

5789.

"table",

5790. };
5791. class CInv
5792. {
5793. public:
5794.

int type;

5795.

uint256 hash;

5796.

CInv()

5797.

5798.

type = 0;

5799.

hash = 0;

5800.

5801.

CInv(int typeIn, const uint256& hashIn)

5802.

5803.

type = typeIn;

5804.

hash = hashIn;

5805.

5806.

CInv(const string& strType, const uint256& hashIn)

5807.

5808.

int i;

5809.

for (i = 1; i < ARRAYLEN(ppszTypeName); i++)

5810.

5811.

if (strType == ppszTypeName[i])

5812.

5813.

type = i;

5814.

break;

5815.

5816.

5817.

if (i == ARRAYLEN(ppszTypeName))

5818.

throw std::out_of_range(strprintf("CInv::CInv(string, uint256) : unknown type '%s'", strType.c_str()));

5819.

hash = hashIn;

5820.

5821.

IMPLEMENT_SERIALIZE

5822.

5823.

READWRITE(type);

5824.

READWRITE(hash);

5825.

5826.

friend inline bool operator<(const CInv& a, const CInv& b)

5827.

5828.

return (a.type < b.type || (a.type == b.type && a.hash < b.hash));

5829.

5830.

bool IsKnownType() const

5831.

5832.

return (type >= 1 && type < ARRAYLEN(ppszTypeName));

5833.

5834.

const char* GetCommand() const

5835.

5836.

if (!IsKnownType())

5837.

throw std::out_of_range(strprintf("CInv::GetCommand() : type=% unknown type", type));

5838.

return ppszTypeName[type];

5839.

5840.

string ToString() const

5841.

5842.

return strprintf("%s %s", GetCommand(), hash.ToString().substr(0,14).c_str());

5843.

5844.

void print() const

5845.

5846.
5847.

printf("CInv(%s)\n", ToString().c_str());
}

5848. };
5849. class CRequestTracker
5850. {
5851. public:
5852.

void (*fn)(void*, CDataStream&);

5853.

void* param1;

5854.

explicit CRequestTracker(void (*fnIn)(void*, CDataStream&)=NULL, void* param1In=NULL)

5855.

5856.

fn = fnIn;

5857.

param1 = param1In;

5858.

5859.

bool IsNull()

5860.

5861.

return fn == NULL;

5862.

5863. };
5864. extern bool fClient;
5865. extern uint64 nLocalServices;
5866. extern CAddress addrLocalHost;
5867. extern CNode* pnodeLocalHost;
5868. extern bool fShutdown;
5869. extern array<bool, 10> vfThreadRunning;
5870. extern vector<CNode*> vNodes;
5871. extern CCriticalSection cs_vNodes;
5872. extern map<vector<unsigned char>, CAddress> mapAddresses;
5873. extern CCriticalSection cs_mapAddresses;
5874. extern map<CInv, CDataStream> mapRelay;
5875. extern deque<pair<int64, CInv> > vRelayExpiration;
5876. extern CCriticalSection cs_mapRelay;
5877. extern map<CInv, int64> mapAlreadyAskedFor;
5878. extern CAddress addrProxy;
5879. class CNode
5880. {
5881. public:
5882.

uint64 nServices;

5883.

SOCKET hSocket;

5884.

CDataStream vSend;

5885.

CDataStream vRecv;

5886.

CCriticalSection cs_vSend;

5887.

CCriticalSection cs_vRecv;

5888.

unsigned int nPushPos;

5889.

CAddress addr;

5890.

int nVersion;

5891.

bool fClient;

5892.

bool fInbound;

5893.

bool fNetworkNode;

5894.

bool fDisconnect;

5895. protected:
5896.

int nRefCount;

5897. public:
5898.

int64 nReleaseTime;

5899.

map<uint256, CRequestTracker> mapRequests;

5900.

CCriticalSection cs_mapRequests;

5901.

vector<CAddress> vAddrToSend;

5902.

set<CAddress> setAddrKnown;

5903.

set<CInv> setInventoryKnown;

5904.

set<CInv> setInventoryKnown2;

5905.

vector<CInv> vInventoryToSend;

5906.

CCriticalSection cs_inventory;

5907.

multimap<int64, CInv> mapAskFor;

5908.

vector<char> vfSubscribe;

5909.

CNode(SOCKET hSocketIn, CAddress addrIn, bool fInboundIn=false)

5910.

5911.

nServices = 0;

5912.

hSocket = hSocketIn;

5913.

vSend.SetType(SER_NETWORK);

5914.

vRecv.SetType(SER_NETWORK);

5915.

nPushPos = -1;

5916.

addr = addrIn;

5917.

nVersion = 0;

5918.

fClient = false;

5919.

fInbound = fInboundIn;

5920.

fNetworkNode = false;

5921.

fDisconnect = false;

5922.

nRefCount = 0;

5923.

nReleaseTime = 0;

5924.

vfSubscribe.assign(256, false);

5925.

int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());

5926.

PushMessage("version", VERSION, nLocalServices, nTime, addr);

5927.

5928.

~CNode()

5929.

5930.

if (hSocket != INVALID_SOCKET)

5931.
5932.

closesocket(hSocket);
}

5933. private:
5934.

CNode(const CNode&);

5935.

void operator=(const CNode&);

5936. public:
5937.

bool ReadyToDisconnect()

5938.

5939.

return fDisconnect || GetRefCount() <= 0;

5940.

5941.

int GetRefCount()

5942.

5943.
5944.

return max(nRefCount, 0) + (GetTime() < nReleaseTime ? 1 : 0);


}

5945.

void AddRef(int64 nTimeout=0)

5946.

5947.

if (nTimeout != 0)

5948.

nReleaseTime = max(nReleaseTime, GetTime() + nTimeout);

5949.

else

5950.

nRefCount++;

5951.

5952.

void Release()

5953.

5954.

nRefCount--;

5955.

5956.

void AddInventoryKnown(const CInv& inv)

5957.

5958.

CRITICAL_BLOCK(cs_inventory)

5959.

setInventoryKnown.insert(inv);

5960.

5961.

void PushInventory(const CInv& inv)

5962.

5963.

CRITICAL_BLOCK(cs_inventory)

5964.

if (!setInventoryKnown.count(inv))

5965.

vInventoryToSend.push_back(inv);

5966.

5967.

void AskFor(const CInv& inv)

5968.

5969.

int64& nRequestTime = mapAlreadyAskedFor[inv];

5970.

printf("askfor %s %I64d\n", inv.ToString().c_str(), nRequestTime);

5971.

int64 nNow = (GetTime() - 1) * 1000000;

5972.

static int64 nLastTime;

5973.

nLastTime = nNow = max(nNow, ++nLastTime);

5974.

nRequestTime = max(nRequestTime + 2 * 60 * 1000000, nNow);

5975.

mapAskFor.insert(make_pair(nRequestTime, inv));

5976.

5977.

void BeginMessage(const char* pszCommand)

5978.

5979.

EnterCriticalSection(&cs_vSend);

5980.

if (nPushPos != -1)

5981.

AbortMessage();

5982.

nPushPos = vSend.size();

5983.

vSend << CMessageHeader(pszCommand, 0);

5984.

printf("sending: %-12s ", pszCommand);

5985.

5986.

void AbortMessage()

5987.

5988.

if (nPushPos == -1)

5989.

return;

5990.

vSend.resize(nPushPos);

5991.

nPushPos = -1;

5992.

LeaveCriticalSection(&cs_vSend);

5993.

printf("(aborted)\n");

5994.

5995.

void EndMessage()

5996.

5997.

extern int nDropMessagesTest;

5998.

if (nDropMessagesTest > 0 && GetRand(nDropMessagesTest) == 0)

5999.

6000.

printf("dropmessages DROPPING SEND MESSAGE\n");

6001.

AbortMessage();

6002.

return;

6003.

6004.

if (nPushPos == -1)

6005.

return;

6006.

unsigned int nSize = vSend.size() - nPushPos - sizeof(CMessageHeader);

6007.

memcpy((char*)&vSend[nPushPos] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize));

6008.

printf("(%d bytes) ", nSize);

6009.

printf("\n");

6010.

nPushPos = -1;

6011.

LeaveCriticalSection(&cs_vSend);

6012.

6013.

void EndMessageAbortIfEmpty()

6014.

6015.

if (nPushPos == -1)

6016.

return;

6017.

int nSize = vSend.size() - nPushPos - sizeof(CMessageHeader);

6018.

if (nSize > 0)

6019.

EndMessage();

6020.

else

6021.

AbortMessage();

6022.

6023.

const char* GetMessageCommand() const

6024.

6025.
6026.
6027.

if (nPushPos == -1)
return "";
return &vSend[nPushPos] + offsetof(CMessageHeader, pchCommand);

6028.

6029.

void PushMessage(const char* pszCommand)

6030.

6031.

try

6032.

6033.

BeginMessage(pszCommand);

6034.

EndMessage();

6035.

6036.

catch (...)

6037.

6038.

AbortMessage();

6039.

throw;

6040.

6041.

6042.

template<typename T1>

6043.

void PushMessage(const char* pszCommand, const T1& a1)

6044.

6045.

try

6046.

6047.

BeginMessage(pszCommand);

6048.

vSend << a1;

6049.

EndMessage();

6050.

6051.

catch (...)

6052.

6053.

AbortMessage();

6054.

throw;

6055.

6056.

6057.

template<typename T1, typename T2>

6058.

void PushMessage(const char* pszCommand, const T1& a1, const T2& a2)

6059.

6060.

try

6061.

6062.

BeginMessage(pszCommand);

6063.

vSend << a1 << a2;

6064.

EndMessage();

6065.

6066.

catch (...)

6067.

6068.

AbortMessage();

6069.

throw;

6070.

6071.

6072.

template<typename T1, typename T2, typename T3>

6073.

void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3)

6074.

6075.

try

6076.

6077.

BeginMessage(pszCommand);

6078.

vSend << a1 << a2 << a3;

6079.

EndMessage();

6080.

6081.

catch (...)

6082.

6083.

AbortMessage();

6084.

throw;

6085.

6086.

6087.

template<typename T1, typename T2, typename T3, typename T4>

6088.

void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4)

6089.

6090.

try

6091.

6092.

BeginMessage(pszCommand);

6093.

vSend << a1 << a2 << a3 << a4;

6094.

EndMessage();

6095.

6096.

catch (...)

6097.

6098.

AbortMessage();

6099.

throw;

6100.

6101.

6102.

void PushRequest(const char* pszCommand,

6103.
6104.

void (*fn)(void*, CDataStream&), void* param1)


{

6105.

uint256 hashReply;

6106.

RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));

6107.

CRITICAL_BLOCK(cs_mapRequests)

6108.

mapRequests[hashReply] = CRequestTracker(fn, param1);

6109.
6110.

PushMessage(pszCommand, hashReply);
}

6111.

template<typename T1>

6112.

void PushRequest(const char* pszCommand, const T1& a1,

6113.
6114.

void (*fn)(void*, CDataStream&), void* param1)


{

6115.

uint256 hashReply;

6116.

RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));

6117.

CRITICAL_BLOCK(cs_mapRequests)

6118.

mapRequests[hashReply] = CRequestTracker(fn, param1);

6119.

PushMessage(pszCommand, hashReply, a1);

6120.

6121.

template<typename T1, typename T2>

6122.

void PushRequest(const char* pszCommand, const T1& a1, const T2& a2,

6123.
6124.

void (*fn)(void*, CDataStream&), void* param1)


{

6125.

uint256 hashReply;

6126.

RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));

6127.

CRITICAL_BLOCK(cs_mapRequests)

6128.

mapRequests[hashReply] = CRequestTracker(fn, param1);

6129.

PushMessage(pszCommand, hashReply, a1, a2);

6130.

6131.

bool IsSubscribed(unsigned int nChannel);

6132.

void Subscribe(unsigned int nChannel, unsigned int nHops=0);

6133.

void CancelSubscribe(unsigned int nChannel);

6134.

void Disconnect();

6135. };
6136. inline void RelayInventory(const CInv& inv)
6137. {
6138.

CRITICAL_BLOCK(cs_vNodes)

6139.

foreach(CNode* pnode, vNodes)

6140.

pnode->PushInventory(inv);

6141. }
6142. template<typename T>
6143. void RelayMessage(const CInv& inv, const T& a)
6144. {
6145.

CDataStream ss(SER_NETWORK);

6146.

ss.reserve(10000);

6147.

ss << a;

6148.

RelayMessage(inv, ss);

6149. }
6150. template<>
6151. inline void RelayMessage<>(const CInv& inv, const CDataStream& ss)
6152. {
6153.

CRITICAL_BLOCK(cs_mapRelay)

6154.

6155.

while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())

6156.

6157.

mapRelay.erase(vRelayExpiration.front().second);

6158.

vRelayExpiration.pop_front();

6159.

6160.

mapRelay[inv] = ss;

6161.

vRelayExpiration.push_back(make_pair(GetTime() + 15 * 60, inv));

6162.

6163.

RelayInventory(inv);

6164. }
6165. template<typename T>
6166. void AdvertStartPublish(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj)
6167. {
6168.

obj.setSources.insert(pfrom->addr.ip);

6169.

if (!AdvertInsert(obj))

6170.
6171.
6172.
6173.
6174.

return;
CRITICAL_BLOCK(cs_vNodes)
foreach(CNode* pnode, vNodes)
if (pnode != pfrom && (nHops < PUBLISH_HOPS || pnode->IsSubscribed(nChannel)))
pnode->PushMessage("publish", nChannel, nHops, obj);

6175. }
6176. template<typename T>
6177. void AdvertStopPublish(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj)
6178. {
6179.

uint256 hash = obj.GetHash();

6180.

CRITICAL_BLOCK(cs_vNodes)

6181.
6182.
6183.
6184.

foreach(CNode* pnode, vNodes)


if (pnode != pfrom && (nHops < PUBLISH_HOPS || pnode->IsSubscribed(nChannel)))
pnode->PushMessage("pub-cancel", nChannel, nHops, hash);
AdvertErase(obj);

6185. }
6186. template<typename T>
6187. void AdvertRemoveSource(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj)
6188. {
6189.

obj.setSources.erase(pfrom->addr.ip);

6190.

if (obj.setSources.empty())

6191.

AdvertStopPublish(pfrom, nChannel, nHops, obj);

6192. }
6193. #include "headers.h"

6194. bool CheckSig(vector<unsigned char> vchSig, vector<unsigned char> vchPubKey, CScript scriptCode, const CTransaction& txTo, unsigned int nIn,
int nHashType);
6195. typedef vector<unsigned char> valtype;
6196. static const valtype vchFalse(0);
6197. static const valtype vchZero(0);
6198. static const valtype vchTrue(1, 1);
6199. static const CBigNum bnZero(0);
6200. static const CBigNum bnOne(1);
6201. static const CBigNum bnFalse(0);
6202. static const CBigNum bnTrue(1);
6203. bool CastToBool(const valtype& vch)
6204. {
6205.

return (CBigNum(vch) != bnZero);

6206. }
6207. void MakeSameSize(valtype& vch1, valtype& vch2)
6208. {
6209.

if (vch1.size() < vch2.size())

6210.
6211.

vch1.resize(vch2.size(), 0);
if (vch2.size() < vch1.size())

6212.

vch2.resize(vch1.size(), 0);

6213. }
6214. #define stacktop(i) (stack.at(stack.size()+(i)))
6215. #define altstacktop(i) (altstack.at(altstack.size()+(i)))
6216. bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType,
6217.

vector<vector<unsigned char> >* pvStackRet)

6218. {
6219.

CAutoBN_CTX pctx;

6220.

CScript::const_iterator pc = script.begin();

6221.

CScript::const_iterator pend = script.end();

6222.

CScript::const_iterator pbegincodehash = script.begin();

6223.

vector<bool> vfExec;

6224.

vector<valtype> stack;

6225.

vector<valtype> altstack;

6226.

if (pvStackRet)

6227.

pvStackRet->clear();

6228.

while (pc < pend)

6229.

6230.

bool fExec = !count(vfExec.begin(), vfExec.end(), false);

6231.

opcodetype opcode;

6232.

valtype vchPushValue;

6233.

if (!script.GetOp(pc, opcode, vchPushValue))

6234.
6235.

return false;
if (fExec && opcode <= OP_PUSHDATA4)

6236.

stack.push_back(vchPushValue);

6237.

else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF))

6238.

switch (opcode)

6239.

6240.

case OP_1NEGATE:

6241.

case OP_1:

6242.

case OP_2:

6243.

case OP_3:

6244.

case OP_4:

6245.

case OP_5:

6246.

case OP_6:

6247.

case OP_7:

6248.

case OP_8:

6249.

case OP_9:

6250.

case OP_10:

6251.

case OP_11:

6252.

case OP_12:

6253.

case OP_13:

6254.

case OP_14:

6255.

case OP_15:

6256.

case OP_16:

6257.

6258.

CBigNum bn((int)opcode - (int)(OP_1 - 1));

6259.

stack.push_back(bn.getvch());

6260.

6261.

break;

6262.

case OP_NOP:

6263.

break;

6264.

case OP_VER:

6265.

6266.

CBigNum bn(VERSION);

6267.

stack.push_back(bn.getvch());

6268.

6269.

break;

6270.

case OP_IF:

6271.

case OP_NOTIF:

6272.

case OP_VERIF:

6273.

case OP_VERNOTIF:

6274.

6275.

bool fValue = false;

6276.

if (fExec)

6277.

6278.

if (stack.size() < 1)

6279.

return false;

6280.

valtype& vch = stacktop(-1);

6281.

if (opcode == OP_VERIF || opcode == OP_VERNOTIF)

6282.

fValue = (CBigNum(VERSION) >= CBigNum(vch));

6283.

else

6284.

fValue = CastToBool(vch);

6285.

if (opcode == OP_NOTIF || opcode == OP_VERNOTIF)

6286.

fValue = !fValue;

6287.

stack.pop_back();

6288.

6289.

vfExec.push_back(fValue);

6290.

6291.

break;

6292.

case OP_ELSE:

6293.

6294.

if (vfExec.empty())

6295.

return false;

6296.

vfExec.back() = !vfExec.back();

6297.

6298.

break;

6299.

case OP_ENDIF:

6300.

6301.

if (vfExec.empty())

6302.

return false;

6303.

vfExec.pop_back();

6304.

6305.

break;

6306.

case OP_VERIFY:

6307.

6308.

if (stack.size() < 1)

6309.

return false;

6310.

bool fValue = CastToBool(stacktop(-1));

6311.

if (fValue)

6312.

stack.pop_back();

6313.

else

6314.

pc = pend;

6315.

6316.

break;

6317.

case OP_RETURN:

6318.

6319.

pc = pend;

6320.

6321.

break;

6322.

case OP_TOALTSTACK:

6323.

6324.

if (stack.size() < 1)

6325.

return false;

6326.

altstack.push_back(stacktop(-1));

6327.

stack.pop_back();

6328.

6329.

break;

6330.

case OP_FROMALTSTACK:

6331.

6332.

if (altstack.size() < 1)

6333.

return false;

6334.

stack.push_back(altstacktop(-1));

6335.

altstack.pop_back();

6336.

6337.

break;

6338.

case OP_2DROP:

6339.

6340.

stack.pop_back();

6341.

stack.pop_back();

6342.

6343.

break;

6344.

case OP_2DUP:

6345.

6346.

if (stack.size() < 2)

6347.

return false;

6348.

valtype vch1 = stacktop(-2);

6349.

valtype vch2 = stacktop(-1);

6350.

stack.push_back(vch1);

6351.

stack.push_back(vch2);

6352.

6353.

break;

6354.

case OP_3DUP:

6355.

6356.
6357.
6358.

if (stack.size() < 3)
return false;
valtype vch1 = stacktop(-3);

6359.

valtype vch2 = stacktop(-2);

6360.

valtype vch3 = stacktop(-1);

6361.

stack.push_back(vch1);

6362.

stack.push_back(vch2);

6363.

stack.push_back(vch3);

6364.

6365.

break;

6366.

case OP_2OVER:

6367.

6368.

if (stack.size() < 4)

6369.

return false;

6370.

valtype vch1 = stacktop(-4);

6371.

valtype vch2 = stacktop(-3);

6372.

stack.push_back(vch1);

6373.

stack.push_back(vch2);

6374.

6375.

break;

6376.

case OP_2ROT:

6377.

6378.

if (stack.size() < 6)

6379.

return false;

6380.

valtype vch1 = stacktop(-6);

6381.

valtype vch2 = stacktop(-5);

6382.

stack.erase(stack.end()-6, stack.end()-4);

6383.

stack.push_back(vch1);

6384.

stack.push_back(vch2);

6385.

6386.

break;

6387.

case OP_2SWAP:

6388.

6389.

if (stack.size() < 4)

6390.

return false;

6391.

swap(stacktop(-4), stacktop(-2));

6392.

swap(stacktop(-3), stacktop(-1));

6393.

6394.

break;

6395.

case OP_IFDUP:

6396.

6397.

if (stack.size() < 1)

6398.

return false;

6399.

valtype vch = stacktop(-1);

6400.

if (CastToBool(vch))

6401.

stack.push_back(vch);

6402.

6403.

break;

6404.

case OP_DEPTH:

6405.

6406.

CBigNum bn(stack.size());

6407.

stack.push_back(bn.getvch());

6408.

6409.

break;

6410.

case OP_DROP:

6411.

6412.

if (stack.size() < 1)

6413.

return false;

6414.

stack.pop_back();

6415.

6416.

break;

6417.

case OP_DUP:

6418.

6419.

if (stack.size() < 1)

6420.

return false;

6421.

valtype vch = stacktop(-1);

6422.

stack.push_back(vch);

6423.

6424.

break;

6425.

case OP_NIP:

6426.

6427.

if (stack.size() < 2)

6428.

return false;

6429.

stack.erase(stack.end() - 2);

6430.

6431.

break;

6432.

case OP_OVER:

6433.

6434.

if (stack.size() < 2)

6435.

return false;

6436.

valtype vch = stacktop(-2);

6437.

stack.push_back(vch);

6438.

6439.

break;

6440.

case OP_PICK:

6441.

case OP_ROLL:

6442.

6443.

if (stack.size() < 2)

6444.

return false;

6445.

int n = CBigNum(stacktop(-1)).getint();

6446.

stack.pop_back();

6447.

if (n < 0 || n >= stack.size())

6448.

return false;

6449.

valtype vch = stacktop(-n-1);

6450.

if (opcode == OP_ROLL)

6451.

stack.erase(stack.end()-n-1);

6452.

stack.push_back(vch);

6453.

6454.

break;

6455.

case OP_ROT:

6456.

6457.

if (stack.size() < 3)

6458.

return false;

6459.

swap(stacktop(-3), stacktop(-2));

6460.

swap(stacktop(-2), stacktop(-1));

6461.

6462.

break;

6463.

case OP_SWAP:

6464.

6465.

if (stack.size() < 2)

6466.

return false;

6467.

swap(stacktop(-2), stacktop(-1));

6468.

6469.

break;

6470.

case OP_TUCK:

6471.

6472.

if (stack.size() < 2)

6473.

return false;

6474.

valtype vch = stacktop(-1);

6475.

stack.insert(stack.end()-2, vch);

6476.

6477.

break;

6478.

case OP_CAT:

6479.

6480.

if (stack.size() < 2)

6481.

return false;

6482.

valtype& vch1 = stacktop(-2);

6483.

valtype& vch2 = stacktop(-1);

6484.

vch1.insert(vch1.end(), vch2.begin(), vch2.end());

6485.

stack.pop_back();

6486.

6487.

break;

6488.

case OP_SUBSTR:

6489.

6490.

if (stack.size() < 3)

6491.

return false;

6492.

valtype& vch = stacktop(-3);

6493.

int nBegin = CBigNum(stacktop(-2)).getint();

6494.

int nEnd = nBegin + CBigNum(stacktop(-1)).getint();

6495.

if (nBegin < 0 || nEnd < nBegin)

6496.

return false;

6497.

if (nBegin > vch.size())

6498.

nBegin = vch.size();

6499.

if (nEnd > vch.size())

6500.

nEnd = vch.size();

6501.

vch.erase(vch.begin() + nEnd, vch.end());

6502.

vch.erase(vch.begin(), vch.begin() + nBegin);

6503.

stack.pop_back();

6504.

stack.pop_back();

6505.

6506.

break;

6507.

case OP_LEFT:

6508.

case OP_RIGHT:

6509.

6510.

if (stack.size() < 2)

6511.

return false;

6512.

valtype& vch = stacktop(-2);

6513.

int nSize = CBigNum(stacktop(-1)).getint();

6514.

if (nSize < 0)

6515.

return false;

6516.

if (nSize > vch.size())

6517.

nSize = vch.size();

6518.

if (opcode == OP_LEFT)

6519.

vch.erase(vch.begin() + nSize, vch.end());

6520.

else

6521.

vch.erase(vch.begin(), vch.end() - nSize);

6522.

stack.pop_back();

6523.

6524.

break;

6525.

case OP_SIZE:

6526.

6527.

if (stack.size() < 1)

6528.

return false;

6529.

CBigNum bn(stacktop(-1).size());

6530.

stack.push_back(bn.getvch());

6531.

6532.

break;

6533.

case OP_INVERT:

6534.

6535.

if (stack.size() < 1)

6536.

return false;

6537.

valtype& vch = stacktop(-1);

6538.

for (int i = 0; i < vch.size(); i++)

6539.

vch[i] = ~vch[i];

6540.

6541.

break;

6542.

case OP_AND:

6543.

case OP_OR:

6544.

case OP_XOR:

6545.

6546.

if (stack.size() < 2)

6547.

return false;

6548.

valtype& vch1 = stacktop(-2);

6549.

valtype& vch2 = stacktop(-1);

6550.

MakeSameSize(vch1, vch2);

6551.

if (opcode == OP_AND)

6552.

6553.

for (int i = 0; i < vch1.size(); i++)

6554.

vch1[i] &= vch2[i];

6555.

6556.

else if (opcode == OP_OR)

6557.

6558.

for (int i = 0; i < vch1.size(); i++)

6559.

vch1[i] |= vch2[i];

6560.

6561.

else if (opcode == OP_XOR)

6562.

6563.

for (int i = 0; i < vch1.size(); i++)

6564.

vch1[i] ^= vch2[i];

6565.

6566.

stack.pop_back();

6567.

6568.

break;

6569.

case OP_EQUAL:

6570.

case OP_EQUALVERIFY:

6571.

6572.

if (stack.size() < 2)

6573.

return false;

6574.

valtype& vch1 = stacktop(-2);

6575.

valtype& vch2 = stacktop(-1);

6576.

bool fEqual = (vch1 == vch2);

6577.

stack.pop_back();

6578.

stack.pop_back();

6579.

stack.push_back(fEqual ? vchTrue : vchFalse);

6580.

if (opcode == OP_EQUALVERIFY)

6581.

6582.

if (fEqual)

6583.

stack.pop_back();

6584.

else

6585.

pc = pend;

6586.

6587.

6588.

break;

6589.

case OP_1ADD:

6590.

case OP_1SUB:

6591.

case OP_2MUL:

6592.

case OP_2DIV:

6593.

case OP_NEGATE:

6594.

case OP_ABS:

6595.

case OP_NOT:

6596.

case OP_0NOTEQUAL:

6597.

6598.

if (stack.size() < 1)

6599.

return false;

6600.

CBigNum bn(stacktop(-1));

6601.

switch (opcode)

6602.

6603.

case OP_1ADD:

bn += bnOne; break;

6604.

case OP_1SUB:

bn -= bnOne; break;

6605.

case OP_2MUL:

6606.

case OP_2DIV:

6607.

case OP_NEGATE:

bn <<= 1; break;
bn >>= 1; break;
bn = -bn; break;

6608.

case OP_ABS:

if (bn < bnZero) bn = -bn; break;

6609.

case OP_NOT:

bn = (bn == bnZero); break;

6610.

case OP_0NOTEQUAL: bn = (bn != bnZero); break;

6611.

6612.

stack.pop_back();

6613.

stack.push_back(bn.getvch());

6614.

6615.

break;

6616.

case OP_ADD:

6617.

case OP_SUB:

6618.

case OP_MUL:

6619.

case OP_DIV:

6620.

case OP_MOD:

6621.

case OP_LSHIFT:

6622.

case OP_RSHIFT:

6623.

case OP_BOOLAND:

6624.

case OP_BOOLOR:

6625.

case OP_NUMEQUAL:

6626.

case OP_NUMEQUALVERIFY:

6627.

case OP_NUMNOTEQUAL:

6628.

case OP_LESSTHAN:

6629.

case OP_GREATERTHAN:

6630.

case OP_LESSTHANOREQUAL:

6631.

case OP_GREATERTHANOREQUAL:

6632.

case OP_MIN:

6633.

case OP_MAX:

6634.

6635.

if (stack.size() < 2)

6636.

return false;

6637.

CBigNum bn1(stacktop(-2));

6638.

CBigNum bn2(stacktop(-1));

6639.

CBigNum bn;

6640.

switch (opcode)

6641.

6642.

case OP_ADD:

6643.

bn = bn1 + bn2;

6644.
6645.

break;
case OP_SUB:

6646.

bn = bn1 - bn2;

6647.
6648.

break;
case OP_MUL:

6649.

if (!BN_mul(&bn, &bn1, &bn2, pctx))

6650.

return false;

6651.
6652.

break;
case OP_DIV:

6653.

if (!BN_div(&bn, NULL, &bn1, &bn2, pctx))

6654.

return false;

6655.
6656.

break;
case OP_MOD:

6657.

if (!BN_mod(&bn, &bn1, &bn2, pctx))

6658.

return false;

6659.
6660.

break;
case OP_LSHIFT:

6661.

if (bn2 < bnZero)

6662.

return false;

6663.

bn = bn1 << bn2.getulong();

6664.

break;

6665.

case OP_RSHIFT:

6666.

if (bn2 < bnZero)

6667.

return false;

6668.

bn = bn1 >> bn2.getulong();

6669.

break;

6670.

case OP_BOOLAND:

6671.

case OP_BOOLOR:

6672.

case OP_NUMEQUAL:

6673.

case OP_NUMEQUALVERIFY:

6674.

case OP_NUMNOTEQUAL:

6675.

case OP_LESSTHAN:

6676.

case OP_GREATERTHAN:

6677.

case OP_LESSTHANOREQUAL:

6678.

case OP_GREATERTHANOREQUAL: bn = (bn1 >= bn2); break;

6679.

case OP_MIN:

6680.

case OP_MAX:

6681.

6682.

stack.pop_back();

6683.

stack.pop_back();

6684.

stack.push_back(bn.getvch());

6685.

if (opcode == OP_NUMEQUALVERIFY)

6686.

6687.
6688.
6689.
6690.

bn = (bn1 != bnZero && bn2 != bnZero); break;


bn = (bn1 != bnZero || bn2 != bnZero); break;
bn = (bn1 == bn2); break;

bn = (bn1 < bn2); break;

stack.pop_back();
pc = pend;

bn = (bn1 > bn2); break;


bn = (bn1 <= bn2); break;

bn = (bn1 < bn2 ? bn1 : bn2); break;


bn = (bn1 > bn2 ? bn1 : bn2); break;

if (CastToBool(stacktop(-1)))
else

bn = (bn1 == bn2); break;


bn = (bn1 != bn2); break;

6691.

6692.

6693.

break;

6694.

case OP_WITHIN:

6695.

6696.

if (stack.size() < 3)

6697.

return false;

6698.

CBigNum bn1(stacktop(-3));

6699.

CBigNum bn2(stacktop(-2));

6700.

CBigNum bn3(stacktop(-1));

6701.

bool fValue = (bn2 <= bn1 && bn1 < bn3);

6702.

stack.pop_back();

6703.

stack.pop_back();

6704.

stack.pop_back();

6705.

stack.push_back(fValue ? vchTrue : vchFalse);

6706.

6707.

break;

6708.

case OP_RIPEMD160:

6709.

case OP_SHA1:

6710.

case OP_SHA256:

6711.

case OP_HASH160:

6712.

case OP_HASH256:

6713.

6714.

if (stack.size() < 1)

6715.

return false;

6716.

valtype& vch = stacktop(-1);

6717.

valtype vchHash(opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160 ? 20 : 32);

6718.

if (opcode == OP_RIPEMD160)

6719.

RIPEMD160(&vch[0], vch.size(), &vchHash[0]);

6720.

else if (opcode == OP_SHA1)

6721.

SHA1(&vch[0], vch.size(), &vchHash[0]);

6722.

else if (opcode == OP_SHA256)

6723.

SHA256(&vch[0], vch.size(), &vchHash[0]);

6724.

else if (opcode == OP_HASH160)

6725.

6726.

uint160 hash160 = Hash160(vch);

6727.

memcpy(&vchHash[0], &hash160, sizeof(hash160));

6728.

6729.

else if (opcode == OP_HASH256)

6730.

6731.

uint256 hash = Hash(vch.begin(), vch.end());

6732.

memcpy(&vchHash[0], &hash, sizeof(hash));

6733.

6734.

stack.pop_back();

6735.

stack.push_back(vchHash);

6736.

6737.

break;

6738.

case OP_CODESEPARATOR:

6739.

6740.

pbegincodehash = pc;

6741.

6742.

break;

6743.

case OP_CHECKSIG:

6744.

case OP_CHECKSIGVERIFY:

6745.

6746.

if (stack.size() < 2)

6747.

return false;

6748.
6749.

valtype& vchSig

6750.

valtype& vchPubKey = stacktop(-1);

6751.

CScript scriptCode(pbegincodehash, pend);

6752.

scriptCode.FindAndDelete(CScript(vchSig));

6753.

bool fSuccess = CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType);

6754.

stack.pop_back();

6755.

stack.pop_back();

6756.

stack.push_back(fSuccess ? vchTrue : vchFalse);

6757.

if (opcode == OP_CHECKSIGVERIFY)

6758.

6759.

= stacktop(-2);

if (fSuccess)

6760.

stack.pop_back();

6761.

else

6762.

pc = pend;

6763.

6764.

6765.

break;

6766.

case OP_CHECKMULTISIG:

6767.

case OP_CHECKMULTISIGVERIFY:

6768.

6769.

int i = 1;

6770.

if (stack.size() < i)

6771.

return false;

6772.

int nKeysCount = CBigNum(stacktop(-i)).getint();

6773.

if (nKeysCount < 0)

6774.

return false;

6775.

int ikey = ++i;

6776.

i += nKeysCount;

6777.

if (stack.size() < i)

6778.

return false;

6779.

int nSigsCount = CBigNum(stacktop(-i)).getint();

6780.

if (nSigsCount < 0 || nSigsCount > nKeysCount)

6781.

return false;

6782.

int isig = ++i;

6783.

i += nSigsCount;

6784.

if (stack.size() < i)

6785.

return false;

6786.

CScript scriptCode(pbegincodehash, pend);

6787.

for (int i = 0; i < nSigsCount; i++)

6788.

6789.

valtype& vchSig = stacktop(-isig-i);

6790.

scriptCode.FindAndDelete(CScript(vchSig));

6791.

6792.

bool fSuccess = true;

6793.

while (fSuccess && nSigsCount > 0)

6794.

6795.

valtype& vchSig

6796.

valtype& vchPubKey = stacktop(-ikey);

6797.

if (CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType))

6798.

6799.

= stacktop(-isig);

isig++;

6800.

nSigsCount--;

6801.

6802.

ikey++;

6803.

nKeysCount--;

6804.

if (nSigsCount > nKeysCount)

6805.

fSuccess = false;

6806.

6807.

while (i-- > 0)

6808.

stack.pop_back();

6809.

stack.push_back(fSuccess ? vchTrue : vchFalse);

6810.

if (opcode == OP_CHECKMULTISIGVERIFY)

6811.

6812.

if (fSuccess)

6813.

stack.pop_back();

6814.

else

6815.

pc = pend;

6816.

6817.

6818.

break;

6819.

default:

6820.

return false;

6821.

6822.

6823.

if (pvStackRet)

6824.
6825.

*pvStackRet = stack;
return (stack.empty() ? false : CastToBool(stack.back()));

6826. }
6827. #undef top
6828. uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType)
6829. {
6830.

if (nIn >= txTo.vin.size())

6831.

6832.

printf("ERROR: SignatureHash() : nIn=%d out of range\n", nIn);

6833.

return 1;

6834.

6835.

CTransaction txTmp(txTo);

6836.

scriptCode.FindAndDelete(CScript(OP_CODESEPARATOR));

6837.

for (int i = 0; i < txTmp.vin.size(); i++)

6838.

txTmp.vin[i].scriptSig = CScript();

6839.

txTmp.vin[nIn].scriptSig = scriptCode;

6840.

if ((nHashType & 0x1f) == SIGHASH_NONE)

6841.

6842.

txTmp.vout.clear();

6843.

for (int i = 0; i < txTmp.vin.size(); i++)

6844.

if (i != nIn)

6845.

txTmp.vin[i].nSequence = 0;

6846.

6847.

else if ((nHashType & 0x1f) == SIGHASH_SINGLE)

6848.

6849.

unsigned int nOut = nIn;

6850.

if (nOut >= txTmp.vout.size())

6851.

6852.

printf("ERROR: SignatureHash() : nOut=%d out of range\n", nOut);

6853.

return 1;

6854.

6855.

txTmp.vout.resize(nOut+1);

6856.

for (int i = 0; i < nOut; i++)

6857.

txTmp.vout[i].SetNull();

6858.

for (int i = 0; i < txTmp.vin.size(); i++)

6859.

if (i != nIn)

6860.

txTmp.vin[i].nSequence = 0;

6861.

6862.

if (nHashType & SIGHASH_ANYONECANPAY)

6863.

6864.

txTmp.vin[0] = txTmp.vin[nIn];

6865.

txTmp.vin.resize(1);

6866.

6867.

CDataStream ss(SER_GETHASH);

6868.

ss.reserve(10000);

6869.

ss << txTmp << nHashType;

6870.

return Hash(ss.begin(), ss.end());

6871. }
6872. bool CheckSig(vector<unsigned char> vchSig, vector<unsigned char> vchPubKey, CScript scriptCode,
6873.

const CTransaction& txTo, unsigned int nIn, int nHashType)

6874. {
6875.

CKey key;

6876.

if (!key.SetPubKey(vchPubKey))

6877.
6878.

return false;
if (vchSig.empty())

6879.
6880.

return false;
if (nHashType == 0)

6881.
6882.

nHashType = vchSig.back();
else if (nHashType != vchSig.back())

6883.

return false;

6884.

vchSig.pop_back();

6885.

if (key.Verify(SignatureHash(scriptCode, txTo, nIn, nHashType), vchSig))

6886.
6887.

return true;
return false;

6888. }
6889. bool Solver(const CScript& scriptPubKey, vector<pair<opcodetype, valtype> >& vSolutionRet)
6890. {
6891.

static vector<CScript> vTemplates;

6892.

if (vTemplates.empty())

6893.

6894.

vTemplates.push_back(CScript() << OP_PUBKEY << OP_CHECKSIG);

6895.

vTemplates.push_back(CScript() << OP_DUP << OP_HASH160 << OP_PUBKEYHASH << OP_EQUALVERIFY << OP_CHECKSIG);

6896.

6897.

const CScript& script1 = scriptPubKey;

6898.

foreach(const CScript& script2, vTemplates)

6899.

6900.

vSolutionRet.clear();

6901.

opcodetype opcode1, opcode2;

6902.

vector<unsigned char> vch1, vch2;

6903.

CScript::const_iterator pc1 = script1.begin();

6904.

CScript::const_iterator pc2 = script2.begin();

6905.

loop

6906.

6907.

bool f1 = script1.GetOp(pc1, opcode1, vch1);

6908.

bool f2 = script2.GetOp(pc2, opcode2, vch2);

6909.

if (!f1 && !f2)

6910.

6911.

reverse(vSolutionRet.begin(), vSolutionRet.end());

6912.

return true;

6913.

6914.

else if (f1 != f2)

6915.

6916.

break;

6917.

6918.

else if (opcode2 == OP_PUBKEY)

6919.

6920.

if (vch1.size() <= sizeof(uint256))

6921.

break;

6922.

vSolutionRet.push_back(make_pair(opcode2, vch1));

6923.

6924.

else if (opcode2 == OP_PUBKEYHASH)

6925.

6926.

if (vch1.size() != sizeof(uint160))

6927.

break;

6928.

vSolutionRet.push_back(make_pair(opcode2, vch1));

6929.

6930.

else if (opcode1 != opcode2)

6931.

6932.

break;

6933.

6934.

6935.

6936.

vSolutionRet.clear();

6937.

return false;

6938. }
6939. bool Solver(const CScript& scriptPubKey, uint256 hash, int nHashType, CScript& scriptSigRet)

6940. {
6941.

scriptSigRet.clear();

6942.

vector<pair<opcodetype, valtype> > vSolution;

6943.

if (!Solver(scriptPubKey, vSolution))

6944.

return false;

6945.

CRITICAL_BLOCK(cs_mapKeys)

6946.

6947.

foreach(PAIRTYPE(opcodetype, valtype)& item, vSolution)

6948.

6949.

if (item.first == OP_PUBKEY)

6950.

6951.

const valtype& vchPubKey = item.second;

6952.

if (!mapKeys.count(vchPubKey))

6953.

return false;

6954.

if (hash != 0)

6955.

6956.

vector<unsigned char> vchSig;

6957.

if (!CKey::Sign(mapKeys[vchPubKey], hash, vchSig))

6958.

return false;

6959.

vchSig.push_back((unsigned char)nHashType);

6960.

scriptSigRet << vchSig;

6961.

6962.

6963.

else if (item.first == OP_PUBKEYHASH)

6964.

6965.

map<uint160, valtype>::iterator mi = mapPubKeys.find(uint160(item.second));

6966.

if (mi == mapPubKeys.end())

6967.

return false;

6968.

const vector<unsigned char>& vchPubKey = (*mi).second;

6969.

if (!mapKeys.count(vchPubKey))

6970.

return false;

6971.

if (hash != 0)

6972.

6973.

vector<unsigned char> vchSig;

6974.

if (!CKey::Sign(mapKeys[vchPubKey], hash, vchSig))

6975.

return false;

6976.

vchSig.push_back((unsigned char)nHashType);

6977.

scriptSigRet << vchSig << vchPubKey;

6978.

6979.

6980.

6981.

6982.

return true;

6983. }
6984. bool IsMine(const CScript& scriptPubKey)
6985. {
6986.

CScript scriptSig;

6987.

return Solver(scriptPubKey, 0, 0, scriptSig);

6988. }
6989. bool ExtractPubKey(const CScript& scriptPubKey, bool fMineOnly, vector<unsigned char>& vchPubKeyRet)
6990. {
6991.

vchPubKeyRet.clear();

6992.

vector<pair<opcodetype, valtype> > vSolution;

6993.

if (!Solver(scriptPubKey, vSolution))

6994.

return false;

6995.

CRITICAL_BLOCK(cs_mapKeys)

6996.

6997.

foreach(PAIRTYPE(opcodetype, valtype)& item, vSolution)

6998.

6999.

valtype vchPubKey;

7000.

if (item.first == OP_PUBKEY)

7001.

7002.

vchPubKey = item.second;

7003.

7004.

else if (item.first == OP_PUBKEYHASH)

7005.

7006.

map<uint160, valtype>::iterator mi = mapPubKeys.find(uint160(item.second));

7007.

if (mi == mapPubKeys.end())

7008.

continue;

7009.

vchPubKey = (*mi).second;

7010.

7011.

if (!fMineOnly || mapKeys.count(vchPubKey))

7012.

7013.

vchPubKeyRet = vchPubKey;

7014.

return true;

7015.

7016.

7017.

7018.

return false;

7019. }
7020. bool ExtractHash160(const CScript& scriptPubKey, uint160& hash160Ret)
7021. {
7022.

hash160Ret = 0;

7023.

vector<pair<opcodetype, valtype> > vSolution;

7024.

if (!Solver(scriptPubKey, vSolution))

7025.

return false;

7026.

foreach(PAIRTYPE(opcodetype, valtype)& item, vSolution)

7027.

7028.

if (item.first == OP_PUBKEYHASH)

7029.

7030.

hash160Ret = uint160(item.second);

7031.

return true;

7032.

7033.

7034.

return false;

7035. }
7036. bool SignSignature(const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType, CScript scriptPrereq)
7037. {
7038.

assert(nIn < txTo.vin.size());

7039.

CTxIn& txin = txTo.vin[nIn];

7040.

assert(txin.prevout.n < txFrom.vout.size());

7041.

const CTxOut& txout = txFrom.vout[txin.prevout.n];

7042.

uint256 hash = SignatureHash(scriptPrereq + txout.scriptPubKey, txTo, nIn, nHashType);

7043.

if (!Solver(txout.scriptPubKey, hash, nHashType, txin.scriptSig))

7044.

return false;

7045.

txin.scriptSig = scriptPrereq + txin.scriptSig;

7046.

if (scriptPrereq.empty())

7047.

if (!EvalScript(txin.scriptSig + CScript(OP_CODESEPARATOR) + txout.scriptPubKey, txTo, nIn))

7048.
7049.

return false;
return true;

7050. }
7051. bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, int nHashType)
7052. {
7053.

assert(nIn < txTo.vin.size());

7054.

const CTxIn& txin = txTo.vin[nIn];

7055.

if (txin.prevout.n >= txFrom.vout.size())

7056.

return false;

7057.

const CTxOut& txout = txFrom.vout[txin.prevout.n];

7058.

if (txin.prevout.hash != txFrom.GetHash())

7059.
7060.

return false;
return EvalScript(txin.scriptSig + CScript(OP_CODESEPARATOR) + txout.scriptPubKey, txTo, nIn, nHashType);

7061. }
7062. class CTransaction;
7063. enum
7064. {
7065.

SIGHASH_ALL = 1,

7066.

SIGHASH_NONE = 2,

7067.

SIGHASH_SINGLE = 3,

7068.

SIGHASH_ANYONECANPAY = 0x80,

7069. };
7070. enum opcodetype
7071. {
7072.

OP_0=0,

7073.

OP_FALSE=OP_0,

7074.

OP_PUSHDATA1=76,

7075.

OP_PUSHDATA2,

7076.

OP_PUSHDATA4,

7077.

OP_1NEGATE,

7078.

OP_RESERVED,

7079.

OP_1,

7080.

OP_TRUE=OP_1,

7081.

OP_2,

7082.

OP_3,

7083.

OP_4,

7084.

OP_5,

7085.

OP_6,

7086.

OP_7,

7087.

OP_8,

7088.

OP_9,

7089.

OP_10,

7090.

OP_11,

7091.

OP_12,

7092.

OP_13,

7093.

OP_14,

7094.

OP_15,

7095.

OP_16,

7096.

OP_NOP,

7097.

OP_VER,

7098.

OP_IF,

7099.

OP_NOTIF,

7100.

OP_VERIF,

7101.

OP_VERNOTIF,

7102.

OP_ELSE,

7103.

OP_ENDIF,

7104.

OP_VERIFY,

7105.

OP_RETURN,

7106.

OP_TOALTSTACK,

7107.

OP_FROMALTSTACK,

7108.

OP_2DROP,

7109.

OP_2DUP,

7110.

OP_3DUP,

7111.

OP_2OVER,

7112.

OP_2ROT,

7113.

OP_2SWAP,

7114.

OP_IFDUP,

7115.

OP_DEPTH,

7116.

OP_DROP,

7117.

OP_DUP,

7118.

OP_NIP,

7119.

OP_OVER,

7120.

OP_PICK,

7121.

OP_ROLL,

7122.

OP_ROT,

7123.

OP_SWAP,

7124.

OP_TUCK,

7125.

OP_CAT,

7126.

OP_SUBSTR,

7127.

OP_LEFT,

7128.

OP_RIGHT,

7129.

OP_SIZE,

7130.

OP_INVERT,

7131.

OP_AND,

7132.

OP_OR,

7133.

OP_XOR,

7134.

OP_EQUAL,

7135.

OP_EQUALVERIFY,

7136.

OP_RESERVED1,

7137.

OP_RESERVED2,

7138.

OP_1ADD,

7139.

OP_1SUB,

7140.

OP_2MUL,

7141.

OP_2DIV,

7142.

OP_NEGATE,

7143.

OP_ABS,

7144.

OP_NOT,

7145.

OP_0NOTEQUAL,

7146.

OP_ADD,

7147.

OP_SUB,

7148.

OP_MUL,

7149.

OP_DIV,

7150.

OP_MOD,

7151.

OP_LSHIFT,

7152.

OP_RSHIFT,

7153.

OP_BOOLAND,

7154.

OP_BOOLOR,

7155.

OP_NUMEQUAL,

7156.

OP_NUMEQUALVERIFY,

7157.

OP_NUMNOTEQUAL,

7158.

OP_LESSTHAN,

7159.

OP_GREATERTHAN,

7160.

OP_LESSTHANOREQUAL,

7161.

OP_GREATERTHANOREQUAL,

7162.

OP_MIN,

7163.

OP_MAX,

7164.

OP_WITHIN,

7165.

OP_RIPEMD160,

7166.

OP_SHA1,

7167.

OP_SHA256,

7168.

OP_HASH160,

7169.

OP_HASH256,

7170.

OP_CODESEPARATOR,

7171.

OP_CHECKSIG,

7172.

OP_CHECKSIGVERIFY,

7173.

OP_CHECKMULTISIG,

7174.

OP_CHECKMULTISIGVERIFY,

7175.

OP_SINGLEBYTE_END = 0xF0,

7176.

OP_DOUBLEBYTE_BEGIN = 0xF000,

7177.

OP_PUBKEY,

7178.

OP_PUBKEYHASH,

7179.

OP_INVALIDOPCODE = 0xFFFF,

7180. };
7181. inline const char* GetOpName(opcodetype opcode)
7182. {
7183.

switch (opcode)

7184.

7185.

case OP_0

7186.

case OP_PUSHDATA1

: return "OP_PUSHDATA1";

7187.

case OP_PUSHDATA2

: return "OP_PUSHDATA2";

7188.

case OP_PUSHDATA4

: return "OP_PUSHDATA4";

: return "0";

7189.

case OP_1NEGATE

7190.

case OP_RESERVED

: return "-1";

7191.

case OP_1

: return "1";

7192.

case OP_2

: return "2";

7193.

case OP_3

: return "3";

7194.

case OP_4

: return "4";

7195.

case OP_5

: return "5";

7196.

case OP_6

: return "6";

7197.

case OP_7

: return "7";

7198.

case OP_8

: return "8";

7199.

case OP_9

: return "9";

7200.

case OP_10

: return "10";

7201.

case OP_11

: return "11";

7202.

case OP_12

: return "12";

7203.

case OP_13

: return "13";

7204.

case OP_14

: return "14";

7205.

case OP_15

: return "15";

7206.

case OP_16

: return "16";

7207.

case OP_NOP

: return "OP_NOP";

7208.

case OP_VER

: return "OP_VER";

7209.

case OP_IF

7210.

case OP_NOTIF

: return "OP_NOTIF";

7211.

case OP_VERIF

: return "OP_VERIF";

7212.

case OP_VERNOTIF

7213.

case OP_ELSE

: return "OP_ELSE";

7214.

case OP_ENDIF

: return "OP_ENDIF";

7215.

case OP_VERIFY

7216.

case OP_RETURN

7217.

case OP_TOALTSTACK

7218.

case OP_FROMALTSTACK

7219.

case OP_2DROP

7220.

case OP_2DUP

: return "OP_2DUP";

7221.

case OP_3DUP

: return "OP_3DUP";

7222.

case OP_2OVER

7223.

case OP_2ROT

7224.

case OP_2SWAP

7225.

case OP_IFDUP

7226.

case OP_DEPTH

: return "OP_DEPTH";

7227.

case OP_DROP

: return "OP_DROP";

7228.

case OP_DUP

7229.

case OP_NIP

7230.

case OP_OVER

7231.

case OP_PICK

7232.

case OP_ROLL

7233.

case OP_ROT

7234.

case OP_SWAP

: return "OP_SWAP";

7235.

case OP_TUCK

: return "OP_TUCK";

7236.

case OP_CAT

7237.

case OP_SUBSTR

7238.

case OP_LEFT

7239.

case OP_RIGHT

7240.

case OP_SIZE

7241.

case OP_INVERT

7242.

case OP_AND

7243.

case OP_OR

7244.

case OP_XOR

7245.

case OP_EQUAL

7246.

case OP_EQUALVERIFY

7247.

case OP_RESERVED1

7248.

case OP_RESERVED2

7249.

case OP_1ADD

: return "OP_1ADD";

7250.

case OP_1SUB

: return "OP_1SUB";

7251.

case OP_2MUL

7252.

case OP_2DIV

7253.

case OP_NEGATE

7254.

case OP_ABS

: return "OP_ABS";

7255.

case OP_NOT

: return "OP_NOT";

7256.

case OP_0NOTEQUAL

7257.

case OP_ADD

: return "OP_ADD";

7258.

case OP_SUB

: return "OP_SUB";

7259.

case OP_MUL

7260.

case OP_DIV

7261.

case OP_MOD

7262.

case OP_LSHIFT

: return "OP_LSHIFT";

7263.

case OP_RSHIFT

: return "OP_RSHIFT";

7264.

case OP_BOOLAND

7265.

case OP_BOOLOR

7266.

case OP_NUMEQUAL

7267.

case OP_NUMEQUALVERIFY

7268.

case OP_NUMNOTEQUAL

7269.

case OP_LESSTHAN

7270.

case OP_GREATERTHAN

7271.

case OP_LESSTHANOREQUAL

: return "OP_RESERVED";

: return "OP_IF";

: return "OP_VERNOTIF";

: return "OP_VERIFY";
: return "OP_RETURN";
: return "OP_TOALTSTACK";
: return "OP_FROMALTSTACK";

: return "OP_2DROP";

: return "OP_2OVER";
: return "OP_2ROT";
: return "OP_2SWAP";
: return "OP_IFDUP";

: return "OP_DUP";
: return "OP_NIP";
: return "OP_OVER";
: return "OP_PICK";
: return "OP_ROLL";
: return "OP_ROT";

: return "OP_CAT";
: return "OP_SUBSTR";
: return "OP_LEFT";
: return "OP_RIGHT";
: return "OP_SIZE";
: return "OP_INVERT";
: return "OP_AND";
: return "OP_OR";
: return "OP_XOR";
: return "OP_EQUAL";
: return "OP_EQUALVERIFY";
: return "OP_RESERVED1";
: return "OP_RESERVED2";

: return "OP_2MUL";
: return "OP_2DIV";
: return "OP_NEGATE";

: return "OP_0NOTEQUAL";

: return "OP_MUL";
: return "OP_DIV";
: return "OP_MOD";

: return "OP_BOOLAND";
: return "OP_BOOLOR";
: return "OP_NUMEQUAL";
: return "OP_NUMEQUALVERIFY";
: return "OP_NUMNOTEQUAL";
: return "OP_LESSTHAN";
: return "OP_GREATERTHAN";
: return "OP_LESSTHANOREQUAL";

7272.

case OP_GREATERTHANOREQUAL

7273.

case OP_MIN

7274.

case OP_MAX

7275.

case OP_WITHIN

7276.

case OP_RIPEMD160

7277.

case OP_SHA1

7278.

case OP_SHA256

7279.

case OP_HASH160

: return "OP_HASH160";

7280.

case OP_HASH256

: return "OP_HASH256";

7281.

case OP_CODESEPARATOR

7282.

case OP_CHECKSIG

7283.

case OP_CHECKSIGVERIFY

7284.

case OP_CHECKMULTISIG

7285.

case OP_CHECKMULTISIGVERIFY

7286.

case OP_SINGLEBYTE_END

7287.

case OP_DOUBLEBYTE_BEGIN

7288.

case OP_PUBKEY

7289.

case OP_PUBKEYHASH

7290.

case OP_INVALIDOPCODE

7291.

default:

7292.
7293.

: return "OP_GREATERTHANOREQUAL";

: return "OP_MIN";
: return "OP_MAX";
: return "OP_WITHIN";
: return "OP_RIPEMD160";
: return "OP_SHA1";
: return "OP_SHA256";

: return "OP_CODESEPARATOR";

: return "OP_CHECKSIG";
: return "OP_CHECKSIGVERIFY";
: return "OP_CHECKMULTISIG";
: return "OP_CHECKMULTISIGVERIFY";

: return "OP_SINGLEBYTE_END";
: return "OP_DOUBLEBYTE_BEGIN";

: return "OP_PUBKEY";
: return "OP_PUBKEYHASH";
: return "OP_INVALIDOPCODE";

return "UNKNOWN_OPCODE";
}

7294. };
7295. inline string ValueString(const vector<unsigned char>& vch)
7296. {
7297.

if (vch.size() <= 4)

7298.
7299.

return strprintf("%d", CBigNum(vch).getint());


else

7300.

return HexNumStr(vch.begin(), vch.end());

7301. }
7302. inline string StackString(const vector<vector<unsigned char> >& vStack)
7303. {
7304.

string str;

7305.

foreach(const vector<unsigned char>& vch, vStack)

7306.

7307.

if (!str.empty())

7308.

str += " ";

7309.

str += ValueString(vch);

7310.

7311.

return str;

7312. }
7313. class CScript : public vector<unsigned char>
7314. {
7315. protected:
7316.

CScript& push_int64(int64 n)

7317.

7318.

if (n == -1 || (n >= 1 && n <= 16))

7319.

7320.

push_back(n + (OP_1 - 1));

7321.

7322.

else

7323.

7324.

CBigNum bn(n);

7325.

*this << bn.getvch();

7326.

7327.

return (*this);

7328.

7329.

CScript& push_uint64(uint64 n)

7330.

7331.

if (n == -1 || (n >= 1 && n <= 16))

7332.

7333.

push_back(n + (OP_1 - 1));

7334.

7335.

else

7336.

7337.

CBigNum bn(n);

7338.

*this << bn.getvch();

7339.

7340.
7341.

return (*this);
}

7342. public:
7343.

CScript() { }

7344.

CScript(const CScript& b) : vector<unsigned char>(b.begin(), b.end()) { }

7345.

CScript(const_iterator pbegin, const_iterator pend) : vector<unsigned char>(pbegin, pend) { }

7346. #ifndef _MSC_VER


7347.

CScript(const unsigned char* pbegin, const unsigned char* pend) : vector<unsigned char>(pbegin, pend) { }

7348. #endif
7349.

CScript& operator+=(const CScript& b)

7350.

7351.

insert(end(), b.begin(), b.end());

7352.

return *this;

7353.

7354.

friend CScript operator+(const CScript& a, const CScript& b)

7355.

7356.

CScript ret = a;

7357.

ret += b;

7358.

return (ret);

7359.

7360.

explicit CScript(char b)

7361.

explicit CScript(short b)

7362.

explicit CScript(int b)

7363.

explicit CScript(long b)

{ operator<<(b); }

7364.

explicit CScript(int64 b)

{ operator<<(b); }

7365.

explicit CScript(unsigned char b) { operator<<(b); }

7366.

explicit CScript(unsigned int b) { operator<<(b); }

7367.

explicit CScript(unsigned short b) { operator<<(b); }

7368.

explicit CScript(unsigned long b) { operator<<(b); }

7369.

explicit CScript(uint64 b)

7370.

explicit CScript(opcodetype b)

7371.

explicit CScript(const uint256& b) { operator<<(b); }

7372.

explicit CScript(const CBigNum& b) { operator<<(b); }

7373.

explicit CScript(const vector<unsigned char>& b) { operator<<(b); }

7374.

CScript& operator<<(char b)

7375.

CScript& operator<<(short b)

7376.

CScript& operator<<(int b)

7377.

CScript& operator<<(long b)

{ return (push_int64(b)); }

7378.

CScript& operator<<(int64 b)

{ return (push_int64(b)); }

7379.

CScript& operator<<(unsigned char b) { return (push_uint64(b)); }

7380.

CScript& operator<<(unsigned int b) { return (push_uint64(b)); }

7381.

CScript& operator<<(unsigned short b) { return (push_uint64(b)); }

7382.

CScript& operator<<(unsigned long b) { return (push_uint64(b)); }

7383.

CScript& operator<<(uint64 b)

7384.

CScript& operator<<(opcodetype opcode)

7385.

{ operator<<(b); }
{ operator<<(b); }
{ operator<<(b); }

{ operator<<(b); }
{ operator<<(b); }

{ return (push_int64(b)); }
{ return (push_int64(b)); }
{ return (push_int64(b)); }

{ return (push_uint64(b)); }

7386.

if (opcode <= OP_SINGLEBYTE_END)

7387.

7388.

insert(end(), (unsigned char)opcode);

7389.

7390.

else

7391.

7392.

assert(opcode >= OP_DOUBLEBYTE_BEGIN);

7393.

insert(end(), (unsigned char)(opcode >> 8));

7394.

insert(end(), (unsigned char)(opcode & 0xFF));

7395.

7396.

return (*this);

7397.

7398.

CScript& operator<<(const uint160& b)

7399.

7400.

insert(end(), sizeof(b));

7401.

insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b));

7402.

return (*this);

7403.

7404.

CScript& operator<<(const uint256& b)

7405.

7406.

insert(end(), sizeof(b));

7407.

insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b));

7408.

return (*this);

7409.

7410.

CScript& operator<<(const CBigNum& b)

7411.

7412.

*this << b.getvch();

7413.

return (*this);

7414.

7415.

CScript& operator<<(const vector<unsigned char>& b)

7416.

7417.

if (b.size() < OP_PUSHDATA1)

7418.

7419.

insert(end(), (unsigned char)b.size());

7420.

7421.

else if (b.size() <= 0xff)

7422.

7423.

insert(end(), OP_PUSHDATA1);

7424.

insert(end(), (unsigned char)b.size());

7425.

7426.

else

7427.

7428.

insert(end(), OP_PUSHDATA2);

7429.

unsigned short nSize = b.size();

7430.

insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize));

7431.

7432.

insert(end(), b.begin(), b.end());

7433.

return (*this);

7434.

7435.

CScript& operator<<(const CScript& b)

7436.

7437.

assert(("warning: pushing a CScript onto a CScript with << is probably not intended, use + to concatenate", false));

7438.

return (*this);

7439.

7440.

bool GetOp(iterator& pc, opcodetype& opcodeRet, vector<unsigned char>& vchRet)

7441.

7442.

const_iterator pc2 = pc;

7443.

bool fRet = GetOp(pc2, opcodeRet, vchRet);

7444.

pc = begin() + (pc2 - begin());

7445.

return fRet;

7446.

7447.

bool GetOp(const_iterator& pc, opcodetype& opcodeRet, vector<unsigned char>& vchRet) const

7448.

7449.

opcodeRet = OP_INVALIDOPCODE;

7450.

vchRet.clear();

7451.

if (pc >= end())

7452.

return false;

7453.

unsigned int opcode = *pc++;

7454.

if (opcode >= OP_SINGLEBYTE_END)

7455.

7456.

if (pc + 1 > end())

7457.

return false;

7458.

opcode <<= 8;

7459.

opcode |= *pc++;

7460.

7461.

if (opcode <= OP_PUSHDATA4)

7462.

7463.

unsigned int nSize = opcode;

7464.

if (opcode == OP_PUSHDATA1)

7465.

7466.

if (pc + 1 > end())

7467.

return false;

7468.

nSize = *pc++;

7469.

7470.

else if (opcode == OP_PUSHDATA2)

7471.

7472.

if (pc + 2 > end())

7473.

return false;

7474.

nSize = 0;

7475.

memcpy(&nSize, &pc[0], 2);

7476.

pc += 2;

7477.

7478.

else if (opcode == OP_PUSHDATA4)

7479.

7480.

if (pc + 4 > end())

7481.

return false;

7482.

memcpy(&nSize, &pc[0], 4);

7483.

pc += 4;

7484.

7485.

if (pc + nSize > end())

7486.

return false;

7487.

vchRet.assign(pc, pc + nSize);

7488.

pc += nSize;

7489.

7490.

opcodeRet = (opcodetype)opcode;

7491.

return true;

7492.

7493.

void FindAndDelete(const CScript& b)

7494.

7495.

iterator pc = begin();

7496.

opcodetype opcode;

7497.

vector<unsigned char> vchPushValue;

7498.

int count = 0;

7499.

do

7500.

7501.

while (end() - pc >= b.size() && memcmp(&pc[0], &b[0], b.size()) == 0)

7502.

7503.

erase(pc, pc + b.size());

7504.

count++;

7505.

7506.

7507.

while (GetOp(pc, opcode, vchPushValue));

7508.

7509.

void PrintHex() const

7510.

7511.

printf("CScript(%s)\n", HexStr(begin(), end()).c_str());

7512.

7513.

string ToString() const

7514.

7515.

string str;

7516.

opcodetype opcode;

7517.

vector<unsigned char> vch;

7518.

const_iterator it = begin();

7519.

while (GetOp(it, opcode, vch))

7520.

7521.

if (!str.empty())

7522.

str += " ";

7523.

if (opcode <= OP_PUSHDATA4)

7524.

str += ValueString(vch);

7525.

else

7526.

str += GetOpName(opcode);

7527.

7528.

return str;

7529.

7530.

void print() const

7531.

7532.

printf("%s\n", ToString().c_str());

7533.

7534. };
7535. bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType=0,
7536.

vector<vector<unsigned char> >* pvStackRet=NULL);

7537. uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType);
7538. bool IsMine(const CScript& scriptPubKey);
7539. bool ExtractPubKey(const CScript& scriptPubKey, bool fMineOnly, vector<unsigned char>& vchPubKeyRet);
7540. bool ExtractHash160(const CScript& scriptPubKey, uint160& hash160Ret);
7541. bool SignSignature(const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL, CScript
scriptPrereq=CScript());
7542. bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, int nHashType=0);
7543. #include <vector>
7544. #include <map>
7545. #include <boost/type_traits/is_fundamental.hpp>
7546. #if defined(_MSC_VER) || defined(__BORLANDC__)
7547. typedef __int64 int64;
7548. typedef unsigned __int64 uint64;
7549. #else
7550. typedef long long int64;
7551. typedef unsigned long long uint64;
7552. #endif
7553. #if defined(_MSC_VER) && _MSC_VER < 1300
7554. #define for if (false) ; else for
7555. #endif
7556. class CScript;
7557. class CDataStream;
7558. class CAutoFile;
7559. static const int VERSION = 101;
7560. enum
7561. {
7562.

SER_NETWORK

7563.

SER_DISK

= (1 << 0),

7564.

SER_GETHASH

7565.

SER_SKIPSIG

7566.

SER_BLOCKHEADERONLY = (1 << 17),

= (1 << 1),
= (1 << 2),
= (1 << 16),

7567. };
7568. #define IMPLEMENT_SERIALIZE(statements)

7569.

unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const \

7570.

7571.

CSerActionGetSerializeSize ser_action; \

7572.

const bool fGetSize = true;

7573.

const bool fWrite = false;

7574.

const bool fRead = false;

7575.

unsigned int nSerSize = 0;

7576.

ser_streamplaceholder s;

7577.

s.nType = nType;

7578.

s.nVersion = nVersion;

7579.

{statements}

7580.

\
\
\
\
\
\
\
\

return nSerSize;

7581.

7582.

template<typename Stream>

7583.

void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const \

7584.

7585.

CSerActionSerialize ser_action;

7586.

const bool fGetSize = false;

7587.

const bool fWrite = true;

7588.

const bool fRead = false;

7589.

unsigned int nSerSize = 0;

7590.

{statements}

\
\

\
\
\
\

7591.

7592.

template<typename Stream>

7593.

void Unserialize(Stream& s, int nType=0, int nVersion=VERSION) \

7594.

7595.

CSerActionUnserialize ser_action;

7596.

const bool fGetSize = false;

7597.

const bool fWrite = false;

7598.

const bool fRead = true;

7599.

unsigned int nSerSize = 0;

7600.

{statements}

7601.

\
\

7602. #define READWRITE(obj)

(nSerSize += ::SerReadWrite(s, (obj), nType, nVersion, ser_action))

7603. #define WRITEDATA(s, obj) s.write((char*)&(obj), sizeof(obj))


7604. #define READDATA(s, obj)

s.read((char*)&(obj), sizeof(obj))

7605. inline unsigned int GetSerializeSize(char a,

int, int=0) { return sizeof(a); }

7606. inline unsigned int GetSerializeSize(signed char a, int, int=0) { return sizeof(a); }
7607. inline unsigned int GetSerializeSize(unsigned char a, int, int=0) { return sizeof(a); }
7608. inline unsigned int GetSerializeSize(signed short a, int, int=0) { return sizeof(a); }
7609. inline unsigned int GetSerializeSize(unsigned short a, int, int=0) { return sizeof(a); }
7610. inline unsigned int GetSerializeSize(signed int a,

int, int=0) { return sizeof(a); }

7611. inline unsigned int GetSerializeSize(unsigned int a, int, int=0) { return sizeof(a); }
7612. inline unsigned int GetSerializeSize(signed long a, int, int=0) { return sizeof(a); }
7613. inline unsigned int GetSerializeSize(unsigned long a, int, int=0) { return sizeof(a); }
7614. inline unsigned int GetSerializeSize(int64 a,

int, int=0) { return sizeof(a); }

7615. inline unsigned int GetSerializeSize(uint64 a,


7616. inline unsigned int GetSerializeSize(float a,

int, int=0) { return sizeof(a); }


int, int=0) { return sizeof(a); }

7617. inline unsigned int GetSerializeSize(double a,

int, int=0) { return sizeof(a); }

7618. template<typename Stream> inline void Serialize(Stream& s, char a,

int, int=0) { WRITEDATA(s, a); }

7619. template<typename Stream> inline void Serialize(Stream& s, signed char a, int, int=0) { WRITEDATA(s, a); }
7620. template<typename Stream> inline void Serialize(Stream& s, unsigned char a, int, int=0) { WRITEDATA(s, a); }
7621. template<typename Stream> inline void Serialize(Stream& s, signed short a, int, int=0) { WRITEDATA(s, a); }
7622. template<typename Stream> inline void Serialize(Stream& s, unsigned short a, int, int=0) { WRITEDATA(s, a); }
7623. template<typename Stream> inline void Serialize(Stream& s, signed int a,

int, int=0) { WRITEDATA(s, a); }

7624. template<typename Stream> inline void Serialize(Stream& s, unsigned int a, int, int=0) { WRITEDATA(s, a); }
7625. template<typename Stream> inline void Serialize(Stream& s, signed long a, int, int=0) { WRITEDATA(s, a); }
7626. template<typename Stream> inline void Serialize(Stream& s, unsigned long a, int, int=0) { WRITEDATA(s, a); }
7627. template<typename Stream> inline void Serialize(Stream& s, int64 a,

int, int=0) { WRITEDATA(s, a); }

7628. template<typename Stream> inline void Serialize(Stream& s, uint64 a,


7629. template<typename Stream> inline void Serialize(Stream& s, float a,

int, int=0) { WRITEDATA(s, a); }


int, int=0) { WRITEDATA(s, a); }

7630. template<typename Stream> inline void Serialize(Stream& s, double a,

int, int=0) { WRITEDATA(s, a); }

7631. template<typename Stream> inline void Unserialize(Stream& s, char& a,

int, int=0) { READDATA(s, a); }

7632. template<typename Stream> inline void Unserialize(Stream& s, signed char& a, int, int=0) { READDATA(s, a); }
7633. template<typename Stream> inline void Unserialize(Stream& s, unsigned char& a, int, int=0) { READDATA(s, a); }
7634. template<typename Stream> inline void Unserialize(Stream& s, signed short& a, int, int=0) { READDATA(s, a); }
7635. template<typename Stream> inline void Unserialize(Stream& s, unsigned short& a, int, int=0) { READDATA(s, a); }
7636. template<typename Stream> inline void Unserialize(Stream& s, signed int& a,

int, int=0) { READDATA(s, a); }

7637. template<typename Stream> inline void Unserialize(Stream& s, unsigned int& a, int, int=0) { READDATA(s, a); }
7638. template<typename Stream> inline void Unserialize(Stream& s, signed long& a, int, int=0) { READDATA(s, a); }
7639. template<typename Stream> inline void Unserialize(Stream& s, unsigned long& a, int, int=0) { READDATA(s, a); }
7640. template<typename Stream> inline void Unserialize(Stream& s, int64& a,

int, int=0) { READDATA(s, a); }

7641. template<typename Stream> inline void Unserialize(Stream& s, uint64& a,


7642. template<typename Stream> inline void Unserialize(Stream& s, float& a,

int, int=0) { READDATA(s, a); }


int, int=0) { READDATA(s, a); }

7643. template<typename Stream> inline void Unserialize(Stream& s, double& a,


7644. inline unsigned int GetSerializeSize(bool a, int, int=0)

int, int=0) { READDATA(s, a); }

{ return sizeof(char); }

7645. template<typename Stream> inline void Serialize(Stream& s, bool a, int, int=0)

{ char f=a; WRITEDATA(s, f); }

7646. template<typename Stream> inline void Unserialize(Stream& s, bool& a, int, int=0) { char f; READDATA(s, f); a=f; }
7647. inline unsigned int GetSizeOfCompactSize(uint64 nSize)
7648. {
7649.

if (nSize < UCHAR_MAX-2)

7650.

else if (nSize <= USHRT_MAX) return sizeof(unsigned char) + sizeof(unsigned short);

return sizeof(unsigned char);

7651.

else if (nSize <= UINT_MAX) return sizeof(unsigned char) + sizeof(unsigned int);

7652.

else

return sizeof(unsigned char) + sizeof(uint64);

7653. }
7654. template<typename Stream>
7655. void WriteCompactSize(Stream& os, uint64 nSize)
7656. {
7657.

if (nSize < UCHAR_MAX-2)

7658.

7659.

unsigned char chSize = nSize;

7660.

WRITEDATA(os, chSize);

7661.

7662.

else if (nSize <= USHRT_MAX)

7663.

7664.

unsigned char chSize = UCHAR_MAX-2;

7665.

unsigned short xSize = nSize;

7666.

WRITEDATA(os, chSize);

7667.

WRITEDATA(os, xSize);

7668.

7669.

else if (nSize <= UINT_MAX)

7670.

7671.

unsigned char chSize = UCHAR_MAX-1;

7672.

unsigned int xSize = nSize;

7673.

WRITEDATA(os, chSize);

7674.

WRITEDATA(os, xSize);

7675.

7676.

else

7677.

7678.

unsigned char chSize = UCHAR_MAX;

7679.

WRITEDATA(os, chSize);

7680.

WRITEDATA(os, nSize);

7681.

7682.

return;

7683. }
7684. template<typename Stream>
7685. uint64 ReadCompactSize(Stream& is)

7686. {
7687.

unsigned char chSize;

7688.

READDATA(is, chSize);

7689.

if (chSize < UCHAR_MAX-2)

7690.

7691.

return chSize;

7692.

7693.

else if (chSize == UCHAR_MAX-2)

7694.

7695.

unsigned short nSize;

7696.

READDATA(is, nSize);

7697.

return nSize;

7698.

7699.

else if (chSize == UCHAR_MAX-1)

7700.

7701.

unsigned int nSize;

7702.

READDATA(is, nSize);

7703.

return nSize;

7704.

7705.

else

7706.

7707.

uint64 nSize;

7708.

READDATA(is, nSize);

7709.
7710.

return nSize;
}

7711. }
7712. #define FLATDATA(obj) REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj)))
7713. class CFlatData
7714. {
7715. protected:
7716.

char* pbegin;

7717.

char* pend;

7718. public:
7719.

CFlatData(void* pbeginIn, void* pendIn) : pbegin((char*)pbeginIn), pend((char*)pendIn) { }

7720.

char* begin() { return pbegin; }

7721.

const char* begin() const { return pbegin; }

7722.

char* end() { return pend; }

7723.

const char* end() const { return pend; }

7724.

unsigned int GetSerializeSize(int, int=0) const

7725.

7726.

return pend - pbegin;

7727.

7728.

template<typename Stream>

7729.

void Serialize(Stream& s, int, int=0) const

7730.

7731.

s.write(pbegin, pend - pbegin);

7732.

7733.

template<typename Stream>

7734.

void Unserialize(Stream& s, int, int=0)

7735.

7736.
7737.

s.read(pbegin, pend - pbegin);


}

7738. };
7739. template<std::size_t LEN>
7740. class CFixedFieldString
7741. {
7742. protected:
7743.

const string* pcstr;

7744.

string* pstr;

7745. public:
7746.

explicit CFixedFieldString(const string& str) : pcstr(&str), pstr(NULL) { }

7747.

explicit CFixedFieldString(string& str) : pcstr(&str), pstr(&str) { }

7748.

unsigned int GetSerializeSize(int, int=0) const

7749.

7750.

return LEN;

7751.

7752.

template<typename Stream>

7753.

void Serialize(Stream& s, int, int=0) const

7754.

7755.

char pszBuf[LEN];

7756.

strncpy(pszBuf, pcstr->c_str(), LEN);

7757.

s.write(pszBuf, LEN);

7758.

7759.

template<typename Stream>

7760.

void Unserialize(Stream& s, int, int=0)

7761.

7762.

if (pstr == NULL)

7763.

throw std::ios_base::failure("CFixedFieldString::Unserialize : trying to unserialize to const string");

7764.

char pszBuf[LEN+1];

7765.

s.read(pszBuf, LEN);

7766.

pszBuf[LEN] = '\0';

7767.
7768.

*pstr = pszBuf;
}

7769. };
7770. template<typename C> unsigned int GetSerializeSize(const basic_string<C>& str, int, int=0);
7771. template<typename Stream, typename C> void Serialize(Stream& os, const basic_string<C>& str, int, int=0);
7772. template<typename Stream, typename C> void Unserialize(Stream& is, basic_string<C>& str, int, int=0);
7773. template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&);
7774. template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const
boost::false_type&);
7775. template<typename T, typename A> inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion=VERSION);
7776. template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const
boost::true_type&);
7777. template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const
boost::false_type&);
7778. template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int
nVersion=VERSION);
7779. template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const
boost::true_type&);
7780. template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const
boost::false_type&);
7781. template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion=VERSION);
7782. extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion=VERSION);
7783. template<typename Stream> void Serialize(Stream& os, const CScript& v, int nType, int nVersion=VERSION);
7784. template<typename Stream> void Unserialize(Stream& is, CScript& v, int nType, int nVersion=VERSION);
7785. template<typename K, typename T> unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion=VERSION);
7786. template<typename Stream, typename K, typename T> void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion=VERSION);
7787. template<typename Stream, typename K, typename T> void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion=VERSION);
7788. template<typename K, typename T, typename Pred, typename A> unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int
nVersion=VERSION);
7789. template<typename Stream, typename K, typename T, typename Pred, typename A> void Serialize(Stream& os, const std::map<K, T, Pred, A>& m,
int nType, int nVersion=VERSION);
7790. template<typename Stream, typename K, typename T, typename Pred, typename A> void Unserialize(Stream& is, std::map<K, T, Pred, A>& m, int
nType, int nVersion=VERSION);
7791. template<typename K, typename Pred, typename A> unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int
nVersion=VERSION);
7792. template<typename Stream, typename K, typename Pred, typename A> void Serialize(Stream& os, const std::set<K, Pred, A>& m, int nType, int
nVersion=VERSION);
7793. template<typename Stream, typename K, typename Pred, typename A> void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int
nVersion=VERSION);
7794. template<typename T>
7795. inline unsigned int GetSerializeSize(const T& a, long nType, int nVersion=VERSION)
7796. {
7797.

return a.GetSerializeSize((int)nType, nVersion);

7798. }
7799. template<typename Stream, typename T>
7800. inline void Serialize(Stream& os, const T& a, long nType, int nVersion=VERSION)
7801. {
7802.

a.Serialize(os, (int)nType, nVersion);

7803. }
7804. template<typename Stream, typename T>
7805. inline void Unserialize(Stream& is, T& a, long nType, int nVersion=VERSION)
7806. {
7807.

a.Unserialize(is, (int)nType, nVersion);

7808. }
7809. template<typename C>
7810. unsigned int GetSerializeSize(const basic_string<C>& str, int, int)
7811. {
7812.

return GetSizeOfCompactSize(str.size()) + str.size() * sizeof(str[0]);

7813. }
7814. template<typename Stream, typename C>
7815. void Serialize(Stream& os, const basic_string<C>& str, int, int)
7816. {
7817.

WriteCompactSize(os, str.size());

7818.

if (!str.empty())

7819.

os.write((char*)&str[0], str.size() * sizeof(str[0]));

7820. }
7821. template<typename Stream, typename C>
7822. void Unserialize(Stream& is, basic_string<C>& str, int, int)
7823. {
7824.

unsigned int nSize = ReadCompactSize(is);

7825.

str.resize(nSize);

7826.

if (nSize != 0)

7827.

is.read((char*)&str[0], nSize * sizeof(str[0]));

7828. }
7829. template<typename T, typename A>
7830. unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&)
7831. {
7832.

return (GetSizeOfCompactSize(v.size()) + v.size() * sizeof(T));

7833. }
7834. template<typename T, typename A>
7835. unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&)
7836. {
7837.

unsigned int nSize = GetSizeOfCompactSize(v.size());

7838.

for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)

7839.

nSize += GetSerializeSize((*vi), nType, nVersion);

7840.

return nSize;

7841. }
7842. template<typename T, typename A>
7843. inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion)
7844. {
7845.

return GetSerializeSize_impl(v, nType, nVersion, boost::is_fundamental<T>());

7846. }
7847. template<typename Stream, typename T, typename A>
7848. void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&)
7849. {
7850.

WriteCompactSize(os, v.size());

7851.

if (!v.empty())

7852.

os.write((char*)&v[0], v.size() * sizeof(T));

7853. }
7854. template<typename Stream, typename T, typename A>
7855. void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&)
7856. {
7857.

WriteCompactSize(os, v.size());

7858.

for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)

7859.

::Serialize(os, (*vi), nType, nVersion);

7860. }
7861. template<typename Stream, typename T, typename A>
7862. inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion)
7863. {
7864.

Serialize_impl(os, v, nType, nVersion, boost::is_fundamental<T>());

7865. }
7866. template<typename Stream, typename T, typename A>
7867. void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&)
7868. {
7869.

v.clear();

7870.

unsigned int nSize = ReadCompactSize(is);

7871.

unsigned int i = 0;

7872.

while (i < nSize)

7873.

7874.

unsigned int blk = min(nSize - i, 1 + 4999999 / sizeof(T));

7875.

v.resize(i + blk);

7876.

is.read((char*)&v[i], blk * sizeof(T));

7877.
7878.

i += blk;
}

7879. }
7880. template<typename Stream, typename T, typename A>
7881. void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&)
7882. {
7883.

v.clear();

7884.

unsigned int nSize = ReadCompactSize(is);

7885.

unsigned int i = 0;

7886.

unsigned int nMid = 0;

7887.

while (nMid < nSize)

7888.

7889.

nMid += 5000000 / sizeof(T);

7890.

if (nMid > nSize)

7891.

nMid = nSize;

7892.

v.resize(nMid);

7893.

for (; i < nMid; i++)

7894.
7895.

Unserialize(is, v[i], nType, nVersion);


}

7896. }
7897. template<typename Stream, typename T, typename A>
7898. inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion)
7899. {
7900.

Unserialize_impl(is, v, nType, nVersion, boost::is_fundamental<T>());

7901. }
7902. inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion)
7903. {
7904.

return GetSerializeSize((const vector<unsigned char>&)v, nType, nVersion);

7905. }
7906. template<typename Stream>
7907. void Serialize(Stream& os, const CScript& v, int nType, int nVersion)
7908. {
7909.

Serialize(os, (const vector<unsigned char>&)v, nType, nVersion);

7910. }
7911. template<typename Stream>
7912. void Unserialize(Stream& is, CScript& v, int nType, int nVersion)
7913. {
7914.

Unserialize(is, (vector<unsigned char>&)v, nType, nVersion);

7915. }
7916. template<typename K, typename T>
7917. unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion)
7918. {
7919.

return GetSerializeSize(item.first, nType, nVersion) + GetSerializeSize(item.second, nType, nVersion);

7920. }
7921. template<typename Stream, typename K, typename T>
7922. void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion)

7923. {
7924.

Serialize(os, item.first, nType, nVersion);

7925.

Serialize(os, item.second, nType, nVersion);

7926. }
7927. template<typename Stream, typename K, typename T>
7928. void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion)
7929. {
7930.

Unserialize(is, item.first, nType, nVersion);

7931.

Unserialize(is, item.second, nType, nVersion);

7932. }
7933. template<typename K, typename T, typename Pred, typename A>
7934. unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion)
7935. {
7936.

unsigned int nSize = GetSizeOfCompactSize(m.size());

7937.

for (typename std::map<K, T, Pred, A>::const_iterator mi = m.begin(); mi != m.end(); ++mi)

7938.
7939.

nSize += GetSerializeSize((*mi), nType, nVersion);


return nSize;

7940. }
7941. template<typename Stream, typename K, typename T, typename Pred, typename A>
7942. void Serialize(Stream& os, const std::map<K, T, Pred, A>& m, int nType, int nVersion)
7943. {
7944.

WriteCompactSize(os, m.size());

7945.

for (typename std::map<K, T, Pred, A>::const_iterator mi = m.begin(); mi != m.end(); ++mi)

7946.

Serialize(os, (*mi), nType, nVersion);

7947. }
7948. template<typename Stream, typename K, typename T, typename Pred, typename A>
7949. void Unserialize(Stream& is, std::map<K, T, Pred, A>& m, int nType, int nVersion)
7950. {
7951.

m.clear();

7952.

unsigned int nSize = ReadCompactSize(is);

7953.

typename std::map<K, T, Pred, A>::iterator mi = m.begin();

7954.

for (unsigned int i = 0; i < nSize; i++)

7955.

7956.

pair<K, T> item;

7957.

Unserialize(is, item, nType, nVersion);

7958.
7959.

mi = m.insert(mi, item);
}

7960. }
7961. template<typename K, typename Pred, typename A>
7962. unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion)
7963. {
7964.

unsigned int nSize = GetSizeOfCompactSize(m.size());

7965.

for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it)

7966.
7967.

nSize += GetSerializeSize((*it), nType, nVersion);


return nSize;

7968. }
7969. template<typename Stream, typename K, typename Pred, typename A>
7970. void Serialize(Stream& os, const std::set<K, Pred, A>& m, int nType, int nVersion)
7971. {
7972.

WriteCompactSize(os, m.size());

7973.

for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it)

7974.

Serialize(os, (*it), nType, nVersion);

7975. }
7976. template<typename Stream, typename K, typename Pred, typename A>
7977. void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion)
7978. {
7979.

m.clear();

7980.

unsigned int nSize = ReadCompactSize(is);

7981.

typename std::set<K, Pred, A>::iterator it = m.begin();

7982.

for (unsigned int i = 0; i < nSize; i++)

7983.

7984.

K key;

7985.

Unserialize(is, key, nType, nVersion);

7986.
7987.

it = m.insert(it, key);
}

7988. }
7989. class CSerActionGetSerializeSize { };
7990. class CSerActionSerialize { };
7991. class CSerActionUnserialize { };
7992. template<typename Stream, typename T>
7993. inline unsigned int SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionGetSerializeSize ser_action)
7994. {
7995.

return ::GetSerializeSize(obj, nType, nVersion);

7996. }
7997. template<typename Stream, typename T>
7998. inline unsigned int SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionSerialize ser_action)
7999. {
8000.

::Serialize(s, obj, nType, nVersion);

8001.

return 0;

8002. }
8003. template<typename Stream, typename T>
8004. inline unsigned int SerReadWrite(Stream& s, T& obj, int nType, int nVersion, CSerActionUnserialize ser_action)
8005. {

8006.

::Unserialize(s, obj, nType, nVersion);

8007.

return 0;

8008. }
8009. struct ser_streamplaceholder
8010. {
8011.

int nType;

8012.

int nVersion;

8013. };
8014. template<typename T>
8015. struct secure_allocator : public std::allocator<T>
8016. {
8017.

typedef std::allocator<T> base;

8018.

typedef typename base::size_type size_type;

8019.

typedef typename base::difference_type difference_type;

8020.

typedef typename base::pointer pointer;

8021.

typedef typename base::const_pointer const_pointer;

8022.

typedef typename base::reference reference;

8023.

typedef typename base::const_reference const_reference;

8024.

typedef typename base::value_type value_type;

8025.

secure_allocator() throw() {}

8026.

secure_allocator(const secure_allocator& a) throw() : base(a) {}

8027.

~secure_allocator() throw() {}

8028.

template<typename _Other> struct rebind

8029.

{ typedef secure_allocator<_Other> other; };

8030.

void deallocate(T* p, std::size_t n)

8031.

8032.

if (p != NULL)

8033.

memset(p, 0, sizeof(T) * n);

8034.

allocator<T>::deallocate(p, n);

8035.

8036. };
8037. class CDataStream
8038. {
8039. protected:
8040.

typedef vector<char, secure_allocator<char> > vector_type;

8041.

vector_type vch;

8042.

unsigned int nReadPos;

8043.

short state;

8044.

short exceptmask;

8045. public:
8046.

int nType;

8047.

int nVersion;

8048.

typedef vector_type::allocator_type allocator_type;

8049.

typedef vector_type::size_type

8050.

typedef vector_type::difference_type difference_type;

8051.

typedef vector_type::reference

8052.

typedef vector_type::const_reference const_reference;

8053.

typedef vector_type::value_type

8054.

typedef vector_type::iterator

8055.

typedef vector_type::const_iterator const_iterator;

8056.

typedef vector_type::reverse_iterator reverse_iterator;

8057.

explicit CDataStream(int nTypeIn=0, int nVersionIn=VERSION)

8058.

8059.

size_type;
reference;
value_type;
iterator;

Init(nTypeIn, nVersionIn);

8060.

8061.

CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn=0, int nVersionIn=VERSION) : vch(pbegin, pend)

8062.

8063.
8064.

Init(nTypeIn, nVersionIn);
}

8065. #if !defined(_MSC_VER) || _MSC_VER >= 1300


8066.

CDataStream(const char* pbegin, const char* pend, int nTypeIn=0, int nVersionIn=VERSION) : vch(pbegin, pend)

8067.

8068.
8069.

Init(nTypeIn, nVersionIn);
}

8070. #endif
8071.

CDataStream(const vector_type& vchIn, int nTypeIn=0, int nVersionIn=VERSION) : vch(vchIn.begin(), vchIn.end())

8072.

8073.

Init(nTypeIn, nVersionIn);

8074.

8075.

CDataStream(const vector<char>& vchIn, int nTypeIn=0, int nVersionIn=VERSION) : vch(vchIn.begin(), vchIn.end())

8076.

8077.
8078.
8079.

Init(nTypeIn, nVersionIn);
}
CDataStream(const vector<unsigned char>& vchIn, int nTypeIn=0, int nVersionIn=VERSION) : vch((char*)&vchIn.begin()[0],
(char*)&vchIn.end()[0])

8080.

8081.

Init(nTypeIn, nVersionIn);

8082.

8083.

void Init(int nTypeIn=0, int nVersionIn=VERSION)

8084.

8085.

nReadPos = 0;

8086.

nType = nTypeIn;

8087.

nVersion = nVersionIn;

8088.

state = 0;

8089.

exceptmask = ios::badbit | ios::failbit;

8090.

8091.

CDataStream& operator+=(const CDataStream& b)

8092.

8093.

vch.insert(vch.end(), b.begin(), b.end());

8094.

return *this;

8095.

8096.

friend CDataStream operator+(const CDataStream& a, const CDataStream& b)

8097.

8098.

CDataStream ret = a;

8099.

ret += b;

8100.

return (ret);

8101.

8102.

string str() const

8103.

8104.

return (string(begin(), end()));

8105.

8106.

const_iterator begin() const

8107.

iterator begin()

8108.

const_iterator end() const

8109.

iterator end()

8110.

size_type size() const

8111.

bool empty() const

8112.

void resize(size_type n, value_type c=0)

8113.

void reserve(size_type n)

8114.

const_reference operator[](size_type pos) const { return vch[pos + nReadPos]; }

8115.

reference operator[](size_type pos)

8116.

void clear()

8117.

iterator insert(iterator it, const char& x=char()) { return vch.insert(it, x); }

8118.

void insert(iterator it, size_type n, const char& x) { vch.insert(it, n, x); }

8119.

void insert(iterator it, const_iterator first, const_iterator last)

8120.

{ return vch.begin() + nReadPos; }


{ return vch.begin() + nReadPos; }
{ return vch.end(); }
{ return vch.end(); }
{ return vch.size() - nReadPos; }
{ return vch.size() == nReadPos; }
{ vch.resize(n + nReadPos, c); }

{ vch.reserve(n + nReadPos); }
{ return vch[pos + nReadPos]; }

{ vch.clear(); nReadPos = 0; }

8121.

if (it == vch.begin() + nReadPos && last - first <= nReadPos)

8122.

8123.

nReadPos -= (last - first);

8124.

memcpy(&vch[nReadPos], &first[0], last - first);

8125.

8126.

else

8127.
8128.

vch.insert(it, first, last);


}

8129. #if !defined(_MSC_VER) || _MSC_VER >= 1300


8130.

void insert(iterator it, const char* first, const char* last)

8131.

8132.
8133.

insert(it, (const_iterator)first, (const_iterator)last);


}

8134. #endif
8135.

iterator erase(iterator it)

8136.

8137.

if (it == vch.begin() + nReadPos)

8138.

8139.

if (++nReadPos >= vch.size())

8140.

8141.

nReadPos = 0;

8142.

return vch.erase(vch.begin(), vch.end());

8143.

8144.

return vch.begin() + nReadPos;

8145.

8146.

else

8147.

return vch.erase(it);

8148.

8149.

iterator erase(iterator first, iterator last)

8150.

8151.

if (first == vch.begin() + nReadPos)

8152.

8153.

if (last == vch.end())

8154.

8155.

nReadPos = 0;

8156.

return vch.erase(vch.begin(), vch.end());

8157.

8158.

else

8159.

8160.

nReadPos = (last - vch.begin());

8161.

return last;

8162.

8163.

8164.

else

8165.

return vch.erase(first, last);

8166.

8167.

inline void Compact()

8168.

8169.

vch.erase(vch.begin(), vch.begin() + nReadPos);

8170.

nReadPos = 0;

8171.

8172.

bool Rewind(size_type n)

8173.

8174.

if (n > nReadPos)

8175.

return false;

8176.

nReadPos -= n;

8177.

return true;

8178.

8179.

void setstate(short bits, const char* psz)

8180.

8181.

state |= bits;

8182.

if (state & exceptmask)

8183.

throw std::ios_base::failure(psz);

8184.

8185.

bool eof() const

8186.

bool fail() const

8187.

bool good() const

{ return !eof() && (state == 0); }

8188.

void clear(short n)

{ state = n; }

8189.

short exceptions()

{ return exceptmask; }

8190.

short exceptions(short mask) { short prev = exceptmask; exceptmask = mask; setstate(0, "CDataStream"); return prev; }

8191.

CDataStream* rdbuf()

8192.

int in_avail()

8193.

void SetType(int n)

8194.

int GetType()

8195.

void SetVersion(int n)

8196.

int GetVersion()

8197.

void ReadVersion()

8198.

void WriteVersion()

8199.

CDataStream& read(char* pch, int nSize)

8200.

{ return size() == 0; }
{ return state & (ios::badbit | ios::failbit); }

{ return this; }

{ return size(); }
{ nType = n; }
{ return nType; }
{ nVersion = n; }
{ return nVersion; }
{ *this >> nVersion; }
{ *this << nVersion; }

8201.

assert(nSize >= 0);

8202.

unsigned int nReadPosNext = nReadPos + nSize;

8203.

if (nReadPosNext >= vch.size())

8204.

8205.

if (nReadPosNext > vch.size())

8206.

8207.

setstate(ios::failbit, "CDataStream::read() : end of data");

8208.

memset(pch, 0, nSize);

8209.

nSize = vch.size() - nReadPos;

8210.

8211.

memcpy(pch, &vch[nReadPos], nSize);

8212.

nReadPos = 0;

8213.

vch.clear();

8214.

return (*this);

8215.

8216.

memcpy(pch, &vch[nReadPos], nSize);

8217.

nReadPos = nReadPosNext;

8218.

return (*this);

8219.

8220.

CDataStream& ignore(int nSize)

8221.

8222.

assert(nSize >= 0);

8223.

unsigned int nReadPosNext = nReadPos + nSize;

8224.

if (nReadPosNext >= vch.size())

8225.

8226.

if (nReadPosNext > vch.size())

8227.

8228.

setstate(ios::failbit, "CDataStream::ignore() : end of data");

8229.

nSize = vch.size() - nReadPos;

8230.

8231.

nReadPos = 0;

8232.

vch.clear();

8233.

return (*this);

8234.

8235.

nReadPos = nReadPosNext;

8236.

return (*this);

8237.

8238.

CDataStream& write(const char* pch, int nSize)

8239.

8240.

assert(nSize >= 0);

8241.

vch.insert(vch.end(), pch, pch + nSize);

8242.

return (*this);

8243.

8244.

template<typename Stream>

8245.

void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const

8246.

8247.

if (!vch.empty())

8248.

s.write((char*)&vch[0], vch.size() * sizeof(vch[0]));

8249.

8250.

template<typename T>

8251.

unsigned int GetSerializeSize(const T& obj)

8252.

8253.

return ::GetSerializeSize(obj, nType, nVersion);

8254.

8255.

template<typename T>

8256.

CDataStream& operator<<(const T& obj)

8257.

8258.

::Serialize(*this, obj, nType, nVersion);

8259.

return (*this);

8260.

8261.

template<typename T>

8262.

CDataStream& operator>>(T& obj)

8263.

8264.

::Unserialize(*this, obj, nType, nVersion);

8265.
8266.

return (*this);
}

8267. };
8268. #ifdef TESTCDATASTREAM
8269. #include <iostream>
8270. int main(int argc, char *argv[])
8271. {
8272.

vector<unsigned char> vch(0xcc, 250);

8273.

printf("CDataStream:\n");

8274.

for (int n = 1000; n <= 4500000; n *= 2)

8275.

8276.

CDataStream ss;

8277.

time_t nStart = time(NULL);

8278.

for (int i = 0; i < n; i++)

8279.

ss.write((char*)&vch[0], vch.size());

8280.

printf("n=%-10d %d seconds\n", n, time(NULL) - nStart);

8281.

8282.

printf("stringstream:\n");

8283.

for (int n = 1000; n <= 4500000; n *= 2)

8284.

8285.

stringstream ss;

8286.

time_t nStart = time(NULL);

8287.

for (int i = 0; i < n; i++)

8288.

ss.write((char*)&vch[0], vch.size());

8289.
8290.

printf("n=%-10d %d seconds\n", n, time(NULL) - nStart);


}

8291. }
8292. #endif
8293. class CAutoFile
8294. {
8295. protected:
8296.

FILE* file;

8297.

short state;

8298.

short exceptmask;

8299. public:
8300.

int nType;

8301.

int nVersion;

8302.

typedef FILE element_type;

8303.

CAutoFile(FILE* filenew=NULL, int nTypeIn=SER_DISK, int nVersionIn=VERSION)

8304.

8305.

file = filenew;

8306.

nType = nTypeIn;

8307.

nVersion = nVersionIn;

8308.

state = 0;

8309.

exceptmask = ios::badbit | ios::failbit;

8310.

8311.

~CAutoFile()

8312.

8313.

fclose();

8314.

8315.

void fclose()

8316.

8317.

if (file != NULL && file != stdin && file != stdout && file != stderr)

8318.

::fclose(file);

8319.

file = NULL;

8320.

8321.

FILE* release()

{ FILE* ret = file; file = NULL; return ret; }

8322.

operator FILE*()

{ return file; }

8323.

FILE* operator->()

{ return file; }

8324.

FILE& operator*()

{ return *file; }

8325.

FILE** operator&()

{ return &file; }

8326.

FILE* operator=(FILE* pnew) { return file = pnew; }

8327.

bool operator!()

8328.

void setstate(short bits, const char* psz)

8329.

{ return (file == NULL); }

8330.

state |= bits;

8331.

if (state & exceptmask)

8332.

throw std::ios_base::failure(psz);

8333.

8334.

bool fail() const

8335.

bool good() const

8336.

void clear(short n = 0)

{ return state & (ios::badbit | ios::failbit); }


{ return state == 0; }
{ state = n; }

8337.

short exceptions()

8338.

short exceptions(short mask) { short prev = exceptmask; exceptmask = mask; setstate(0, "CAutoFile"); return prev; }

8339.

void SetType(int n)

8340.

int GetType()

8341.

void SetVersion(int n)

8342.

int GetVersion()

8343.

void ReadVersion()

8344.

void WriteVersion()

8345.

CAutoFile& read(char* pch, int nSize)

8346.

8347.

{ return exceptmask; }
{ nType = n; }
{ return nType; }
{ nVersion = n; }
{ return nVersion; }
{ *this >> nVersion; }
{ *this << nVersion; }

if (!file)

8348.

throw std::ios_base::failure("CAutoFile::read : file handle is NULL");

8349.

if (fread(pch, 1, nSize, file) != nSize)

8350.

setstate(ios::failbit, feof(file) ? "CAutoFile::read : end of file" : "CAutoFile::read : fread failed");

8351.

return (*this);

8352.

8353.

CAutoFile& write(const char* pch, int nSize)

8354.

8355.

if (!file)

8356.

throw std::ios_base::failure("CAutoFile::write : file handle is NULL");

8357.

if (fwrite(pch, 1, nSize, file) != nSize)

8358.

setstate(ios::failbit, "CAutoFile::write : write failed");

8359.

return (*this);

8360.

8361.

template<typename T>

8362.

unsigned int GetSerializeSize(const T& obj)

8363.

8364.

return ::GetSerializeSize(obj, nType, nVersion);

8365.

8366.

template<typename T>

8367.

CAutoFile& operator<<(const T& obj)

8368.

8369.

if (!file)

8370.

throw std::ios_base::failure("CAutoFile::operator<< : file handle is NULL");

8371.

::Serialize(*this, obj, nType, nVersion);

8372.

return (*this);

8373.

8374.

template<typename T>

8375.

CAutoFile& operator>>(T& obj)

8376.

8377.

if (!file)

8378.

throw std::ios_base::failure("CAutoFile::operator>> : file handle is NULL");

8379.

::Unserialize(*this, obj, nType, nVersion);

8380.
8381.

return (*this);
}

8382. };
8383. #include "headers.h"
8384. #ifdef _MSC_VER
8385. #include <crtdbg.h>
8386. #endif
8387. DEFINE_EVENT_TYPE(wxEVT_CROSSTHREADCALL)
8388. DEFINE_EVENT_TYPE(wxEVT_REPLY1)
8389. DEFINE_EVENT_TYPE(wxEVT_REPLY2)
8390. DEFINE_EVENT_TYPE(wxEVT_REPLY3)
8391. DEFINE_EVENT_TYPE(wxEVT_TABLEADDED)
8392. DEFINE_EVENT_TYPE(wxEVT_TABLEUPDATED)
8393. DEFINE_EVENT_TYPE(wxEVT_TABLEDELETED)
8394. CMainFrame* pframeMain = NULL;
8395. map<string, string> mapAddressBook;
8396. void ThreadRequestProductDetails(void* parg);
8397. void ThreadRandSendTest(void* parg);
8398. bool fRandSendTest = false;
8399. void RandSend();
8400. void HandleCtrlA(wxKeyEvent& event)
8401. {
8402.

wxTextCtrl* textCtrl = (wxTextCtrl*)event.GetEventObject();

8403.

if (event.GetModifiers() == wxMOD_CONTROL && event.GetKeyCode() == 'A')

8404.
8405.

textCtrl->SetSelection(-1, -1);
event.Skip();

8406. }
8407. bool Is24HourTime()
8408. {
8409.

return true;

8410. }
8411. string DateStr(int64 nTime)
8412. {
8413.

return (string)wxDateTime((time_t)nTime).FormatDate();

8414. }
8415. string DateTimeStr(int64 nTime)
8416. {
8417.

wxDateTime datetime((time_t)nTime);

8418.

if (Is24HourTime())

8419.

return (string)datetime.Format("%x %H:%M");

8420.

else

8421.

return (string)datetime.Format("%x ") + itostr((datetime.GetHour() + 11) % 12 + 1) + (string)datetime.Format(":%M %p");

8422. }
8423. wxString GetItemText(wxListCtrl* listCtrl, int nIndex, int nColumn)
8424. {
8425.

wxListItem item;

8426.

item.m_itemId = nIndex;

8427.

item.m_col = nColumn;

8428.

item.m_mask = wxLIST_MASK_TEXT;

8429.

if (!listCtrl->GetItem(item))

8430.

return "";

8431.

return item.GetText();

8432. }
8433. int InsertLine(wxListCtrl* listCtrl, const wxString& str0, const wxString& str1)
8434. {
8435.

int nIndex = listCtrl->InsertItem(listCtrl->GetItemCount(), str0);

8436.

listCtrl->SetItem(nIndex, 1, str1);

8437.

return nIndex;

8438. }
8439. int InsertLine(wxListCtrl* listCtrl, const wxString& str0, const wxString& str1, const wxString& str2, const wxString& str3, const wxString& str4)
8440. {
8441.

int nIndex = listCtrl->InsertItem(listCtrl->GetItemCount(), str0);

8442.

listCtrl->SetItem(nIndex, 1, str1);

8443.

listCtrl->SetItem(nIndex, 2, str2);

8444.

listCtrl->SetItem(nIndex, 3, str3);

8445.

listCtrl->SetItem(nIndex, 4, str4);

8446.

return nIndex;

8447. }
8448. int InsertLine(wxListCtrl* listCtrl, void* pdata, const wxString& str0, const wxString& str1, const wxString& str2, const wxString& str3, const wxString&
str4)
8449. {
8450.

int nIndex = listCtrl->InsertItem(listCtrl->GetItemCount(), str0);

8451.

listCtrl->SetItemPtrData(nIndex, (wxUIntPtr)pdata);

8452.

listCtrl->SetItem(nIndex, 1, str1);

8453.

listCtrl->SetItem(nIndex, 2, str2);

8454.

listCtrl->SetItem(nIndex, 3, str3);

8455.

listCtrl->SetItem(nIndex, 4, str4);

8456.

return nIndex;

8457. }
8458. void SetSelection(wxListCtrl* listCtrl, int nIndex)
8459. {
8460.

int nSize = listCtrl->GetItemCount();

8461.

long nState = (wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED);

8462.

for (int i = 0; i < nSize; i++)

8463.

listCtrl->SetItemState(i, (i == nIndex ? nState : 0), nState);

8464. }
8465. int GetSelection(wxListCtrl* listCtrl)
8466. {
8467.

int nSize = listCtrl->GetItemCount();

8468.

for (int i = 0; i < nSize; i++)

8469.

if (listCtrl->GetItemState(i, wxLIST_STATE_FOCUSED))

8470.
8471.

return i;
return -1;

8472. }
8473. string HtmlEscape(const char* psz, bool fMultiLine=false)
8474. {
8475.

int len = 0;

8476.

for (const char* p = psz; *p; p++)

8477.

8478.

if (*p == '<') len += 4;

8479.

else if (*p == '>') len += 4;

8480.

else if (*p == '&') len += 5;

8481.

else if (*p == '"') len += 6;

8482.

else if (*p == ' ' && p > psz && p[-1] == ' ' && p[1] == ' ') len += 6;

8483.

else if (*p == '\n' && fMultiLine) len += 5;

8484.

else

8485.

len++;

8486.

8487.

string str;

8488.

str.reserve(len);

8489.

for (const char* p = psz; *p; p++)

8490.

8491.

if (*p == '<') str += "&lt;";

8492.

else if (*p == '>') str += "&gt;";

8493.

else if (*p == '&') str += "&amp;";

8494.

else if (*p == '"') str += "&quot;";

8495.

else if (*p == ' ' && p > psz && p[-1] == ' ' && p[1] == ' ') str += "&nbsp;";

8496.

else if (*p == '\n' && fMultiLine) str += "<br>\n";

8497.

else

8498.

str += *p;

8499.

8500.

return str;

8501. }

8502. string HtmlEscape(const string& str, bool fMultiLine=false)


8503. {
8504.

return HtmlEscape(str.c_str(), fMultiLine);

8505. }
8506. void AddToMyProducts(CProduct product)
8507. {
8508.

CProduct& productInsert = mapMyProducts[product.GetHash()];

8509.

productInsert = product;

8510.

InsertLine(pframeMain->m_listCtrlProductsSent, &productInsert,

8511.

product.mapValue["category"],

8512.

product.mapValue["title"].substr(0, 100),

8513.

product.mapValue["description"].substr(0, 100),

8514.

product.mapValue["price"],

8515.

"");

8516. }
8517. set<void*> setCallbackAvailable;
8518. CCriticalSection cs_setCallbackAvailable;
8519. void AddCallbackAvailable(void* p)
8520. {
8521.
8522.

CRITICAL_BLOCK(cs_setCallbackAvailable)
setCallbackAvailable.insert(p);

8523. }
8524. void RemoveCallbackAvailable(void* p)
8525. {
8526.
8527.

CRITICAL_BLOCK(cs_setCallbackAvailable)
setCallbackAvailable.erase(p);

8528. }
8529. bool IsCallbackAvailable(void* p)
8530. {
8531.
8532.
8533.

CRITICAL_BLOCK(cs_setCallbackAvailable)
return setCallbackAvailable.count(p);
return false;

8534. }
8535. template<typename T>
8536. void AddPendingCustomEvent(wxEvtHandler* pevthandler, int nEventID, const T pbeginIn, const T pendIn)
8537. {
8538.
8539.

if (!pevthandler)
return;

8540.

const char* pbegin = (pendIn != pbeginIn) ? &pbeginIn[0] : NULL;

8541.

const char* pend = pbegin + (pendIn - pbeginIn) * sizeof(pbeginIn[0]);

8542.

wxCommandEvent event(nEventID);

8543.

wxString strData(wxChar(0), (pend - pbegin) / sizeof(wxChar) + 1);

8544.

memcpy(&strData[0], pbegin, pend - pbegin);

8545.

event.SetString(strData);

8546.

event.SetInt(pend - pbegin);

8547.

pevthandler->AddPendingEvent(event);

8548. }
8549. template<class T>
8550. void AddPendingCustomEvent(wxEvtHandler* pevthandler, int nEventID, const T& obj)
8551. {
8552.

CDataStream ss;

8553.

ss << obj;

8554.

AddPendingCustomEvent(pevthandler, nEventID, ss.begin(), ss.end());

8555. }
8556. void AddPendingReplyEvent1(void* pevthandler, CDataStream& vRecv)
8557. {
8558.
8559.

if (IsCallbackAvailable(pevthandler))
AddPendingCustomEvent((wxEvtHandler*)pevthandler, wxEVT_REPLY1, vRecv.begin(), vRecv.end());

8560. }
8561. void AddPendingReplyEvent2(void* pevthandler, CDataStream& vRecv)
8562. {
8563.
8564.

if (IsCallbackAvailable(pevthandler))
AddPendingCustomEvent((wxEvtHandler*)pevthandler, wxEVT_REPLY2, vRecv.begin(), vRecv.end());

8565. }
8566. void AddPendingReplyEvent3(void* pevthandler, CDataStream& vRecv)
8567. {
8568.
8569.

if (IsCallbackAvailable(pevthandler))
AddPendingCustomEvent((wxEvtHandler*)pevthandler, wxEVT_REPLY3, vRecv.begin(), vRecv.end());

8570. }
8571. CDataStream GetStreamFromEvent(const wxCommandEvent& event)
8572. {
8573.

wxString strData = event.GetString();

8574.

return CDataStream(strData.begin(), strData.begin() + event.GetInt(), SER_NETWORK);

8575. }
8576. CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent)
8577. {
8578.

Connect(wxEVT_CROSSTHREADCALL, wxCommandEventHandler(CMainFrame::OnCrossThreadCall), NULL, this);

8579.

fRefreshListCtrl = false;

8580.

fRefreshListCtrlRunning = false;

8581.

fOnSetFocusAddress = false;

8582.

pindexBestLast = NULL;

8583.

m_choiceFilter->SetSelection(0);

8584.

m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " ");

8585.

m_listCtrl->SetFocus();

8586.

SetIcon(wxICON(bitcoin));

8587.

m_menuOptions->Check(wxID_OPTIONSGENERATEBITCOINS, fGenerateBitcoins);

8588.

m_toolBar->ClearTools();

8589.

wxBitmap bmpSend(wxT("send20"), wxBITMAP_TYPE_RESOURCE);

8590.

bmpSend.SetMask(new wxMask(wxBitmap(wxT("send20mask"), wxBITMAP_TYPE_RESOURCE)));

8591.

m_toolBar->AddTool(wxID_BUTTONSEND, wxT("&Send Coins"), bmpSend, wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString);

8592.

wxBitmap bmpAddressBook(wxT("addressbook20"), wxBITMAP_TYPE_RESOURCE);

8593.

bmpAddressBook.SetMask(new wxMask(wxBitmap(wxT("addressbook20mask"), wxBITMAP_TYPE_RESOURCE)));

8594.

m_toolBar->AddTool(wxID_BUTTONRECEIVE, wxT("&Address Book"), bmpAddressBook, wxNullBitmap, wxITEM_NORMAL, wxEmptyString,


wxEmptyString);

8595.

m_toolBar->Realize();

8596.

int nDateWidth = DateTimeStr(1229413914).size() * 6 + 8;

8597.

m_listCtrl->InsertColumn(0, "",

wxLIST_FORMAT_LEFT,

0);

8598.

m_listCtrl->InsertColumn(1, "",

wxLIST_FORMAT_LEFT,

0);

8599.

m_listCtrl->InsertColumn(2, "Status",

wxLIST_FORMAT_LEFT, 90);

8600.

m_listCtrl->InsertColumn(3, "Date",

wxLIST_FORMAT_LEFT, nDateWidth);

8601.

m_listCtrl->InsertColumn(4, "Description", wxLIST_FORMAT_LEFT, 409 - nDateWidth);

8602.

m_listCtrl->InsertColumn(5, "Debit",

wxLIST_FORMAT_RIGHT, 79);

8603.

m_listCtrl->InsertColumn(6, "Credit",

wxLIST_FORMAT_RIGHT, 79);

8604.

int pnWidths[3] = { -100, 81, 286 };

8605.

m_statusBar->SetFieldsCount(3, pnWidths);

8606.

vector<unsigned char> vchPubKey;

8607.

if (CWalletDB("r").ReadDefaultKey(vchPubKey))

8608.

m_textCtrlAddress->SetValue(PubKeyToAddress(vchPubKey));

8609.

RefreshListCtrl();

8610. }
8611. CMainFrame::~CMainFrame()
8612. {
8613.

pframeMain = NULL;

8614. }
8615. void Shutdown(void* parg)
8616. {
8617.

static CCriticalSection cs_Shutdown;

8618.

CRITICAL_BLOCK(cs_Shutdown)

8619.

8620.

fShutdown = true;

8621.

nTransactionsUpdated++;

8622.

DBFlush(false);

8623.

StopNode();

8624.

DBFlush(true);

8625.

printf("Bitcoin exiting\n");

8626.

exit(0);

8627.

8628. }
8629. void CMainFrame::OnClose(wxCloseEvent& event)
8630. {
8631.

Destroy();

8632.

_beginthread(Shutdown, 0, NULL);

8633. }
8634. void CMainFrame::OnMouseEvents(wxMouseEvent& event)
8635. {
8636.

RandAddSeed();

8637.

RAND_add(&event.m_x, sizeof(event.m_x), 0.25);

8638.

RAND_add(&event.m_y, sizeof(event.m_y), 0.25);

8639. }
8640. void CMainFrame::OnListColBeginDrag(wxListEvent& event)
8641. {
8642.

if (event.GetColumn() <= 1 && !fDebug)

8643.

event.Veto();

8644. }
8645. void CMainFrame::InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxString& str2, const wxString& str3, const wxString& str4,
const wxString& str5, const wxString& str6)
8646. {
8647.

string str0 = strSort;

8648.

long nData = *(long*)&hashKey;

8649.

if (fNew)

8650.

8651.

nIndex = m_listCtrl->InsertItem(0, str0);

8652.

8653.

else

8654.

8655.

if (nIndex == -1)

8656.

8657.

while ((nIndex = m_listCtrl->FindItem(nIndex, nData)) != -1)

8658.

if (GetItemText(m_listCtrl, nIndex, 1) == hashKey.ToString())

8659.

break;

8660.

if (nIndex == -1)

8661.

8662.

printf("CMainFrame::InsertLine : Couldn't find item to be updated\n");

8663.

return;

8664.
8665.

}
}

8666.

if (GetItemText(m_listCtrl, nIndex, 0) != str0)

8667.

8668.

m_listCtrl->DeleteItem(nIndex);

8669.

nIndex = m_listCtrl->InsertItem(0, str0);

8670.

8671.

8672.

m_listCtrl->SetItem(nIndex, 1, hashKey.ToString());

8673.

m_listCtrl->SetItem(nIndex, 2, str2);

8674.

m_listCtrl->SetItem(nIndex, 3, str3);

8675.

m_listCtrl->SetItem(nIndex, 4, str4);

8676.

m_listCtrl->SetItem(nIndex, 5, str5);

8677.

m_listCtrl->SetItem(nIndex, 6, str6);

8678.

m_listCtrl->SetItemData(nIndex, nData);

8679. }
8680. string FormatTxStatus(const CWalletTx& wtx)
8681. {
8682.

int nDepth = wtx.GetDepthInMainChain();

8683.

if (!wtx.IsFinal())

8684.
8685.

return strprintf("Open for %d blocks", nBestHeight - wtx.nLockTime);


else if (nDepth < 6)

8686.
8687.

return strprintf("%d/unconfirmed", nDepth);


else

8688.

return strprintf("%d blocks", nDepth);

8689. }
8690. void CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex)
8691. {
8692.

int64 nTime = wtx.nTimeDisplayed = wtx.GetTxTime();

8693.

int64 nCredit = wtx.GetCredit();

8694.

int64 nDebit = wtx.GetDebit();

8695.

int64 nNet = nCredit - nDebit;

8696.

uint256 hash = wtx.GetHash();

8697.

string strStatus = FormatTxStatus(wtx);

8698.

map<string, string> mapValue = wtx.mapValue;

8699.

CBlockIndex* pindex = NULL;

8700.

map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(wtx.hashBlock);

8701.

if (mi != mapBlockIndex.end())

8702.
8703.

pindex = (*mi).second;
string strSort = strprintf("%010d-%01d-%010u",

8704.

(pindex ? pindex->nHeight : INT_MAX),

8705.

(wtx.IsCoinBase() ? 1 : 0),

8706.

wtx.nTimeReceived);

8707.

if (nNet > 0 || wtx.IsCoinBase())

8708.

8709.

string strDescription;

8710.

if (wtx.IsCoinBase())

8711.

8712.

strDescription = "Generated";

8713.

if (nCredit == 0)

8714.

8715.

int64 nUnmatured = 0;

8716.

foreach(const CTxOut& txout, wtx.vout)

8717.

nUnmatured += txout.GetCredit();

8718.

if (wtx.IsInMainChain())

8719.

strDescription += strprintf(" (%s matures in %d blocks)", FormatMoney(nUnmatured).c_str(), wtx.GetBlocksToMaturity());

8720.

else

8721.

strDescription += " (not accepted)";

8722.

8723.

8724.

else if (!mapValue["from"].empty() || !mapValue["message"].empty())

8725.

8726.

if (!mapValue["from"].empty())

8727.

strDescription += "From: " + mapValue["from"];

8728.

if (!mapValue["message"].empty())

8729.

8730.

if (!strDescription.empty())

8731.

strDescription += " - ";

8732.

strDescription += mapValue["message"];

8733.

8734.

8735.

else

8736.

8737.

foreach(const CTxOut& txout, wtx.vout)

8738.

8739.

if (txout.IsMine())

8740.

8741.

vector<unsigned char> vchPubKey;

8742.

if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey))

8743.

8744.

string strAddress = PubKeyToAddress(vchPubKey);

8745.

if (mapAddressBook.count(strAddress))

8746.

8747.

strDescription += "Received with: ";

8748.

if (!mapAddressBook[strAddress].empty())

8749.

strDescription += mapAddressBook[strAddress] + " ";

8750.

strDescription += strAddress;

8751.

8752.

8753.

break;

8754.

8755.

8756.

8757.

string strDescription2;

8758.

foreach(int c, strDescription)

8759.

if (c >= ' ')

8760.

strDescription2 += c;

8761.

InsertLine(fNew, nIndex, hash, strSort,

8762.

strStatus,

8763.

nTime ? DateTimeStr(nTime) : "",

8764.

strDescription2,

8765.

"",

8766.

FormatMoney(nNet, true));

8767.

8768.

else

8769.

8770.

bool fAllFromMe = true;

8771.

foreach(const CTxIn& txin, wtx.vin)

8772.

fAllFromMe = fAllFromMe && txin.IsMine();

8773.

bool fAllToMe = true;

8774.

foreach(const CTxOut& txout, wtx.vout)

8775.

fAllToMe = fAllToMe && txout.IsMine();

8776.

if (fAllFromMe && fAllToMe)

8777.

8778.

int64 nValue = wtx.vout[0].nValue;

8779.

InsertLine(fNew, nIndex, hash, strSort,

8780.

strStatus,

8781.

nTime ? DateTimeStr(nTime) : "",

8782.

"Payment to yourself",

8783.

FormatMoney(nNet - nValue, true),

8784.

FormatMoney(nValue, true));

8785.

8786.

else if (fAllFromMe)

8787.

8788.

int64 nTxFee = nDebit - wtx.GetValueOut();

8789.

for (int nOut = 0; nOut < wtx.vout.size(); nOut++)

8790.

8791.

const CTxOut& txout = wtx.vout[nOut];

8792.

if (txout.IsMine())

8793.

continue;

8794.

string strAddress;

8795.

if (!mapValue["to"].empty())

8796.

8797.

strAddress = mapValue["to"];

8798.

8799.

else

8800.

8801.

uint160 hash160;

8802.

if (ExtractHash160(txout.scriptPubKey, hash160))

8803.

strAddress = Hash160ToAddress(hash160);

8804.

8805.

string strDescription = "To: ";

8806.

if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty())

8807.

strDescription += mapAddressBook[strAddress] + " ";

8808.

strDescription += strAddress;

8809.

if (!mapValue["message"].empty())

8810.

8811.

if (!strDescription.empty())

8812.

strDescription += " - ";

8813.

strDescription += mapValue["message"];

8814.

8815.

string strDescription2;

8816.

foreach(int c, strDescription)

8817.

if (c >= ' ')

8818.

strDescription2 += c;

8819.

int64 nValue = txout.nValue;

8820.

if (nOut == 0 && nTxFee > 0)

8821.

nValue += nTxFee;

8822.

InsertLine(fNew, nIndex, hash, strprintf("%s-%d", strSort.c_str(), nOut),

8823.

strStatus,

8824.

nTime ? DateTimeStr(nTime) : "",

8825.

strDescription2,

8826.

FormatMoney(-nValue, true),

8827.

"");

8828.

8829.

8830.

else

8831.

8832.

bool fAllMine = true;

8833.

foreach(const CTxOut& txout, wtx.vout)

8834.

fAllMine = fAllMine && txout.IsMine();

8835.

foreach(const CTxIn& txin, wtx.vin)

8836.

fAllMine = fAllMine && txin.IsMine();

8837.

InsertLine(fNew, nIndex, hash, strSort,

8838.

strStatus,

8839.

nTime ? DateTimeStr(nTime) : "",

8840.

"",

8841.

FormatMoney(nNet, true),

8842.

"");

8843.
8844.

}
}

8845. }
8846. void CMainFrame::RefreshStatus()
8847. {
8848.

static int nLastTop;

8849.

int nTop = m_listCtrl->GetTopItem();

8850.

if (nTop == nLastTop && pindexBestLast == pindexBest)

8851.

return;

8852.

TRY_CRITICAL_BLOCK(cs_mapWallet)

8853.

8854.

int nStart = nTop;

8855.

int nEnd = min(nStart + 100, m_listCtrl->GetItemCount());

8856.

if (pindexBestLast == pindexBest)

8857.

8858.

if (nStart >= nLastTop && nStart < nLastTop + 100)

8859.

nStart = nLastTop + 100;

8860.

if (nEnd >= nLastTop && nEnd < nLastTop + 100)

8861.

nEnd = nLastTop;

8862.

8863.

nLastTop = nTop;

8864.

pindexBestLast = pindexBest;

8865.

for (int nIndex = nStart; nIndex < nEnd; nIndex++)

8866.

8867.

uint256 hash((string)GetItemText(m_listCtrl, nIndex, 1));

8868.

map<uint256, CWalletTx>::iterator mi = mapWallet.find(hash);

8869.

if (mi == mapWallet.end())

8870.

8871.

printf("CMainFrame::RefreshStatus() : tx not found in mapWallet\n");

8872.

continue;

8873.

8874.

const CWalletTx& wtx = (*mi).second;

8875.

if (wtx.IsCoinBase() || wtx.GetTxTime() != wtx.nTimeDisplayed)

8876.

InsertTransaction(wtx, false, nIndex);

8877.

else

8878.

m_listCtrl->SetItem(nIndex, 2, FormatTxStatus(wtx));

8879.
8880.

}
}

8881. }
8882. void CMainFrame::RefreshListCtrl()
8883. {
8884.

fRefreshListCtrl = true;

8885.

::wxWakeUpIdle();

8886. }
8887. void CMainFrame::OnIdle(wxIdleEvent& event)
8888. {
8889.

if (fRefreshListCtrl)

8890.

8891.

bool fEntered = false;

8892.

vector<pair<unsigned int, uint256> > vSorted;

8893.

TRY_CRITICAL_BLOCK(cs_mapWallet)

8894.

8895.

printf("RefreshListCtrl starting\n");

8896.

fEntered = true;

8897.

fRefreshListCtrl = false;

8898.

vWalletUpdated.clear();

8899.

vSorted.reserve(mapWallet.size());

8900.

for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)

8901.

8902.

const CWalletTx& wtx = (*it).second;

8903.

unsigned int nTime = UINT_MAX - wtx.GetTxTime();

8904.

vSorted.push_back(make_pair(nTime, (*it).first));

8905.

8906.

m_listCtrl->DeleteAllItems();

8907.

8908.

if (!fEntered)

8909.

return;

8910.

sort(vSorted.begin(), vSorted.end());

8911.

for (int i = 0; i < vSorted.size();)

8912.

8913.
8914.

if (fShutdown)
return;

8915.

bool fEntered = false;

8916.

TRY_CRITICAL_BLOCK(cs_mapWallet)

8917.

8918.

fEntered = true;

8919.

uint256& hash = vSorted[i++].second;

8920.

map<uint256, CWalletTx>::iterator mi = mapWallet.find(hash);

8921.

if (mi != mapWallet.end())

8922.

InsertTransaction((*mi).second, true);

8923.

8924.

if (!fEntered || i == 100 || i % 500 == 0)

8925.

wxYield();

8926.

8927.

printf("RefreshListCtrl done\n");

8928.

8929.

else

8930.

8931.

static int64 nLastTime;

8932.

if (GetTime() > nLastTime + 30)

8933.

8934.

TRY_CRITICAL_BLOCK(cs_mapWallet)

8935.

8936.

nLastTime = GetTime();

8937.

for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)

8938.

8939.

CWalletTx& wtx = (*it).second;

8940.

if (wtx.nTimeDisplayed && wtx.nTimeDisplayed != wtx.GetTxTime())

8941.

InsertTransaction(wtx, false);

8942.

8943.

8944.
8945.

}
}

8946. }
8947. void CMainFrame::OnPaint(wxPaintEvent& event)
8948. {
8949.

event.Skip();

8950. }
8951. void CMainFrame::OnPaintListCtrl(wxPaintEvent& event)
8952. {
8953.

if (!vWalletUpdated.empty())

8954.

8955.

TRY_CRITICAL_BLOCK(cs_mapWallet)

8956.

8957.

pair<uint256, bool> item;

8958.

foreach(item, vWalletUpdated)

8959.

8960.

bool fNew = item.second;

8961.

map<uint256, CWalletTx>::iterator mi = mapWallet.find(item.first);

8962.

if (mi != mapWallet.end())

8963.

8964.

printf("vWalletUpdated: %s %s\n", (*mi).second.GetHash().ToString().substr(0,6).c_str(), fNew ? "new" : "");

8965.

InsertTransaction((*mi).second, fNew);

8966.

8967.

8968.

m_listCtrl->ScrollList(0, INT_MAX);

8969.

vWalletUpdated.clear();

8970.

8971.

8972.

RefreshStatus();

8973.

string strGen = "";

8974.

if (fGenerateBitcoins)

8975.
8976.
8977.

strGen = " Generating";


if (fGenerateBitcoins && vNodes.empty())
strGen = "(not connected)";

8978.

m_statusBar->SetStatusText(strGen, 1);

8979.

string strStatus = strprintf("

8980.

m_statusBar->SetStatusText(strStatus, 2);

8981.

TRY_CRITICAL_BLOCK(cs_mapWallet)

8982.
8983.

%d connections

%d blocks

%d transactions", vNodes.size(), nBestHeight + 1, m_listCtrl->GetItemCount());

m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " ");


m_listCtrl->OnPaint(event);

8984. }
8985. void CrossThreadCall(wxCommandEvent& event)
8986. {
8987.
8988.

if (pframeMain)
pframeMain->GetEventHandler()->AddPendingEvent(event);

8989. }
8990. void CrossThreadCall(int nID, void* pdata)
8991. {
8992.

wxCommandEvent event;

8993.

event.SetInt(nID);

8994.

event.SetClientData(pdata);

8995.

if (pframeMain)

8996.
8997. }

pframeMain->GetEventHandler()->AddPendingEvent(event);

8998. void CMainFrame::OnCrossThreadCall(wxCommandEvent& event)


8999. {
9000.

void* pdata = event.GetClientData();

9001.

switch (event.GetInt())

9002.

9003.

case UICALL_ADDORDER:

9004.

9005.

break;

9006.

9007.

case UICALL_UPDATEORDER:

9008.

9009.

break;

9010.
9011.

}
}

9012. }
9013. void CMainFrame::OnMenuFileExit(wxCommandEvent& event)
9014. {
9015.

Close(true);

9016. }
9017. void CMainFrame::OnMenuOptionsGenerate(wxCommandEvent& event)
9018. {
9019.

fGenerateBitcoins = event.IsChecked();

9020.

nTransactionsUpdated++;

9021.

CWalletDB().WriteSetting("fGenerateBitcoins", fGenerateBitcoins);

9022.

if (fGenerateBitcoins)

9023.

if (_beginthread(ThreadBitcoinMiner, 0, NULL) == -1)

9024.

printf("Error: _beginthread(ThreadBitcoinMiner) failed\n");

9025.
9026.

Refresh();

9027.

wxPaintEvent eventPaint;

9028.

AddPendingEvent(eventPaint);

9029. }
9030. void CMainFrame::OnMenuOptionsOptions(wxCommandEvent& event)
9031. {
9032.

COptionsDialog dialog(this);

9033.

dialog.ShowModal();

9034. }
9035. void CMainFrame::OnMenuHelpAbout(wxCommandEvent& event)
9036. {
9037.

CAboutDialog dialog(this);

9038.

dialog.ShowModal();

9039. }
9040. void CMainFrame::OnButtonSend(wxCommandEvent& event)
9041. {
9042.

if (fRandSendTest)

9043.

9044.

RandSend();

9045.

return;

9046.

9047.

CSendDialog dialog(this);

9048.

dialog.ShowModal();

9049. }
9050. void CMainFrame::OnButtonAddressBook(wxCommandEvent& event)
9051. {
9052.

CAddressBookDialog dialogAddr(this, "", false);

9053.

if (dialogAddr.ShowModal() == 2)

9054.

9055.

CSendDialog dialogSend(this, dialogAddr.GetAddress());

9056.
9057.

dialogSend.ShowModal();
}

9058. }
9059. void CMainFrame::OnSetFocusAddress(wxFocusEvent& event)
9060. {
9061.

m_textCtrlAddress->SetSelection(-1, -1);

9062.

fOnSetFocusAddress = true;

9063.

event.Skip();

9064. }
9065. void CMainFrame::OnMouseEventsAddress(wxMouseEvent& event)
9066. {
9067.

if (fOnSetFocusAddress)

9068.

m_textCtrlAddress->SetSelection(-1, -1);

9069.

fOnSetFocusAddress = false;

9070.

event.Skip();

9071. }
9072. void CMainFrame::OnButtonCopy(wxCommandEvent& event)
9073. {
9074.

if (wxTheClipboard->Open())

9075.

9076.

wxTheClipboard->SetData(new wxTextDataObject(m_textCtrlAddress->GetValue()));

9077.
9078.

wxTheClipboard->Close();
}

9079. }
9080. void CMainFrame::OnButtonChange(wxCommandEvent& event)

9081. {
9082.

CYourAddressDialog dialog(this, string(m_textCtrlAddress->GetValue()));

9083.

if (!dialog.ShowModal())

9084.

return;

9085.

string strAddress = (string)dialog.GetAddress();

9086.

if (strAddress != m_textCtrlAddress->GetValue())

9087.

9088.

uint160 hash160;

9089.

if (!AddressToHash160(strAddress, hash160))

9090.

return;

9091.

if (!mapPubKeys.count(hash160))

9092.

return;

9093.

CWalletDB().WriteDefaultKey(mapPubKeys[hash160]);

9094.
9095.

m_textCtrlAddress->SetValue(strAddress);
}

9096. }
9097. void CMainFrame::OnListItemActivatedAllTransactions(wxListEvent& event)
9098. {
9099.

uint256 hash((string)GetItemText(m_listCtrl, event.GetIndex(), 1));

9100.

CWalletTx wtx;

9101.

CRITICAL_BLOCK(cs_mapWallet)

9102.

9103.

map<uint256, CWalletTx>::iterator mi = mapWallet.find(hash);

9104.

if (mi == mapWallet.end())

9105.

9106.

printf("CMainFrame::OnListItemActivatedAllTransactions() : tx not found in mapWallet\n");

9107.

return;

9108.

9109.

wtx = (*mi).second;

9110.

9111.

CTxDetailsDialog dialog(this, wtx);

9112.

dialog.ShowModal();

9113. }
9114. void CMainFrame::OnListItemActivatedProductsSent(wxListEvent& event)
9115. {
9116.

CProduct& product = *(CProduct*)event.GetItem().GetData();

9117.

CEditProductDialog* pdialog = new CEditProductDialog(this);

9118.

pdialog->SetProduct(product);

9119.

pdialog->Show();

9120. }
9121. void CMainFrame::OnListItemActivatedOrdersSent(wxListEvent& event)
9122. {
9123.

CWalletTx& order = *(CWalletTx*)event.GetItem().GetData();

9124.

CViewOrderDialog* pdialog = new CViewOrderDialog(this, order, false);

9125.

pdialog->Show();

9126. }
9127. void CMainFrame::OnListItemActivatedOrdersReceived(wxListEvent& event)
9128. {
9129.

CWalletTx& order = *(CWalletTx*)event.GetItem().GetData();

9130.

CViewOrderDialog* pdialog = new CViewOrderDialog(this, order, true);

9131.

pdialog->Show();

9132. }
9133. CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetailsDialogBase(parent)
9134. {
9135.

string strHTML;

9136.

strHTML.reserve(4000);

9137.

int64 nTime = wtx.GetTxTime();

9138.

int64 nCredit = wtx.GetCredit();

9139.

int64 nDebit = wtx.GetDebit();

9140.

int64 nNet = nCredit - nDebit;

9141.

strHTML += "<b>Status:</b> " + FormatTxStatus(wtx) + "<br>";

9142.

strHTML += "<b>Date:</b> " + (nTime ? DateTimeStr(nTime) : "") + "<br>";

9143.

if (wtx.IsCoinBase())

9144.

9145.

strHTML += "<b>Source:</b> Generated<br>";

9146.

9147.

else if (!wtx.mapValue["from"].empty())

9148.

9149.

if (!wtx.mapValue["from"].empty())

9150.

strHTML += "<b>From:</b> " + HtmlEscape(wtx.mapValue["from"]) + "<br>";

9151.

9152.

else

9153.

9154.

foreach(const CTxOut& txout, wtx.vout)

9155.

9156.

if (txout.IsMine())

9157.

9158.

vector<unsigned char> vchPubKey;

9159.

if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey))

9160.

9161.

string strAddress = PubKeyToAddress(vchPubKey);

9162.

if (mapAddressBook.count(strAddress))

9163.

9164.

strHTML += "<b>Received with:</b> ";

9165.

if (!mapAddressBook[strAddress].empty())

9166.

strHTML += mapAddressBook[strAddress] + " ";

9167.

strHTML += HtmlEscape(strAddress);

9168.

strHTML += "<br>";

9169.

9170.

9171.

break;

9172.

9173.

9174.

9175.

string strAddress;

9176.

if (!wtx.mapValue["to"].empty())

9177.

9178.

strAddress = wtx.mapValue["to"];

9179.

strHTML += "<b>To:</b> ";

9180.

if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty())

9181.

strHTML += mapAddressBook[strAddress] + " ";

9182.

strHTML += HtmlEscape(strAddress) + "<br>";

9183.

9184.

if (wtx.IsCoinBase() && nCredit == 0)

9185.

{/

9186.

int64 nUnmatured = 0;

9187.

foreach(const CTxOut& txout, wtx.vout)

9188.

nUnmatured += txout.GetCredit();

9189.

if (wtx.IsInMainChain())

9190.

strHTML += strprintf("<b>Credit:</b> (%s matures in %d blocks)<br>", FormatMoney(nUnmatured).c_str(), wtx.GetBlocksToMaturity());

9191.

else

9192.

strHTML += "<b>Credit:</b> (not accepted)<br>";

9193.

9194.

else if (nNet > 0)

9195.

9196.

strHTML += "<b>Credit:</b> " + FormatMoney(nNet) + "<br>";

9197.

9198.

else

9199.

9200.

bool fAllFromMe = true;

9201.

foreach(const CTxIn& txin, wtx.vin)

9202.

fAllFromMe = fAllFromMe && txin.IsMine();

9203.

bool fAllToMe = true;

9204.

foreach(const CTxOut& txout, wtx.vout)

9205.

fAllToMe = fAllToMe && txout.IsMine();

9206.

if (fAllFromMe)

9207.

9208.

foreach(const CTxOut& txout, wtx.vout)

9209.

9210.

if (txout.IsMine())

9211.

continue;

9212.

string strAddress;

9213.

if (!wtx.mapValue["to"].empty())

9214.

9215.

strAddress = wtx.mapValue["to"];

9216.

9217.

else

9218.

9219.

uint160 hash160;

9220.

if (ExtractHash160(txout.scriptPubKey, hash160))

9221.

strAddress = Hash160ToAddress(hash160);

9222.

9223.

strHTML += "<b>Debit:</b> " + FormatMoney(-txout.nValue) + " &nbsp;&nbsp; ";

9224.

strHTML += "(to ";

9225.

if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty())

9226.

strHTML += mapAddressBook[strAddress] + " ";

9227.

strHTML += strAddress;

9228.

strHTML += ")<br>";

9229.

9230.

if (fAllToMe)

9231.

9232.

int64 nValue = wtx.vout[0].nValue;

9233.

strHTML += "<b>Debit:</b> " + FormatMoney(-nValue) + "<br>";

9234.

strHTML += "<b>Credit:</b> " + FormatMoney(nValue) + "<br>";

9235.

9236.

int64 nTxFee = nDebit - wtx.GetValueOut();

9237.

if (nTxFee > 0)

9238.

strHTML += "<b>Transaction fee:</b> " + FormatMoney(-nTxFee) + "<br>";

9239.

9240.

else

9241.

9242.
9243.
9244.
9245.
9246.

foreach(const CTxIn& txin, wtx.vin)


if (txin.IsMine())
strHTML += "<b>Debit:</b> " + FormatMoney(-txin.GetDebit()) + "<br>";
foreach(const CTxOut& txout, wtx.vout)
if (txout.IsMine())

9247.

strHTML += "<b>Credit:</b> " + FormatMoney(txout.GetCredit()) + "<br>";

9248.

9249.

9250.

strHTML += "<b>Net amount:</b> " + FormatMoney(nNet, true) + "<br>";

9251.

if (!wtx.mapValue["message"].empty())

9252.

strHTML += "<br><b>Message:</b><br>" + HtmlEscape(wtx.mapValue["message"], true) + "<br>";

9253.

if (fDebug)

9254.

9255.

strHTML += "<hr><br>debug print<br><br>";

9256.

foreach(const CTxIn& txin, wtx.vin)

9257.

if (txin.IsMine())

9258.

strHTML += "<b>Debit:</b> " + FormatMoney(-txin.GetDebit()) + "<br>";

9259.

foreach(const CTxOut& txout, wtx.vout)

9260.

if (txout.IsMine())

9261.

strHTML += "<b>Credit:</b> " + FormatMoney(txout.GetCredit()) + "<br>";

9262.

strHTML += "<b>Inputs:</b><br>";

9263.

CRITICAL_BLOCK(cs_mapWallet)

9264.

9265.

foreach(const CTxIn& txin, wtx.vin)

9266.

9267.

COutPoint prevout = txin.prevout;

9268.

map<uint256, CWalletTx>::iterator mi = mapWallet.find(prevout.hash);

9269.

if (mi != mapWallet.end())

9270.

9271.

const CWalletTx& prev = (*mi).second;

9272.

if (prevout.n < prev.vout.size())

9273.

9274.

strHTML += HtmlEscape(prev.ToString(), true);

9275.

strHTML += " &nbsp;&nbsp; " + FormatTxStatus(prev) + ", ";

9276.

strHTML = strHTML + "IsMine=" + (prev.vout[prevout.n].IsMine() ? "true" : "false") + "<br>";

9277.

9278.

9279.

9280.

9281.

strHTML += "<br><hr><br><b>Transaction:</b><br>";

9282.

strHTML += HtmlEscape(wtx.ToString(), true);

9283.

9284.

string(strHTML.begin(), strHTML.end()).swap(strHTML);

9285.

m_htmlWin->SetPage(strHTML);

9286.

m_buttonOK->SetFocus();

9287. }
9288. void CTxDetailsDialog::OnButtonOK(wxCommandEvent& event)
9289. {
9290.

Close();

9291. }
9292. COptionsDialog::COptionsDialog(wxWindow* parent) : COptionsDialogBase(parent)
9293. {
9294.

m_textCtrlTransactionFee->SetValue(FormatMoney(nTransactionFee));

9295.

m_buttonOK->SetFocus();

9296. }
9297. void COptionsDialog::OnKillFocusTransactionFee(wxFocusEvent& event)
9298. {
9299.

int64 nTmp = nTransactionFee;

9300.

ParseMoney(m_textCtrlTransactionFee->GetValue(), nTmp);

9301.

m_textCtrlTransactionFee->SetValue(FormatMoney(nTmp));

9302. }
9303. void COptionsDialog::OnButtonOK(wxCommandEvent& event)
9304. {
9305.

int64 nPrevTransactionFee = nTransactionFee;

9306.

if (ParseMoney(m_textCtrlTransactionFee->GetValue(), nTransactionFee) && nTransactionFee != nPrevTransactionFee)

9307.
9308.

CWalletDB().WriteSetting("nTransactionFee", nTransactionFee);
Close();

9309. }
9310. void COptionsDialog::OnButtonCancel(wxCommandEvent& event)
9311. {
9312.

Close();

9313. }
9314. CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent)
9315. {
9316.

m_staticTextVersion->SetLabel(strprintf("version 0.%d.%d Alpha", VERSION/100, VERSION%100));

9317.

wxString str = m_staticTextMain->GetLabel();

9318.

if (str.Find('') != wxNOT_FOUND)

9319.
9320.

str.Remove(str.Find(''), 1);
m_staticTextMain->SetLabel(str);

9321. }
9322. void CAboutDialog::OnButtonOK(wxCommandEvent& event)
9323. {
9324.

Close();

9325. }
9326. CSendDialog::CSendDialog(wxWindow* parent, const wxString& strAddress) : CSendDialogBase(parent)
9327. {
9328.

m_textCtrlAddress->SetValue(strAddress);

9329.

m_choiceTransferType->SetSelection(0);

9330.

m_bitmapCheckMark->Show(false);

9331.

wxBitmap bmpSend(wxT("send16"), wxBITMAP_TYPE_RESOURCE);

9332.

bmpSend.SetMask(new wxMask(wxBitmap(wxT("send16masknoshadow"), wxBITMAP_TYPE_RESOURCE)));

9333.

wxIcon iconSend;

9334.

iconSend.CopyFromBitmap(bmpSend);

9335.

SetIcon(iconSend);

9336.

wxCommandEvent event;

9337.

OnTextAddress(event);

9338.

m_buttonPaste->MoveAfterInTabOrder(m_buttonCancel);

9339.

m_buttonAddress->MoveAfterInTabOrder(m_buttonPaste);

9340.

this->Layout();

9341. }
9342. void CSendDialog::OnTextAddress(wxCommandEvent& event)
9343. {
9344.

bool fBitcoinAddress = IsValidBitcoinAddress(m_textCtrlAddress->GetValue());

9345.

m_bitmapCheckMark->Show(fBitcoinAddress);

9346.

bool fEnable = !fBitcoinAddress;

9347.

m_staticTextFrom->Enable(fEnable);

9348.

m_textCtrlFrom->Enable(fEnable);

9349.

m_staticTextMessage->Enable(fEnable);

9350.

m_textCtrlMessage->Enable(fEnable);

9351.

m_textCtrlMessage->SetBackgroundColour(wxSystemSettings::GetColour(fEnable ? wxSYS_COLOUR_WINDOW :
wxSYS_COLOUR_BTNFACE));

9352. }
9353. void CSendDialog::OnKillFocusAmount(wxFocusEvent& event)
9354. {
9355.

if (m_textCtrlAmount->GetValue().Trim().empty())

9356.

return;

9357.

int64 nTmp;

9358.

if (ParseMoney(m_textCtrlAmount->GetValue(), nTmp))

9359.

m_textCtrlAmount->SetValue(FormatMoney(nTmp));

9360. }
9361. void CSendDialog::OnButtonAddressBook(wxCommandEvent& event)
9362. {
9363.

CAddressBookDialog dialog(this, m_textCtrlAddress->GetValue(), true);

9364.

if (dialog.ShowModal())

9365.

m_textCtrlAddress->SetValue(dialog.GetAddress());

9366. }
9367. void CSendDialog::OnButtonPaste(wxCommandEvent& event)
9368. {
9369.

if (wxTheClipboard->Open())

9370.

9371.

if (wxTheClipboard->IsSupported(wxDF_TEXT))

9372.

9373.

wxTextDataObject data;

9374.

wxTheClipboard->GetData(data);

9375.

m_textCtrlAddress->SetValue(data.GetText());

9376.

9377.
9378.

wxTheClipboard->Close();
}

9379. }
9380. void CSendDialog::OnButtonSend(wxCommandEvent& event)
9381. {
9382.

CWalletTx wtx;

9383.

string strAddress = (string)m_textCtrlAddress->GetValue();

9384.

int64 nValue = 0;

9385.

if (!ParseMoney(m_textCtrlAmount->GetValue(), nValue) || nValue <= 0)

9386.

9387.

wxMessageBox("Error in amount ");

9388.

return;

9389.

9390.

if (nValue > GetBalance())

9391.

9392.

wxMessageBox("Amount exceeds your balance ");

9393.

return;

9394.

9395.

if (nValue + nTransactionFee > GetBalance())

9396.

9397.

wxMessageBox(string("Total exceeds your balance when the ") + FormatMoney(nTransactionFee) + " transaction fee is included ");

9398.

return;

9399.

9400.

uint160 hash160;

9401.

bool fBitcoinAddress = AddressToHash160(strAddress, hash160);

9402.

if (fBitcoinAddress)

9403.

9404.

CScript scriptPubKey;

9405.

scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG;

9406.

if (!SendMoney(scriptPubKey, nValue, wtx))

9407.

return;

9408.

wxMessageBox("Payment sent ", "Sending...");

9409.

9410.

else

9411.

9412.

CAddress addr(strAddress.c_str());

9413.

if (addr.ip == 0)

9414.

9415.

wxMessageBox("Invalid address ");

9416.

return;

9417.

9418.

wtx.mapValue["to"] = strAddress;

9419.

wtx.mapValue["from"] = m_textCtrlFrom->GetValue();

9420.

wtx.mapValue["message"] = m_textCtrlMessage->GetValue();

9421.

CSendingDialog* pdialog = new CSendingDialog(this, addr, nValue, wtx);

9422.

if (!pdialog->ShowModal())

9423.

return;

9424.

9425.

if (!mapAddressBook.count(strAddress))

9426.

SetAddressBookName(strAddress, "");

9427.

EndModal(true);

9428. }
9429. void CSendDialog::OnButtonCancel(wxCommandEvent& event)
9430. {
9431.

EndModal(false);

9432. }
9433. CSendingDialog::CSendingDialog(wxWindow* parent, const CAddress& addrIn, int64 nPriceIn, const CWalletTx& wtxIn) :
CSendingDialogBase(NULL)
9434. {
9435.

addr = addrIn;

9436.

nPrice = nPriceIn;

9437.

wtx = wtxIn;

9438.

start = wxDateTime::UNow();

9439.

strStatus = "";

9440.

fCanCancel = true;

9441.

fAbort = false;

9442.

fSuccess = false;

9443.

fUIDone = false;

9444.

fWorkDone = false;

9445.

SetTitle(strprintf("Sending %s to %s...", FormatMoney(nPrice).c_str(), wtx.mapValue["to"].c_str()));

9446.

m_textCtrlStatus->SetValue("");

9447.

_beginthread(SendingDialogStartTransfer, 0, this);

9448. }
9449. CSendingDialog::~CSendingDialog()
9450. {
9451.

printf("~CSendingDialog()\n");

9452. }
9453. void CSendingDialog::Close()
9454. {
9455.

if (IsModal())

9456.
9457.

EndModal(fSuccess);
else

9458.

Show(false);

9459.

if (fWorkDone)

9460.
9461.

Destroy();
else

9462.

fUIDone = true;

9463. }
9464. void CSendingDialog::OnClose(wxCloseEvent& event)
9465. {
9466.

if (!event.CanVeto() || fWorkDone || fAbort || !fCanCancel)

9467.

9468.

Close();

9469.

9470.

else

9471.

9472.

event.Veto();

9473.

wxCommandEvent cmdevent;

9474.
9475.

OnButtonCancel(cmdevent);
}

9476. }
9477. void CSendingDialog::OnButtonOK(wxCommandEvent& event)
9478. {
9479.
9480.

if (fWorkDone)
Close();

9481. }
9482. void CSendingDialog::OnButtonCancel(wxCommandEvent& event)
9483. {
9484.

if (fCanCancel)

9485.

fAbort = true;

9486. }
9487. void CSendingDialog::OnPaint(wxPaintEvent& event)
9488. {
9489.
9490.
9491.
9492.
9493.

if (strStatus.size() > 130)


m_textCtrlStatus->SetValue(string("\n") + strStatus);
else
m_textCtrlStatus->SetValue(string("\n\n") + strStatus);
m_staticTextSending->SetFocus();

9494.

if (!fCanCancel)

9495.

m_buttonCancel->Enable(false);

9496.

if (fWorkDone)

9497.

9498.

m_buttonOK->Enable(true);

9499.

m_buttonOK->SetFocus();

9500.

m_buttonCancel->Enable(false);

9501.

9502.

if (fAbort && fCanCancel && IsShown())

9503.

9504.

strStatus = "CANCELLED";

9505.

m_buttonOK->Enable(true);

9506.

m_buttonOK->SetFocus();

9507.

m_buttonCancel->Enable(false);

9508.

m_buttonCancel->SetLabel("Cancelled");

9509.

Close();

9510.

wxMessageBox("Transfer cancelled ", "Sending...", wxOK, this);

9511.

9512.

event.Skip();

9513.

if (fRandSendTest && fWorkDone && fSuccess)

9514.

9515.

Close();

9516.

Sleep(1000);

9517.
9518.

RandSend();
}

9519. }
9520. void CSendingDialog::Repaint()
9521. {
9522.

Refresh();

9523.

wxPaintEvent event;

9524.

AddPendingEvent(event);

9525. }
9526. bool CSendingDialog::Status()
9527. {
9528.

if (fUIDone)

9529.

9530.

Destroy();

9531.

return false;

9532.

9533.

if (fAbort && fCanCancel)

9534.

9535.

strStatus = "CANCELLED";

9536.

Repaint();

9537.

fWorkDone = true;

9538.

return false;

9539.

9540.

return true;

9541. }
9542. bool CSendingDialog::Status(const string& str)
9543. {
9544.

if (!Status())

9545.

return false;

9546.

strStatus = str;

9547.

Repaint();

9548.

return true;

9549. }
9550. bool CSendingDialog::Error(const string& str)
9551. {
9552.

fCanCancel = false;

9553.

fWorkDone = true;

9554.

Status(string("Error: ") + str);

9555.

return false;

9556. }
9557. void SendingDialogStartTransfer(void* parg)
9558. {
9559.

((CSendingDialog*)parg)->StartTransfer();

9560. }
9561. void CSendingDialog::StartTransfer()
9562. {
9563.

if (nPrice + nTransactionFee > GetBalance())

9564.

9565.

Error("You don't have enough money");

9566.

return;

9567.

9568.

if (!Status("Connecting..."))

9569.

return;

9570.

CNode* pnode = ConnectNode(addr, 5 * 60);

9571.

if (!pnode)

9572.

9573.

Error("Unable to connect");

9574.

return;

9575.

9576.

if (!Status("Requesting public key..."))

9577.
9578.

return;
pnode->PushRequest("checkorder", wtx, SendingDialogOnReply2, this);

9579. }
9580. void SendingDialogOnReply2(void* parg, CDataStream& vRecv)
9581. {
9582.

((CSendingDialog*)parg)->OnReply2(vRecv);

9583. }
9584. void CSendingDialog::OnReply2(CDataStream& vRecv)
9585. {
9586.

if (!Status("Received public key..."))

9587.

return;

9588.

CScript scriptPubKey;

9589.

int nRet;

9590.

try

9591.

9592.

vRecv >> nRet;

9593.

if (nRet > 0)

9594.

9595.

string strMessage;

9596.

vRecv >> strMessage;

9597.

Error("Transfer was not accepted");

9598.

return;

9599.

9600.

vRecv >> scriptPubKey;

9601.

9602.

catch (...)

9603.

9604.

Error("Invalid response received");

9605.

return;

9606.

9607.

CNode* pnode = ConnectNode(addr, 5 * 60);

9608.

if (!pnode)

9609.

9610.

Error("Lost connection");

9611.

return;

9612.

9613.

while (wxDateTime::UNow() < start + wxTimeSpan(0, 0, 0, 2 * 1000))

9614.

9615.

Sleep(200);

9616.

if (!Status())

9617.

return;

9618.

9619.

CRITICAL_BLOCK(cs_main)

9620.

9621.

if (!Status("Creating transaction..."))

9622.

return;

9623.

if (nPrice + nTransactionFee > GetBalance())

9624.

9625.

Error("You don't have enough money");

9626.

return;

9627.

9628.

int64 nFeeRequired;

9629.

if (!CreateTransaction(scriptPubKey, nPrice, wtx, nFeeRequired))

9630.

9631.

if (nPrice + nFeeRequired > GetBalance())

9632.

Error(strprintf("This is an oversized transaction that requires a transaction fee of %s", FormatMoney(nFeeRequired).c_str()));

9633.

else

9634.

Error("Transaction creation failed");

9635.

return;

9636.

9637.

Sleep(50);

9638.

if (!Status())

9639.

return;

9640.

fCanCancel = false;

9641.

if (fAbort)

9642.

9643.

fCanCancel = true;

9644.

if (!Status())

9645.

return;

9646.

fCanCancel = false;

9647.

9648.

if (!Status("Sending payment..."))

9649.

return;

9650.

if (!CommitTransactionSpent(wtx))

9651.

9652.

Error("Error finalizing payment");

9653.

return;

9654.

9655.

pnode->PushRequest("submitorder", wtx, SendingDialogOnReply3, this);

9656.

if (!wtx.AcceptTransaction())

9657.

printf("ERROR: CSendingDialog : wtxNew.AcceptTransaction() %s failed\n", wtx.GetHash().ToString().c_str());

9658.

wtx.RelayWalletTransaction();

9659.

Status("Waiting for confirmation...");

9660.

MainFrameRepaint();

9661.

9662. }
9663. void SendingDialogOnReply3(void* parg, CDataStream& vRecv)
9664. {
9665.

((CSendingDialog*)parg)->OnReply3(vRecv);

9666. }
9667. void CSendingDialog::OnReply3(CDataStream& vRecv)
9668. {
9669.

int nRet;

9670.

try

9671.

9672.

vRecv >> nRet;

9673.

if (nRet > 0)

9674.

9675.

Error("The payment was sent, but the recipient was unable to verify it.\n"

9676.

"The transaction is recorded and will credit to the recipient if it is valid,\n"

9677.

"but without comment information.");

9678.

return;

9679.

9680.

9681.

catch (...)

9682.

9683.

Error("Payment was sent, but an invalid response was received");

9684.

return;

9685.

9686.

fSuccess = true;

9687.

fWorkDone = true;

9688.

Status("Payment completed");

9689. }
9690. CYourAddressDialog::CYourAddressDialog(wxWindow* parent, const string& strInitSelected) : CYourAddressDialogBase(parent)
9691. {
9692.

m_listCtrl->InsertColumn(0, "Name", wxLIST_FORMAT_LEFT, 200);

9693.

m_listCtrl->InsertColumn(1, "Bitcoin Address", wxLIST_FORMAT_LEFT, 350);

9694.

m_listCtrl->SetFocus();

9695.

CRITICAL_BLOCK(cs_mapKeys)

9696.

9697.

foreach(const PAIRTYPE(string, string)& item, mapAddressBook)

9698.

9699.

string strAddress = item.first;

9700.

string strName = item.second;

9701.

uint160 hash160;

9702.

bool fMine = (AddressToHash160(strAddress, hash160) && mapPubKeys.count(hash160));

9703.

if (fMine)

9704.

9705.

int nIndex = InsertLine(m_listCtrl, strName, strAddress);

9706.

if (strAddress == strInitSelected)

9707.

m_listCtrl->SetItemState(nIndex, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED,
wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED);

9708.

9709.
9710.

}
}

9711. }
9712. wxString CYourAddressDialog::GetAddress()
9713. {
9714.

int nIndex = GetSelection(m_listCtrl);

9715.

if (nIndex == -1)

9716.
9717.

return "";
return GetItemText(m_listCtrl, nIndex, 1);

9718. }
9719. void CYourAddressDialog::OnListEndLabelEdit(wxListEvent& event)
9720. {
9721.
9722.

if (event.IsEditCancelled())
return;

9723.

string strAddress = (string)GetItemText(m_listCtrl, event.GetIndex(), 1);

9724.

SetAddressBookName(strAddress, string(event.GetText()));

9725.

pframeMain->RefreshListCtrl();

9726. }
9727. void CYourAddressDialog::OnListItemSelected(wxListEvent& event)
9728. {
9729. }
9730. void CYourAddressDialog::OnListItemActivated(wxListEvent& event)
9731. {
9732.

EndModal(true);

9733. }
9734. void CYourAddressDialog::OnButtonRename(wxCommandEvent& event)
9735. {
9736.

int nIndex = GetSelection(m_listCtrl);

9737.

if (nIndex == -1)

9738.

return;

9739.

string strName = (string)m_listCtrl->GetItemText(nIndex);

9740.

string strAddress = (string)GetItemText(m_listCtrl, nIndex, 1);

9741.

CGetTextFromUserDialog dialog(this, "Rename Bitcoin Address", "New Name", strName);

9742.

if (!dialog.ShowModal())

9743.

return;

9744.

strName = dialog.GetValue();

9745.

SetAddressBookName(strAddress, strName);

9746.

m_listCtrl->SetItemText(nIndex, strName);

9747.

pframeMain->RefreshListCtrl();

9748. }
9749. void CYourAddressDialog::OnButtonNew(wxCommandEvent& event)
9750. {
9751.

CGetTextFromUserDialog dialog(this, "New Bitcoin Address", "Name", "");

9752.

if (!dialog.ShowModal())

9753.

return;

9754.

string strName = dialog.GetValue();

9755.

string strAddress = PubKeyToAddress(GenerateNewKey());

9756.

SetAddressBookName(strAddress, strName);

9757.

int nIndex = InsertLine(m_listCtrl, strName, strAddress);

9758.

SetSelection(m_listCtrl, nIndex);

9759.

m_listCtrl->SetFocus();

9760. }
9761. void CYourAddressDialog::OnButtonCopy(wxCommandEvent& event)
9762. {
9763.

if (wxTheClipboard->Open())

9764.

9765.

wxTheClipboard->SetData(new wxTextDataObject(GetAddress()));

9766.

wxTheClipboard->Close();

9767.

9768. }
9769. void CYourAddressDialog::OnButtonOK(wxCommandEvent& event)
9770. {
9771.

EndModal(true);

9772. }
9773. void CYourAddressDialog::OnButtonCancel(wxCommandEvent& event)
9774. {
9775.

EndModal(false);

9776. }
9777. void CYourAddressDialog::OnClose(wxCloseEvent& event)
9778. {
9779.

EndModal(false);

9780. }
9781. CAddressBookDialog::CAddressBookDialog(wxWindow* parent, const wxString& strInitSelected, bool fSendingIn) :
CAddressBookDialogBase(parent)
9782. {
9783.

fSending = fSendingIn;

9784.

if (!fSending)

9785.

m_buttonCancel->Show(false);

9786.

m_listCtrl->InsertColumn(0, "Name", wxLIST_FORMAT_LEFT, 200);

9787.

m_listCtrl->InsertColumn(1, "Address", wxLIST_FORMAT_LEFT, 350);

9788.

m_listCtrl->SetFocus();

9789.

wxBitmap bmpAddressBook(wxT("addressbook16"), wxBITMAP_TYPE_RESOURCE);

9790.

bmpAddressBook.SetMask(new wxMask(wxBitmap(wxT("addressbook16mask"), wxBITMAP_TYPE_RESOURCE)));

9791.

wxIcon iconAddressBook;

9792.

iconAddressBook.CopyFromBitmap(bmpAddressBook);

9793.

SetIcon(iconAddressBook);

9794.

CRITICAL_BLOCK(cs_mapKeys)

9795.

9796.

foreach(const PAIRTYPE(string, string)& item, mapAddressBook)

9797.

9798.

string strAddress = item.first;

9799.

string strName = item.second;

9800.

uint160 hash160;

9801.

bool fMine = (AddressToHash160(strAddress, hash160) && mapPubKeys.count(hash160));

9802.

if (!fMine)

9803.

9804.

int nIndex = InsertLine(m_listCtrl, strName, strAddress);

9805.

if (strAddress == strInitSelected)

9806.

m_listCtrl->SetItemState(nIndex, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED,
wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED);

9807.

9808.
9809.

}
}

9810. }
9811. wxString CAddressBookDialog::GetAddress()
9812. {
9813.

int nIndex = GetSelection(m_listCtrl);

9814.

if (nIndex == -1)

9815.
9816.

return "";
return GetItemText(m_listCtrl, nIndex, 1);

9817. }
9818. void CAddressBookDialog::OnListEndLabelEdit(wxListEvent& event)
9819. {
9820.
9821.
9822.

if (event.IsEditCancelled())
return;
string strAddress = (string)GetItemText(m_listCtrl, event.GetIndex(), 1);

9823.

SetAddressBookName(strAddress, string(event.GetText()));

9824.

pframeMain->RefreshListCtrl();

9825. }
9826. void CAddressBookDialog::OnListItemSelected(wxListEvent& event)
9827. {
9828. }
9829. void CAddressBookDialog::OnListItemActivated(wxListEvent& event)
9830. {
9831.

if (fSending)

9832.

9833.

EndModal(GetAddress() != "" ? 2 : 0);

9834.

9835.

else

9836.

9837.

wxCommandEvent event;

9838.
9839.

OnButtonEdit(event);
}

9840. }
9841. void CAddressBookDialog::OnButtonEdit(wxCommandEvent& event)
9842. {
9843.

int nIndex = GetSelection(m_listCtrl);

9844.

if (nIndex == -1)

9845.

return;

9846.

string strName = (string)m_listCtrl->GetItemText(nIndex);

9847.

string strAddress = (string)GetItemText(m_listCtrl, nIndex, 1);

9848.

string strAddressOrg = strAddress;

9849.

CGetTextFromUserDialog dialog(this, "Edit Address", "Name", strName, "Address", strAddress);

9850.

if (!dialog.ShowModal())

9851.

return;

9852.

strName = dialog.GetValue1();

9853.

strAddress = dialog.GetValue2();

9854.

if (strAddress != strAddressOrg)

9855.

CWalletDB().EraseName(strAddressOrg);

9856.

SetAddressBookName(strAddress, strName);

9857.

m_listCtrl->SetItem(nIndex, 1, strAddress);

9858.

m_listCtrl->SetItemText(nIndex, strName);

9859.

pframeMain->RefreshListCtrl();

9860. }
9861. void CAddressBookDialog::OnButtonNew(wxCommandEvent& event)
9862. {
9863.

CGetTextFromUserDialog dialog(this, "New Address", "Name", "", "Address", "");

9864.

if (!dialog.ShowModal())

9865.

return;

9866.

string strName = dialog.GetValue1();

9867.

string strAddress = dialog.GetValue2();

9868.

SetAddressBookName(strAddress, strName);

9869.

int nIndex = InsertLine(m_listCtrl, strName, strAddress);

9870.

SetSelection(m_listCtrl, nIndex);

9871.

m_listCtrl->SetFocus();

9872. }
9873. void CAddressBookDialog::OnButtonDelete(wxCommandEvent& event)
9874. {
9875.

for (int nIndex = m_listCtrl->GetItemCount()-1; nIndex >= 0; nIndex--)

9876.

9877.

if (m_listCtrl->GetItemState(nIndex, wxLIST_STATE_SELECTED))

9878.

9879.

string strAddress = (string)GetItemText(m_listCtrl, nIndex, 1);

9880.

CWalletDB().EraseName(strAddress);

9881.

m_listCtrl->DeleteItem(nIndex);

9882.

9883.

9884.

pframeMain->RefreshListCtrl();

9885. }
9886. void CAddressBookDialog::OnButtonCopy(wxCommandEvent& event)
9887. {
9888.

if (wxTheClipboard->Open())

9889.

9890.

wxTheClipboard->SetData(new wxTextDataObject(GetAddress()));

9891.
9892.

wxTheClipboard->Close();
}

9893. }
9894. void CAddressBookDialog::OnButtonOK(wxCommandEvent& event)
9895. {
9896.

EndModal(GetAddress() != "" ? 1 : 0);

9897. }
9898. void CAddressBookDialog::OnButtonCancel(wxCommandEvent& event)
9899. {
9900.

EndModal(0);

9901. }
9902. void CAddressBookDialog::OnClose(wxCloseEvent& event)
9903. {
9904.
9905. }

EndModal(0);

9906. bool CompareIntStringPairBestFirst(const pair<int, string>& item1, const pair<int, string>& item2)
9907. {
9908.

return (item1.first > item2.first);

9909. }
9910. CProductsDialog::CProductsDialog(wxWindow* parent) : CProductsDialogBase(parent)
9911. {
9912.

m_listCtrl->InsertColumn(0, "Title", wxLIST_FORMAT_LEFT, 200);

9913.

m_listCtrl->InsertColumn(1, "Price", wxLIST_FORMAT_LEFT, 80);

9914.

m_listCtrl->InsertColumn(2, "Seller", wxLIST_FORMAT_LEFT, 80);

9915.

m_listCtrl->InsertColumn(3, "Stars", wxLIST_FORMAT_LEFT, 50);

9916.

m_listCtrl->InsertColumn(4, "Power", wxLIST_FORMAT_LEFT, 50);

9917.
9918.

map<string, int> mapTopCategories;

9919.

CRITICAL_BLOCK(cs_mapProducts)

9920.

for (map<uint256, CProduct>::iterator mi = mapProducts.begin(); mi != mapProducts.end(); ++mi)

9921.

mapTopCategories[(*mi).second.mapValue["category"]]++;

9922.
9923.

vector<pair<int, string> > vTopCategories;

9924.

for (map<string, int>::iterator mi = mapTopCategories.begin(); mi != mapTopCategories.end(); ++mi)

9925.

vTopCategories.push_back(make_pair((*mi).second, (*mi).first));

9926.

sort(vTopCategories.begin(), vTopCategories.end(), CompareIntStringPairBestFirst);

9927.

int nLimit = 250;

9928.

for (vector<pair<int, string> >::iterator it = vTopCategories.begin(); it != vTopCategories.end() && nLimit-- > 0; ++it)

9929.

m_comboBoxCategory->Append((*it).second);

9930. }
9931. void CProductsDialog::OnCombobox(wxCommandEvent& event)
9932. {
9933.

OnButtonSearch(event);

9934. }
9935. bool CompareProductsBestFirst(const CProduct* p1, const CProduct* p2)
9936. {
9937.

return (p1->nAtoms > p2->nAtoms);

9938. }
9939. void CProductsDialog::OnButtonSearch(wxCommandEvent& event)
9940. {
9941.

string strCategory = (string)m_comboBoxCategory->GetValue();

9942.

string strSearch = (string)m_textCtrlSearch->GetValue();

9943.

vector<CProduct*> vProductsFound;

9944.

CRITICAL_BLOCK(cs_mapProducts)

9945.

9946.

for (map<uint256, CProduct>::iterator mi = mapProducts.begin(); mi != mapProducts.end(); ++mi)

9947.

9948.

CProduct& product = (*mi).second;

9949.

if (product.mapValue["category"].find(strCategory) != -1)

9950.

9951.

if (product.mapValue["title"].find(strSearch) != -1 ||

9952.

product.mapValue["description"].find(strSearch) != -1 ||

9953.

product.mapValue["seller"].find(strSearch) != -1)

9954.

9955.

vProductsFound.push_back(&product);

9956.

9957.

9958.

9959.

9960.

sort(vProductsFound.begin(), vProductsFound.end(), CompareProductsBestFirst);

9961.

foreach(CProduct* pproduct, vProductsFound)

9962.

9963.

InsertLine(m_listCtrl,

9964.

pproduct->mapValue["title"],

9965.

pproduct->mapValue["price"],

9966.

pproduct->mapValue["seller"],

9967.

pproduct->mapValue["stars"],

9968.
9969.

itostr(pproduct->nAtoms));
}

9970. }
9971. void CProductsDialog::OnListItemActivated(wxListEvent& event)
9972. {
9973.

CViewProductDialog* pdialog = new CViewProductDialog(this, m_vProduct[event.GetIndex()]);

9974.

pdialog->Show();

9975. }
9976. CEditProductDialog::CEditProductDialog(wxWindow* parent) : CEditProductDialogBase(parent)
9977. {
9978.

m_textCtrlLabel[0 ] = m_textCtrlLabel0;

9979.

m_textCtrlLabel[1 ] = m_textCtrlLabel1;

9980.

m_textCtrlLabel[2 ] = m_textCtrlLabel2;

9981.

m_textCtrlLabel[3 ] = m_textCtrlLabel3;

9982.

m_textCtrlLabel[4 ] = m_textCtrlLabel4;

9983.

m_textCtrlLabel[5 ] = m_textCtrlLabel5;

9984.

m_textCtrlLabel[6 ] = m_textCtrlLabel6;

9985.

m_textCtrlLabel[7 ] = m_textCtrlLabel7;

9986.

m_textCtrlLabel[8 ] = m_textCtrlLabel8;

9987.

m_textCtrlLabel[9 ] = m_textCtrlLabel9;

9988.

m_textCtrlLabel[10] = m_textCtrlLabel10;

9989.

m_textCtrlLabel[11] = m_textCtrlLabel11;

9990.

m_textCtrlLabel[12] = m_textCtrlLabel12;

9991.

m_textCtrlLabel[13] = m_textCtrlLabel13;

9992.

m_textCtrlLabel[14] = m_textCtrlLabel14;

9993.

m_textCtrlLabel[15] = m_textCtrlLabel15;

9994.

m_textCtrlLabel[16] = m_textCtrlLabel16;

9995.

m_textCtrlLabel[17] = m_textCtrlLabel17;

9996.

m_textCtrlLabel[18] = m_textCtrlLabel18;

9997.

m_textCtrlLabel[19] = m_textCtrlLabel19;

9998.

m_textCtrlField[0 ] = m_textCtrlField0;

9999.

m_textCtrlField[1 ] = m_textCtrlField1;

10000.

m_textCtrlField[2 ] = m_textCtrlField2;

10001.

m_textCtrlField[3 ] = m_textCtrlField3;

10002.

m_textCtrlField[4 ] = m_textCtrlField4;

10003.

m_textCtrlField[5 ] = m_textCtrlField5;

10004.

m_textCtrlField[6 ] = m_textCtrlField6;

10005.

m_textCtrlField[7 ] = m_textCtrlField7;

10006.

m_textCtrlField[8 ] = m_textCtrlField8;

10007.

m_textCtrlField[9 ] = m_textCtrlField9;

10008.

m_textCtrlField[10] = m_textCtrlField10;

10009.

m_textCtrlField[11] = m_textCtrlField11;

10010.

m_textCtrlField[12] = m_textCtrlField12;

10011.

m_textCtrlField[13] = m_textCtrlField13;

10012.

m_textCtrlField[14] = m_textCtrlField14;

10013.

m_textCtrlField[15] = m_textCtrlField15;

10014.

m_textCtrlField[16] = m_textCtrlField16;

10015.

m_textCtrlField[17] = m_textCtrlField17;

10016.

m_textCtrlField[18] = m_textCtrlField18;

10017.

m_textCtrlField[19] = m_textCtrlField19;

10018.

m_buttonDel[0 ] = m_buttonDel0;

10019.

m_buttonDel[1 ] = m_buttonDel1;

10020.

m_buttonDel[2 ] = m_buttonDel2;

10021.

m_buttonDel[3 ] = m_buttonDel3;

10022.

m_buttonDel[4 ] = m_buttonDel4;

10023.

m_buttonDel[5 ] = m_buttonDel5;

10024.

m_buttonDel[6 ] = m_buttonDel6;

10025.

m_buttonDel[7 ] = m_buttonDel7;

10026.

m_buttonDel[8 ] = m_buttonDel8;

10027.

m_buttonDel[9 ] = m_buttonDel9;

10028.

m_buttonDel[10] = m_buttonDel10;

10029.

m_buttonDel[11] = m_buttonDel11;

10030.

m_buttonDel[12] = m_buttonDel12;

10031.

m_buttonDel[13] = m_buttonDel13;

10032.

m_buttonDel[14] = m_buttonDel14;

10033.

m_buttonDel[15] = m_buttonDel15;

10034.

m_buttonDel[16] = m_buttonDel16;

10035.

m_buttonDel[17] = m_buttonDel17;

10036.

m_buttonDel[18] = m_buttonDel18;

10037.

m_buttonDel[19] = m_buttonDel19;

10038.

for (int i = 1; i < FIELDS_MAX; i++)

10039.
10040.

ShowLine(i, false);
LayoutAll();

10041. }
10042. void CEditProductDialog::LayoutAll()
10043. {
10044.

m_scrolledWindow->Layout();

10045.

m_scrolledWindow->GetSizer()->Fit(m_scrolledWindow);

10046.

this->Layout();

10047. }
10048. void CEditProductDialog::ShowLine(int i, bool fShow)
10049. {
10050.

m_textCtrlLabel[i]->Show(fShow);

10051.

m_textCtrlField[i]->Show(fShow);

10052.

m_buttonDel[i]->Show(fShow);

10053. }
10054. void CEditProductDialog::OnButtonDel0(wxCommandEvent& event) { OnButtonDel(event, 0); }
10055. void CEditProductDialog::OnButtonDel1(wxCommandEvent& event) { OnButtonDel(event, 1); }
10056. void CEditProductDialog::OnButtonDel2(wxCommandEvent& event) { OnButtonDel(event, 2); }
10057. void CEditProductDialog::OnButtonDel3(wxCommandEvent& event) { OnButtonDel(event, 3); }
10058. void CEditProductDialog::OnButtonDel4(wxCommandEvent& event) { OnButtonDel(event, 4); }
10059. void CEditProductDialog::OnButtonDel5(wxCommandEvent& event) { OnButtonDel(event, 5); }
10060. void CEditProductDialog::OnButtonDel6(wxCommandEvent& event) { OnButtonDel(event, 6); }
10061. void CEditProductDialog::OnButtonDel7(wxCommandEvent& event) { OnButtonDel(event, 7); }
10062. void CEditProductDialog::OnButtonDel8(wxCommandEvent& event) { OnButtonDel(event, 8); }
10063. void CEditProductDialog::OnButtonDel9(wxCommandEvent& event) { OnButtonDel(event, 9); }
10064. void CEditProductDialog::OnButtonDel10(wxCommandEvent& event) { OnButtonDel(event, 10); }
10065. void CEditProductDialog::OnButtonDel11(wxCommandEvent& event) { OnButtonDel(event, 11); }
10066. void CEditProductDialog::OnButtonDel12(wxCommandEvent& event) { OnButtonDel(event, 12); }
10067. void CEditProductDialog::OnButtonDel13(wxCommandEvent& event) { OnButtonDel(event, 13); }
10068. void CEditProductDialog::OnButtonDel14(wxCommandEvent& event) { OnButtonDel(event, 14); }
10069. void CEditProductDialog::OnButtonDel15(wxCommandEvent& event) { OnButtonDel(event, 15); }
10070. void CEditProductDialog::OnButtonDel16(wxCommandEvent& event) { OnButtonDel(event, 16); }
10071. void CEditProductDialog::OnButtonDel17(wxCommandEvent& event) { OnButtonDel(event, 17); }

10072. void CEditProductDialog::OnButtonDel18(wxCommandEvent& event) { OnButtonDel(event, 18); }


10073. void CEditProductDialog::OnButtonDel19(wxCommandEvent& event) { OnButtonDel(event, 19); }
10074. void CEditProductDialog::OnButtonDel(wxCommandEvent& event, int n)
10075. {
10076.

Freeze();

10077.

int x, y;

10078.

m_scrolledWindow->GetViewStart(&x, &y);

10079.

int i;

10080.

for (i = n; i < FIELDS_MAX-1; i++)

10081.

10082.

m_textCtrlLabel[i]->SetValue(m_textCtrlLabel[i+1]->GetValue());

10083.

m_textCtrlField[i]->SetValue(m_textCtrlField[i+1]->GetValue());

10084.

if (!m_buttonDel[i+1]->IsShown())

10085.

break;

10086.

10087.

m_textCtrlLabel[i]->SetValue("");

10088.

m_textCtrlField[i]->SetValue("");

10089.

ShowLine(i, false);

10090.

m_buttonAddField->Enable(true);

10091.

LayoutAll();

10092.

m_scrolledWindow->Scroll(0, y);

10093.

Thaw();

10094. }
10095. void CEditProductDialog::OnButtonAddField(wxCommandEvent& event)
10096. {
10097.

for (int i = 0; i < FIELDS_MAX; i++)

10098.

10099.

if (!m_buttonDel[i]->IsShown())

10100.

10101.

Freeze();

10102.

ShowLine(i, true);

10103.

if (i == FIELDS_MAX-1)

10104.

m_buttonAddField->Enable(false);

10105.

LayoutAll();

10106.

m_scrolledWindow->Scroll(0, 99999);

10107.

Thaw();

10108.

break;

10109.
10110.

}
}

10111. }
10112. void CEditProductDialog::OnButtonSend(wxCommandEvent& event)
10113. {
10114.

CProduct product;

10115.

GetProduct(product);

10116.

product.vchPubKeyFrom = keyUser.GetPubKey();

10117.

if (!keyUser.Sign(product.GetSigHash(), product.vchSig))

10118.

10119.

wxMessageBox("Error digitally signing the product ");

10120.

return;

10121.

10122.

AddToMyProducts(product);

10123.

product.mapDetails.clear();

10124.

product.vOrderForm.clear();

10125.

if (!keyUser.Sign(product.GetSigHash(), product.vchSig))

10126.

10127.

wxMessageBox("Error digitally signing the product ");

10128.

return;

10129.

10130.

if (!product.CheckProduct())

10131.

10132.

wxMessageBox("Errors found in product ");

10133.

return;

10134.

10135.

AdvertStartPublish(pnodeLocalHost, MSG_PRODUCT, 0, product);

10136.

Destroy();

10137. }
10138. void CEditProductDialog::OnButtonPreview(wxCommandEvent& event)
10139. {
10140.

CProduct product;

10141.

GetProduct(product);

10142.

CViewProductDialog* pdialog = new CViewProductDialog(this, product);

10143.

pdialog->Show();

10144. }
10145. void CEditProductDialog::OnButtonCancel(wxCommandEvent& event)
10146. {
10147.

Destroy();

10148. }
10149. void CEditProductDialog::SetProduct(const CProduct& productIn)
10150. {
10151.

CProduct product = productIn;

10152.

m_comboBoxCategory->SetValue(product.mapValue["category"]);

10153.

m_textCtrlTitle->SetValue(product.mapValue["title"]);

10154.

m_textCtrlPrice->SetValue(product.mapValue["price"]);

10155.

m_textCtrlDescription->SetValue(product.mapValue["description"]);

10156.

m_textCtrlInstructions->SetValue(product.mapValue["instructions"]);

10157.

for (int i = 0; i < FIELDS_MAX; i++)

10158.

10159.

bool fUsed = i < product.vOrderForm.size();

10160.

m_buttonDel[i]->Show(fUsed);

10161.

m_textCtrlLabel[i]->Show(fUsed);

10162.

m_textCtrlField[i]->Show(fUsed);

10163.

if (!fUsed)

10164.

continue;

10165.

m_textCtrlLabel[i]->SetValue(product.vOrderForm[i].first);

10166.

string strControl = product.vOrderForm[i].second;

10167.

if (strControl.substr(0, 5) == "text=")

10168.

m_textCtrlField[i]->SetValue("");

10169.

else if (strControl.substr(0, 7) == "choice=")

10170.

m_textCtrlField[i]->SetValue(strControl.substr(7));

10171.

else

10172.
10173.

m_textCtrlField[i]->SetValue(strControl);
}

10174. }
10175. void CEditProductDialog::GetProduct(CProduct& product)
10176. {
10177.

product.mapValue["category"]

10178.

product.mapValue["title"]

= m_comboBoxCategory->GetValue().Trim();

10179.

product.mapValue["price"]

10180.

product.mapValue["description"] = m_textCtrlDescription->GetValue().Trim();

10181.

product.mapValue["instructions"] = m_textCtrlInstructions->GetValue().Trim();

10182.

for (int i = 0; i < FIELDS_MAX; i++)

10183.

= m_textCtrlTitle->GetValue().Trim();
= m_textCtrlPrice->GetValue().Trim();

10184.

if (m_buttonDel[i]->IsShown())

10185.

10186.

string strLabel = (string)m_textCtrlLabel[i]->GetValue().Trim();

10187.

string strControl = (string)m_textCtrlField[i]->GetValue();

10188.

if (strControl.empty())

10189.

strControl = "text=";

10190.

else

10191.

strControl = "choice=" + strControl;

10192.

product.vOrderForm.push_back(make_pair(strLabel, strControl));

10193.
10194.

}
}

10195. }
10196. CViewProductDialog::CViewProductDialog(wxWindow* parent, const CProduct& productIn) : CViewProductDialogBase(parent)
10197. {
10198.

Connect(wxEVT_REPLY1, wxCommandEventHandler(CViewProductDialog::OnReply1), NULL, this);

10199.

AddCallbackAvailable(GetEventHandler());

10200.

product = productIn;

10201.

UpdateProductDisplay(false);

10202.

m_buttonBack->Enable(false);

10203.

m_buttonNext->Enable(!product.vOrderForm.empty());

10204.

m_htmlWinReviews->Show(true);

10205.

m_scrolledWindow->Show(false);

10206.

this->Layout();

10207.

_beginthread(ThreadRequestProductDetails, 0, new pair<CProduct, wxEvtHandler*>(product, GetEventHandler()));

10208. }
10209. CViewProductDialog::~CViewProductDialog()
10210. {
10211.

RemoveCallbackAvailable(GetEventHandler());

10212. }
10213. void ThreadRequestProductDetails(void* parg)
10214. {
10215.

pair<CProduct, wxEvtHandler*>* pitem = (pair<CProduct, wxEvtHandler*>*)parg;

10216.

CProduct product = pitem->first;

10217.

wxEvtHandler* pevthandler = pitem->second;

10218.

delete pitem;

10219.

CNode* pnode = ConnectNode(product.addr, 5 * 60);

10220.

if (!pnode)

10221.

10222.

CDataStream ssEmpty;

10223.

AddPendingReplyEvent1(pevthandler, ssEmpty);

10224.

return;

10225.

10226.

pnode->PushRequest("getdetails", product.GetHash(), AddPendingReplyEvent1, (void*)pevthandler);

10227. }
10228. void CViewProductDialog::OnReply1(wxCommandEvent& event)
10229. {
10230.

CDataStream ss = GetStreamFromEvent(event);

10231.

if (ss.empty())

10232.

10233.

product.mapValue["description"] = "-- CAN'T CONNECT TO SELLER --\n";

10234.

UpdateProductDisplay(true);

10235.

return;

10236.

10237.

int nRet;

10238.

CProduct product2;

10239.

try

10240.

10241.

ss >> nRet;

10242.

if (nRet > 0)

10243.

throw false;

10244.

ss >> product2;

10245.

if (product2.GetHash() != product.GetHash())

10246.

throw false;

10247.

if (!product2.CheckSignature())

10248.

throw false;

10249.

10250.

catch (...)

10251.

10252.

product.mapValue["description"] = "-- INVALID RESPONSE --\n";

10253.

UpdateProductDisplay(true);

10254.

return;

10255.

10256.

product = product2;

10257.

UpdateProductDisplay(true);

10258. }
10259. bool CompareReviewsBestFirst(const CReview* p1, const CReview* p2)
10260. {
10261.

return (p1->nAtoms > p2->nAtoms);

10262. }
10263. void CViewProductDialog::UpdateProductDisplay(bool fDetails)
10264. {
10265.

string strHTML;

10266.

strHTML.reserve(4000);

10267.

strHTML += "<html>\n"

10268.

"<head>\n"

10269.

"<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n"

10270.

"</head>\n"

10271.

"<body>\n";

10272.

strHTML += "<b>Category:</b> " + HtmlEscape(product.mapValue["category"]) + "<br>\n";

10273.

strHTML += "<b>Title:</b> " + HtmlEscape(product.mapValue["title"])

10274.

strHTML += "<b>Price:</b> " + HtmlEscape(product.mapValue["price"])

10275.

if (!fDetails)

10276.
10277.

+ "<br>\n";
+ "<br>\n";

strHTML += "<b>Loading details...</b><br>\n<br>\n";


else

10278.

strHTML += HtmlEscape(product.mapValue["description"], true) + "<br>\n<br>\n";

10279.

strHTML += "<b>Reviews:</b><br>\n<br>\n";

10280.

if (!product.vchPubKeyFrom.empty())

10281.

10282.

CReviewDB reviewdb("r");

10283.

vector<CReview> vReviews;

10284.

reviewdb.ReadReviews(product.GetUserHash(), vReviews);

10285.

vector<CReview*> vSortedReviews;

10286.

vSortedReviews.reserve(vReviews.size());

10287.

for (vector<CReview>::reverse_iterator it = vReviews.rbegin(); it != vReviews.rend(); ++it)

10288.

10289.

CReview& review = *it;

10290.

CUser user;

10291.

reviewdb.ReadUser(review.GetUserHash(), user);

10292.

review.nAtoms = user.GetAtomCount();

10293.

vSortedReviews.push_back(&review);

10294.

10295.

reviewdb.Close();

10296.

stable_sort(vSortedReviews.begin(), vSortedReviews.end(), CompareReviewsBestFirst);

10297.

foreach(CReview* preview, vSortedReviews)

10298.

10299.

CReview& review = *preview;

10300.

int nStars = atoi(review.mapValue["stars"].c_str());

10301.

if (nStars < 1 || nStars > 5)

10302.

continue;

10303.

strHTML += "<b>" + itostr(nStars) + (nStars == 1 ? " star" : " stars") + "</b>";

10304.

strHTML += " &nbsp;&nbsp;&nbsp; ";

10305.

strHTML += DateStr(atoi64(review.mapValue["date"])) + "<br>\n";

10306.

strHTML += HtmlEscape(review.mapValue["review"], true);

10307.

strHTML += "<br>\n<br>\n";

10308.

10309.

10310.

strHTML += "</body>\n</html>\n";

10311.

string(strHTML.begin(), strHTML.end()).swap(strHTML);

10312.

m_htmlWinReviews->SetPage(strHTML);

10313.

if (product.vOrderForm.empty())

10314.

return;

10315.

m_staticTextInstructions->SetLabel(product.mapValue["instructions"]);

10316.

for (int i = 0; i < FIELDS_MAX; i++)

10317.

10318.

m_staticTextLabel[i] = NULL;

10319.

m_textCtrlField[i] = NULL;

10320.

m_choiceField[i] = NULL;

10321.

10322.

wxBoxSizer* bSizer21 = (wxBoxSizer*)m_scrolledWindow->GetSizer();

10323.

wxFlexGridSizer* fgSizer;

10324.

fgSizer = new wxFlexGridSizer(0, 2, 0, 0);

10325.

fgSizer->AddGrowableCol(1);

10326.

fgSizer->SetFlexibleDirection(wxBOTH);

10327.

fgSizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);

10328.

wxWindow* windowLast = NULL;

10329.

for (int i = 0; i < product.vOrderForm.size(); i++)

10330.

10331.

string strLabel = product.vOrderForm[i].first;

10332.

string strControl = product.vOrderForm[i].second;

10333.

if (strLabel.size() < 20)

10334.

strLabel.insert(strLabel.begin(), 20 - strLabel.size(), ' ');

10335.

m_staticTextLabel[i] = new wxStaticText(m_scrolledWindow, wxID_ANY, strLabel, wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);

10336.

m_staticTextLabel[i]->Wrap(-1);

10337.

fgSizer->Add(m_staticTextLabel[i], 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5);

10338.

if (strControl.substr(0, 5) == "text=")

10339.

10340.

m_textCtrlField[i] = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);

10341.

fgSizer->Add(m_textCtrlField[i], 1, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5);

10342.

windowLast = m_textCtrlField[i];

10343.

10344.

else if (strControl.substr(0, 7) == "choice=")

10345.

10346.

vector<string> vChoices;

10347.

ParseString(strControl.substr(7), ',', vChoices);

10348.

wxArrayString arraystring;

10349.

foreach(const string& str, vChoices)

10350.

arraystring.Add(str);

10351.

m_choiceField[i] = new wxChoice(m_scrolledWindow, wxID_ANY, wxDefaultPosition, wxDefaultSize, arraystring, 0);

10352.

fgSizer->Add(m_choiceField[i], 0, wxALL|wxALIGN_CENTER_VERTICAL, 5);

10353.

windowLast = m_choiceField[i];

10354.

10355.

else

10356.

10357.

m_textCtrlField[i] = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);

10358.

fgSizer->Add(m_textCtrlField[i], 1, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5);

10359.

m_staticTextLabel[i]->Show(false);

10360.

m_textCtrlField[i]->Show(false);

10361.

10362.

10363.

bSizer21->Insert(2, fgSizer, 0, wxEXPAND|wxRIGHT|wxLEFT, 5);

10364.

m_scrolledWindow->Layout();

10365.

bSizer21->Fit(m_scrolledWindow);

10366.

this->Layout();

10367.

m_buttonSubmitForm->MoveAfterInTabOrder(windowLast);

10368.

m_buttonCancelForm->MoveAfterInTabOrder(m_buttonSubmitForm);

10369.

this->Layout();

10370. }
10371. void CViewProductDialog::GetOrder(CWalletTx& wtx)
10372. {
10373.

wtx.SetNull();

10374.

for (int i = 0; i < product.vOrderForm.size(); i++)

10375.

10376.

string strValue;

10377.

if (m_textCtrlField[i])

10378.

strValue = m_textCtrlField[i]->GetValue().Trim();

10379.

else

10380.

strValue = m_choiceField[i]->GetStringSelection();

10381.
10382.

wtx.vOrderForm.push_back(make_pair(m_staticTextLabel[i]->GetLabel(), strValue));
}

10383. }
10384. void CViewProductDialog::OnButtonSubmitForm(wxCommandEvent& event)
10385. {
10386.

m_buttonSubmitForm->Enable(false);

10387.

m_buttonCancelForm->Enable(false);

10388.

CWalletTx wtx;

10389.

GetOrder(wtx);

10390.

CSendingDialog* pdialog = new CSendingDialog(this, product.addr, atoi64(product.mapValue["price"]), wtx);

10391.

if (!pdialog->ShowModal())

10392.

10393.

m_buttonSubmitForm->Enable(true);

10394.

m_buttonCancelForm->Enable(true);

10395.
10396.

return;
}

10397. }
10398. void CViewProductDialog::OnButtonCancelForm(wxCommandEvent& event)
10399. {
10400.

Destroy();

10401. }
10402. void CViewProductDialog::OnButtonBack(wxCommandEvent& event)
10403. {

10404.

Freeze();

10405.

m_htmlWinReviews->Show(true);

10406.

m_scrolledWindow->Show(false);

10407.

m_buttonBack->Enable(false);

10408.

m_buttonNext->Enable(!product.vOrderForm.empty());

10409.

this->Layout();

10410.

Thaw();

10411. }
10412. void CViewProductDialog::OnButtonNext(wxCommandEvent& event)
10413. {
10414.

if (!product.vOrderForm.empty())

10415.

10416.

Freeze();

10417.

m_htmlWinReviews->Show(false);

10418.

m_scrolledWindow->Show(true);

10419.

m_buttonBack->Enable(true);

10420.

m_buttonNext->Enable(false);

10421.

this->Layout();

10422.
10423.

Thaw();
}

10424. }
10425. void CViewProductDialog::OnButtonCancel(wxCommandEvent& event)
10426. {
10427.

Destroy();

10428. }
10429. CViewOrderDialog::CViewOrderDialog(wxWindow* parent, CWalletTx order, bool fReceived) : CViewOrderDialogBase(parent)
10430. {
10431.

int64 nPrice = (fReceived ? order.GetCredit() : order.GetDebit());

10432.

string strHTML;

10433.

strHTML.reserve(4000);

10434.

strHTML += "<html>\n"

10435.

"<head>\n"

10436.

"<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n"

10437.

"</head>\n"

10438.

"<body>\n";

10439.

strHTML += "<b>Time:</b> " + HtmlEscape(DateTimeStr(order.nTimeReceived)) + "<br>\n";

10440.

strHTML += "<b>Price:</b> " + HtmlEscape(FormatMoney(nPrice)) + "<br>\n";

10441.

strHTML += "<b>Status:</b> " + HtmlEscape(FormatTxStatus(order)) + "<br>\n";

10442.

strHTML += "<table>\n";

10443.

for (int i = 0; i < order.vOrderForm.size(); i++)

10444.

10445.

strHTML += " <tr><td><b>" + HtmlEscape(order.vOrderForm[i].first) + ":</b></td>";

10446.

strHTML += "<td>" + HtmlEscape(order.vOrderForm[i].second) + "</td></tr>\n";

10447.

10448.

strHTML += "</table>\n";

10449.

strHTML += "</body>\n</html>\n";

10450.

string(strHTML.begin(), strHTML.end()).swap(strHTML);

10451.

m_htmlWin->SetPage(strHTML);

10452. }
10453. void CViewOrderDialog::OnButtonOK(wxCommandEvent& event)
10454. {
10455.

Destroy();

10456. }
10457. CEditReviewDialog::CEditReviewDialog(wxWindow* parent) : CEditReviewDialogBase(parent)
10458. {
10459. }
10460. void CEditReviewDialog::OnButtonSubmit(wxCommandEvent& event)
10461. {
10462.

if (m_choiceStars->GetSelection() == -1)

10463.

10464.

wxMessageBox("Please select a rating ");

10465.

return;

10466.

10467.

CReview review;

10468.

GetReview(review);

10469.

review.vchPubKeyFrom = keyUser.GetPubKey();

10470.

if (!keyUser.Sign(review.GetSigHash(), review.vchSig))

10471.

10472.

wxMessageBox("Unable to digitally sign the review ");

10473.

return;

10474.

10475.

if (!review.AcceptReview())

10476.

10477.

wxMessageBox("Save failed ");

10478.

return;

10479.

10480.

RelayMessage(CInv(MSG_REVIEW, review.GetHash()), review);

10481.

Destroy();

10482. }
10483. void CEditReviewDialog::OnButtonCancel(wxCommandEvent& event)
10484. {
10485.
10486. }

Destroy();

10487. void CEditReviewDialog::GetReview(CReview& review)


10488. {
10489.

review.mapValue["time"] = i64tostr(GetAdjustedTime());

10490.

review.mapValue["stars"] = itostr(m_choiceStars->GetSelection()+1);

10491.

review.mapValue["review"] = m_textCtrlReview->GetValue();

10492. }
10493. class CMyApp: public wxApp
10494. {
10495. public:
10496.

CMyApp(){};

10497.

~CMyApp(){};

10498.

bool OnInit();

10499.

bool OnInit2();

10500.

int OnExit();

10501.

virtual bool OnExceptionInMainLoop();

10502.

virtual void OnUnhandledException();

10503.

virtual void OnFatalException();

10504. };
10505. IMPLEMENT_APP(CMyApp)
10506. bool CMyApp::OnInit()
10507. {
10508.

try

10509.

10510.

return OnInit2();

10511.

10512.

catch (std::exception& e) {

10513.
10514.

PrintException(&e, "OnInit()");
} catch (...) {

10515.

PrintException(NULL, "OnInit()");

10516.

10517.

return false;

10518. }
10519. map<string, string> ParseParameters(int argc, char* argv[])
10520. {
10521.

map<string, string> mapArgs;

10522.

for (int i = 0; i < argc; i++)

10523.

10524.

char psz[10000];

10525.

strcpy(psz, argv[i]);

10526.

char* pszValue = "";

10527.

if (strchr(psz, '='))

10528.

10529.

pszValue = strchr(psz, '=');

10530.

*pszValue++ = '\0';

10531.

10532.

strlwr(psz);

10533.

if (psz[0] == '-')

10534.

psz[0] = '/';

10535.

mapArgs[psz] = pszValue;

10536.

10537.

return mapArgs;

10538. }
10539. bool CMyApp::OnInit2()
10540. {
10541. #ifdef _MSC_VER
10542.

_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);

10543.

_CrtSetReportFile(_CRT_WARN, CreateFile("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0));

10544. #endif
10545.

printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");

10546.

printf("Bitcoin CMyApp::OnInit()\n");

10547.

wxString strMutexName = wxString("Bitcoin.") + getenv("HOMEPATH");

10548.

for (int i = 0; i < strMutexName.size(); i++)

10549.

if (!isalnum(strMutexName[i]))

10550.

strMutexName[i] = '.';

10551.

wxSingleInstanceChecker* psingleinstancechecker = new wxSingleInstanceChecker(strMutexName);

10552.

if (psingleinstancechecker->IsAnotherRunning())

10553.

10554.

printf("Existing instance found\n");

10555.

unsigned int nStart = GetTime();

10556.

loop

10557.

10558.

HWND hwndPrev = FindWindow("wxWindowClassNR", "Bitcoin");

10559.

if (hwndPrev)

10560.

10561.

if (IsIconic(hwndPrev))

10562.

ShowWindow(hwndPrev, SW_RESTORE);

10563.

SetForegroundWindow(hwndPrev);

10564.

return false;

10565.

10566.

if (GetTime() > nStart + 60)

10567.

return false;

10568.

delete psingleinstancechecker;

10569.

Sleep(1000);

10570.

psingleinstancechecker = new wxSingleInstanceChecker(strMutexName);

10571.

if (!psingleinstancechecker->IsAnotherRunning())

10572.

break;

10573.

10574.

10575.

wxImage::AddHandler(new wxPNGHandler);

10576.

map<string, string> mapArgs = ParseParameters(argc, argv);

10577.

if (mapArgs.count("/datadir"))

10578.
10579.

strSetDataDir = mapArgs["/datadir"];
if (mapArgs.count("/proxy"))

10580.
10581.

addrProxy = CAddress(mapArgs["/proxy"].c_str());
if (mapArgs.count("/debug"))

10582.

fDebug = true;

10583.

if (mapArgs.count("/dropmessages"))

10584.

10585.

nDropMessagesTest = atoi(mapArgs["/dropmessages"]);

10586.

if (nDropMessagesTest == 0)

10587.

nDropMessagesTest = 20;

10588.

10589.

if (mapArgs.count("/loadblockindextest"))

10590.

10591.

CTxDB txdb("r");

10592.

txdb.LoadBlockIndex();

10593.

PrintBlockTree();

10594.

ExitProcess(0);

10595.

10596.

string strErrors;

10597.

int64 nStart, nEnd;

10598.

printf("Loading addresses...\n");

10599.

QueryPerformanceCounter((LARGE_INTEGER*)&nStart);

10600.

if (!LoadAddresses())

10601.

\n";

strErrors += "Error loading addr.dat

10602.

QueryPerformanceCounter((LARGE_INTEGER*)&nEnd);

10603.

printf(" addresses %20I64d\n", nEnd - nStart);

10604.

printf("Loading block index...\n");

10605.

QueryPerformanceCounter((LARGE_INTEGER*)&nStart);

10606.

if (!LoadBlockIndex())

10607.

\n";

strErrors += "Error loading blkindex.dat

10608.

QueryPerformanceCounter((LARGE_INTEGER*)&nEnd);

10609.

printf(" block index %20I64d\n", nEnd - nStart);

10610.

printf("Loading wallet...\n");

10611.

QueryPerformanceCounter((LARGE_INTEGER*)&nStart);

10612.

if (!LoadWallet())

10613.

strErrors += "Error loading wallet.dat

\n";

10614.

QueryPerformanceCounter((LARGE_INTEGER*)&nEnd);

10615.

printf(" wallet

10616.

printf("Done loading\n");

%20I64d\n", nEnd - nStart);

10617.

printf("mapBlockIndex.size() = %d\n", mapBlockIndex.size());

10618.

printf("nBestHeight = %d\n",

10619.

printf("mapKeys.size() = %d\n",

10620.

printf("mapPubKeys.size() = %d\n",

10621.

printf("mapWallet.size() = %d\n",

10622.

nBestHeight);
mapKeys.size());
mapPubKeys.size());
mapWallet.size());

printf("mapAddressBook.size() = %d\n", mapAddressBook.size());

10623.

if (!strErrors.empty())

10624.

10625.

wxMessageBox(strErrors);

10626.

OnExit();

10627.

return false;

10628.

10629.

ReacceptWalletTransactions();

10630.

if (mapArgs.count("/printblockindex") || mapArgs.count("/printblocktree"))

10631.

10632.

PrintBlockTree();

10633.

OnExit();

10634.

return false;

10635.

10636.

if (mapArgs.count("/gen"))

10637.

10638.

if (mapArgs["/gen"].empty())

10639.

fGenerateBitcoins = true;

10640.

else

10641.

fGenerateBitcoins = atoi(mapArgs["/gen"].c_str());

10642.

10643.

10644.

pframeMain = new CMainFrame(NULL);

10645.

pframeMain->Show();

10646.

if (!StartNode(strErrors))

10647.
10648.

wxMessageBox(strErrors);
if (fGenerateBitcoins)

10649.

if (_beginthread(ThreadBitcoinMiner, 0, NULL) == -1)

10650.

printf("Error: _beginthread(ThreadBitcoinMiner) failed\n");

10651.

if (argc >= 2 && stricmp(argv[1], "/send") == 0)

10652.

10653.

int64 nValue = 1;

10654.

if (argc >= 3)

10655.

ParseMoney(argv[2], nValue);

10656.

string strAddress;

10657.

if (argc >= 4)

10658.

strAddress = argv[3];

10659.

CAddress addr(strAddress.c_str());

10660.

CWalletTx wtx;

10661.

wtx.mapValue["to"] = strAddress;

10662.

wtx.mapValue["from"] = addrLocalHost.ToString();

10663.

wtx.mapValue["message"] = "command line send";

10664.

CSendingDialog* pdialog = new CSendingDialog(pframeMain, addr, nValue, wtx);

10665.

if (!pdialog->ShowModal())

10666.

return false;

10667.

10668.

if (mapArgs.count("/randsendtest"))

10669.

10670.

if (!mapArgs["/randsendtest"].empty())

10671.

_beginthread(ThreadRandSendTest, 0, new string(mapArgs["/randsendtest"]));

10672.

else

10673.

fRandSendTest = true;

10674.

fDebug = true;

10675.

10676.

10677.

return true;

10678. }
10679. int CMyApp::OnExit()
10680. {
10681.

Shutdown(NULL);

10682.

return wxApp::OnExit();

10683. }
10684. bool CMyApp::OnExceptionInMainLoop()
10685. {
10686.

try

10687.

10688.

throw;

10689.

10690.

catch (std::exception& e)

10691.

10692.

PrintException(&e, "CMyApp::OnExceptionInMainLoop()");

10693.

wxLogWarning(_T("Exception %s %s"), typeid(e).name(), e.what());

10694.

Sleep(1000);

10695.

throw;

10696.

10697.

catch (...)

10698.

10699.

PrintException(NULL, "CMyApp::OnExceptionInMainLoop()");

10700.

wxLogWarning(_T("Unknown exception"));

10701.

Sleep(1000);

10702.

throw;

10703.

10704.

return true;

10705. }
10706. void CMyApp::OnUnhandledException()
10707. {
10708.

try

10709.

10710.

throw;

10711.

10712.

catch (std::exception& e)

10713.

10714.

PrintException(&e, "CMyApp::OnUnhandledException()");

10715.

wxLogWarning(_T("Exception %s %s"), typeid(e).name(), e.what());

10716.

Sleep(1000);

10717.

throw;

10718.

10719.

catch (...)

10720.

10721.

PrintException(NULL, "CMyApp::OnUnhandledException()");

10722.

wxLogWarning(_T("Unknown exception"));

10723.

Sleep(1000);

10724.
10725.

throw;
}

10726. }
10727. void CMyApp::OnFatalException()
10728. {
10729.

wxMessageBox("Program has crashed and will terminate. ", "", wxOK | wxICON_ERROR);

10730. }
10731. void MainFrameRepaint()
10732. {
10733.

if (pframeMain)

10734.

10735.

printf("MainFrameRepaint()\n");

10736.

wxPaintEvent event;

10737.

pframeMain->Refresh();

10738.
10739.

pframeMain->AddPendingEvent(event);
}

10740. }
10741. void ThreadRandSendTest(void* parg)
10742. {
10743.

string strAddress = *(string*)parg;

10744.

uint160 hash160;

10745.

if (!AddressToHash160(strAddress, hash160))

10746.

10747.

wxMessageBox(strprintf("ThreadRandSendTest: Bitcoin address '%s' not valid ", strAddress.c_str()));

10748.

return;

10749.

10750.

loop

10751.

10752.

Sleep(GetRand(30) * 1000 + 100);

10753.

CWalletTx wtx;

10754.

wtx.mapValue["to"] = strAddress;

10755.

wtx.mapValue["from"] = addrLocalHost.ToString();

10756.

static int nRep;

10757.

wtx.mapValue["message"] = strprintf("randsendtest %d\n", ++nRep);

10758.

int64 nValue = (GetRand(9) + 1) * 100 * CENT;

10759.

if (GetBalance() < nValue)

10760.

10761.

wxMessageBox("Out of money ");

10762.

return;

10763.

10764.

nValue += (nRep % 100) * CENT;

10765.

CScript scriptPubKey;

10766.

scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG;

10767.

if (!SendMoney(scriptPubKey, nValue, wtx))

10768.
10769.

return;
}

10770. }
10771. void RandSend()
10772. {
10773.

CWalletTx wtx;

10774.

while (vNodes.empty())

10775.

Sleep(1000);

10776.

CAddress addr;

10777.

CRITICAL_BLOCK(cs_vNodes)

10778.

addr = vNodes[GetRand(vNodes.size())]->addr;

10779.

wtx.mapValue["to"] = addr.ToString();

10780.

wtx.mapValue["from"] = addrLocalHost.ToString();

10781.

static int nRep;

10782.

wtx.mapValue["message"] = strprintf("randsendtest %d\n", ++nRep);

10783.

int64 nValue = (GetRand(999) + 1) * CENT;

10784.

if (GetBalance() < nValue)

10785.

10786.

wxMessageBox("Out of money ");

10787.

return;

10788.

10789.

CSendingDialog* pdialog = new CSendingDialog(pframeMain, addr, nValue, wtx);

10790.

if (!pdialog->Show())

10791.

wxMessageBox("ShowModal Failed ");

10792. }
10793. DECLARE_EVENT_TYPE(wxEVT_CROSSTHREADCALL, -1)
10794. DECLARE_EVENT_TYPE(wxEVT_REPLY1, -1)
10795. DECLARE_EVENT_TYPE(wxEVT_REPLY2, -1)
10796. DECLARE_EVENT_TYPE(wxEVT_REPLY3, -1)
10797. DECLARE_EVENT_TYPE(wxEVT_TABLEADDED, -1)
10798. DECLARE_EVENT_TYPE(wxEVT_TABLEUPDATED, -1)
10799. DECLARE_EVENT_TYPE(wxEVT_TABLEDELETED, -1)
10800. enum
10801. {
10802.

UICALL_ADDORDER = 1,

10803.

UICALL_UPDATEORDER,

10804. };
10805. extern void HandleCtrlA(wxKeyEvent& event);
10806. extern string DateTimeStr(int64 nTime);
10807. extern string FormatTxStatus(const CWalletTx& wtx);
10808. extern void CrossThreadCall(int nID, void* pdata);
10809. extern void MainFrameRepaint();
10810. class CMainFrame : public CMainFrameBase
10811. {
10812. protected:
10813.

void OnClose(wxCloseEvent& event);

10814.

void OnMouseEvents(wxMouseEvent& event);

10815.

void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); }

10816.

void OnIdle(wxIdleEvent& event);

10817.

void OnPaint(wxPaintEvent& event);

10818.

void OnPaintListCtrl(wxPaintEvent& event);

10819.

void OnMenuFileExit(wxCommandEvent& event);

10820.

void OnMenuOptionsGenerate(wxCommandEvent& event);

10821.

void OnMenuOptionsOptions(wxCommandEvent& event);

10822.

void OnMenuHelpAbout(wxCommandEvent& event);

10823.

void OnButtonSend(wxCommandEvent& event);

10824.

void OnButtonAddressBook(wxCommandEvent& event);

10825.

void OnSetFocusAddress(wxFocusEvent& event);

10826.

void OnMouseEventsAddress(wxMouseEvent& event);

10827.

void OnButtonCopy(wxCommandEvent& event);

10828.

void OnButtonChange(wxCommandEvent& event);

10829.

void OnListColBeginDrag(wxListEvent& event);

10830.

void OnListItemActivatedAllTransactions(wxListEvent& event);

10831.

void OnListItemActivatedProductsSent(wxListEvent& event);

10832.

void OnListItemActivatedOrdersSent(wxListEvent& event);

10833.

void OnListItemActivatedOrdersReceived(wxListEvent& event);

10834. public:
10835.

CMainFrame(wxWindow* parent);

10836.

~CMainFrame();

10837.

bool fRefreshListCtrl;

10838.

bool fRefreshListCtrlRunning;

10839.

bool fOnSetFocusAddress;

10840.

CBlockIndex* pindexBestLast;

10841.

set<uint256> setUnmaturedDisplayed;

10842.

void OnCrossThreadCall(wxCommandEvent& event);

10843.

void InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxString& str1, const wxString& str2, const wxString& str3, const
wxString& str4, const wxString& str5);

10844.

void InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex=-1);

10845.

void RefreshListCtrl();

10846.

void RefreshStatus();

10847. };
10848. class CTxDetailsDialog : public CTxDetailsDialogBase
10849. {
10850. protected:
10851.

void OnButtonOK(wxCommandEvent& event);

10852. public:
10853.

CTxDetailsDialog(wxWindow* parent, CWalletTx wtx);

10854.

CWalletTx wtx;

10855. };
10856. class COptionsDialog : public COptionsDialogBase
10857. {
10858. protected:
10859.

void OnKillFocusTransactionFee(wxFocusEvent& event);

10860.

void OnButtonOK(wxCommandEvent& event);

10861.

void OnButtonCancel(wxCommandEvent& event);

10862. public:
10863.

COptionsDialog(wxWindow* parent);

10864. };
10865. class CAboutDialog : public CAboutDialogBase
10866. {
10867. protected:
10868.

void OnButtonOK(wxCommandEvent& event);

10869. public:
10870.

CAboutDialog(wxWindow* parent);

10871. };
10872. class CSendDialog : public CSendDialogBase
10873. {
10874. protected:
10875.

void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); }

10876.

void OnTextAddress(wxCommandEvent& event);

10877.

void OnKillFocusAmount(wxFocusEvent& event);

10878.

void OnButtonAddressBook(wxCommandEvent& event);

10879.

void OnButtonPaste(wxCommandEvent& event);

10880.

void OnButtonSend(wxCommandEvent& event);

10881.

void OnButtonCancel(wxCommandEvent& event);

10882. public:
10883.

CSendDialog(wxWindow* parent, const wxString& strAddress="");

10884. };
10885. class CSendingDialog : public CSendingDialogBase
10886. {
10887. public:
10888.

void OnClose(wxCloseEvent& event);

10889.

void OnButtonOK(wxCommandEvent& event);

10890.

void OnButtonCancel(wxCommandEvent& event);

10891.

void OnPaint(wxPaintEvent& event);

10892. public:
10893.

CSendingDialog(wxWindow* parent, const CAddress& addrIn, int64 nPriceIn, const CWalletTx& wtxIn);

10894.

~CSendingDialog();

10895.

CAddress addr;

10896.

int64 nPrice;

10897.

CWalletTx wtx;

10898.

wxDateTime start;

10899.

string strStatus;

10900.

bool fCanCancel;

10901.

bool fAbort;

10902.

bool fSuccess;

10903.

bool fUIDone;

10904.

bool fWorkDone;

10905.

void Close();

10906.

void Repaint();

10907.

bool Status();

10908.

bool Status(const string& str);

10909.

bool Error(const string& str);

10910.

void StartTransfer();

10911.

void OnReply2(CDataStream& vRecv);

10912.

void OnReply3(CDataStream& vRecv);

10913. };
10914. void SendingDialogStartTransfer(void* parg);
10915. void SendingDialogOnReply2(void* parg, CDataStream& vRecv);
10916. void SendingDialogOnReply3(void* parg, CDataStream& vRecv);
10917. class CYourAddressDialog : public CYourAddressDialogBase
10918. {
10919. protected:
10920.

void OnListEndLabelEdit(wxListEvent& event);

10921.

void OnListItemSelected(wxListEvent& event);

10922.

void OnListItemActivated(wxListEvent& event);

10923.

void OnButtonRename(wxCommandEvent& event);

10924.

void OnButtonNew(wxCommandEvent& event);

10925.

void OnButtonCopy(wxCommandEvent& event);

10926.

void OnButtonOK(wxCommandEvent& event);

10927.

void OnButtonCancel(wxCommandEvent& event);

10928.

void OnClose(wxCloseEvent& event);

10929. public:
10930.

CYourAddressDialog(wxWindow* parent);

10931.

CYourAddressDialog(wxWindow* parent, const string& strInitSelected);

10932.

wxString GetAddress();

10933. };
10934. class CAddressBookDialog : public CAddressBookDialogBase
10935. {
10936. protected:
10937.

void OnListEndLabelEdit(wxListEvent& event);

10938.

void OnListItemSelected(wxListEvent& event);

10939.

void OnListItemActivated(wxListEvent& event);

10940.

void OnButtonEdit(wxCommandEvent& event);

10941.

void OnButtonDelete(wxCommandEvent& event);

10942.

void OnButtonNew(wxCommandEvent& event);

10943.

void OnButtonCopy(wxCommandEvent& event);

10944.

void OnButtonOK(wxCommandEvent& event);

10945.

void OnButtonCancel(wxCommandEvent& event);

10946.

void OnClose(wxCloseEvent& event);

10947. public:
10948.

CAddressBookDialog(wxWindow* parent, const wxString& strInitSelected, bool fSendingIn);

10949.

bool fSending;

10950.

wxString GetAddress();

10951. };
10952. class CProductsDialog : public CProductsDialogBase
10953. {
10954. protected:
10955.

void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); }

10956.

void OnCombobox(wxCommandEvent& event);

10957.

void OnButtonSearch(wxCommandEvent& event);

10958.

void OnListItemActivated(wxListEvent& event);

10959. public:
10960.

CProductsDialog(wxWindow* parent);

10961.

vector<CProduct> m_vProduct;

10962. };
10963. class CEditProductDialog : public CEditProductDialogBase
10964. {
10965. protected:
10966.

void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); }

10967.

void OnButtonDel0(wxCommandEvent& event);

10968.

void OnButtonDel1(wxCommandEvent& event);

10969.

void OnButtonDel2(wxCommandEvent& event);

10970.

void OnButtonDel3(wxCommandEvent& event);

10971.

void OnButtonDel4(wxCommandEvent& event);

10972.

void OnButtonDel5(wxCommandEvent& event);

10973.

void OnButtonDel6(wxCommandEvent& event);

10974.

void OnButtonDel7(wxCommandEvent& event);

10975.

void OnButtonDel8(wxCommandEvent& event);

10976.

void OnButtonDel9(wxCommandEvent& event);

10977.

void OnButtonDel10(wxCommandEvent& event);

10978.

void OnButtonDel11(wxCommandEvent& event);

10979.

void OnButtonDel12(wxCommandEvent& event);

10980.

void OnButtonDel13(wxCommandEvent& event);

10981.

void OnButtonDel14(wxCommandEvent& event);

10982.

void OnButtonDel15(wxCommandEvent& event);

10983.

void OnButtonDel16(wxCommandEvent& event);

10984.

void OnButtonDel17(wxCommandEvent& event);

10985.

void OnButtonDel18(wxCommandEvent& event);

10986.

void OnButtonDel19(wxCommandEvent& event);

10987.

void OnButtonAddField(wxCommandEvent& event);

10988.

void OnButtonSend(wxCommandEvent& event);

10989.

void OnButtonPreview(wxCommandEvent& event);

10990.

void OnButtonCancel(wxCommandEvent& event);

10991. public:
10992.

CEditProductDialog(wxWindow* parent);

10993.

enum { FIELDS_MAX = 20 };

10994.

wxTextCtrl* m_textCtrlLabel[FIELDS_MAX];

10995.

wxTextCtrl* m_textCtrlField[FIELDS_MAX];

10996.

wxButton* m_buttonDel[FIELDS_MAX];

10997.

void LayoutAll();

10998.

void ShowLine(int i, bool fShow=true);

10999.

void OnButtonDel(wxCommandEvent& event, int n);

11000.

void SetProduct(const CProduct& productIn);

11001.

void GetProduct(CProduct& product);

11002. };
11003. class CViewProductDialog : public CViewProductDialogBase
11004. {
11005. protected:
11006.

void OnButtonSubmitForm(wxCommandEvent& event);

11007.

void OnButtonCancelForm(wxCommandEvent& event);

11008.

void OnButtonBack(wxCommandEvent& event);

11009.

void OnButtonNext(wxCommandEvent& event);

11010.

void OnButtonCancel(wxCommandEvent& event);

11011. public:
11012.

CViewProductDialog(wxWindow* parent, const CProduct& productIn);

11013.

~CViewProductDialog();

11014.

CProduct product;

11015.

enum { FIELDS_MAX = 20 };

11016.

wxStaticText* m_staticTextLabel[FIELDS_MAX];

11017.

wxTextCtrl* m_textCtrlField[FIELDS_MAX];

11018.

wxChoice*

11019.

void GetOrder(CWalletTx& order);

11020.

void UpdateProductDisplay(bool fDetails);

11021.

void OnReply1(wxCommandEvent& event);

m_choiceField[FIELDS_MAX];

11022. };
11023. class CViewOrderDialog : public CViewOrderDialogBase
11024. {
11025. protected:
11026.

void OnButtonOK(wxCommandEvent& event);

11027. public:
11028.

CViewOrderDialog(wxWindow* parent, CWalletTx order, bool fReceived);

11029.

bool fReceived;

11030. };
11031. class CEditReviewDialog : public CEditReviewDialogBase
11032. {
11033. protected:
11034.

void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); }

11035.

void OnButtonSubmit(wxCommandEvent& event);

11036.

void OnButtonCancel(wxCommandEvent& event);

11037. public:
11038.

CEditReviewDialog(wxWindow* parent);

11039.

void GetReview(CReview& review);

11040. };
11041. class CGetTextFromUserDialog : public CGetTextFromUserDialogBase
11042. {
11043. protected:
11044.

void OnButtonOK(wxCommandEvent& event)

11045.

void OnButtonCancel(wxCommandEvent& event) { EndModal(false); }

11046.

void OnClose(wxCloseEvent& event)

11047.

void OnKeyDown(wxKeyEvent& event)

11048.

11049.

{ EndModal(false); }

if (event.GetKeyCode() == '\r' || event.GetKeyCode() == WXK_NUMPAD_ENTER)

11050.

EndModal(true);

11051.

else

11052.
11053.

{ EndModal(true); }

HandleCtrlA(event);
}

11054. public:
11055.

CGetTextFromUserDialog(wxWindow* parent,

11056.

const string& strCaption,

11057.

const string& strMessage1,

11058.

const string& strValue1="",

11059.

const string& strMessage2="",

11060.
11061.

const string& strValue2="") : CGetTextFromUserDialogBase(parent, wxID_ANY, strCaption)


{

11062.

m_staticTextMessage1->SetLabel(strMessage1);

11063.

m_textCtrl1->SetValue(strValue1);

11064.

if (!strMessage2.empty())

11065.

11066.

m_staticTextMessage2->Show(true);

11067.

m_staticTextMessage2->SetLabel(strMessage2);

11068.

m_textCtrl2->Show(true);

11069.

m_textCtrl2->SetValue(strValue2);

11070.

SetSize(wxDefaultCoord, 180);

11071.

11072.

11073.

string GetValue() { return (string)m_textCtrl1->GetValue(); }

11074.

string GetValue1() { return (string)m_textCtrl1->GetValue(); }

11075.

string GetValue2() { return (string)m_textCtrl2->GetValue(); }

11076. };
11077. #include <limits.h>
11078. #include <string>
11079. #if defined(_MSC_VER) || defined(__BORLANDC__)
11080. typedef __int64 int64;
11081. typedef unsigned __int64 uint64;
11082. #else
11083. typedef long long int64;
11084. typedef unsigned long long uint64;
11085. #endif
11086. #if defined(_MSC_VER) && _MSC_VER < 1300
11087. #define for if (false) ; else for
11088. #endif
11089. inline int Testuint256AdHoc(vector<string> vArg);
11090. template<unsigned int BITS>
11091. class base_uint
11092. {
11093. protected:
11094.

enum { WIDTH=BITS/32 };

11095.

unsigned int pn[WIDTH];

11096. public:
11097.

bool operator!() const

11098.

11099.

for (int i = 0; i < WIDTH; i++)

11100.

if (pn[i] != 0)

11101.

return false;

11102.

return true;

11103.

11104.

const base_uint operator~() const

11105.

11106.

base_uint ret;

11107.

for (int i = 0; i < WIDTH; i++)

11108.

ret.pn[i] = ~pn[i];

11109.

return ret;

11110.

11111.

const base_uint operator-() const

11112.

11113.

base_uint ret;

11114.

for (int i = 0; i < WIDTH; i++)

11115.

ret.pn[i] = ~pn[i];

11116.

ret++;

11117.

return ret;

11118.

11119.

base_uint& operator=(uint64 b)

11120.

11121.

pn[0] = (unsigned int)b;

11122.

pn[1] = (unsigned int)(b >> 32);

11123.

for (int i = 2; i < WIDTH; i++)

11124.

pn[i] = 0;

11125.

return *this;

11126.

11127.

base_uint& operator^=(const base_uint& b)

11128.

11129.

for (int i = 0; i < WIDTH; i++)

11130.

pn[i] ^= b.pn[i];

11131.

return *this;

11132.

11133.

base_uint& operator&=(const base_uint& b)

11134.

11135.

for (int i = 0; i < WIDTH; i++)

11136.

pn[i] &= b.pn[i];

11137.

return *this;

11138.

11139.

base_uint& operator|=(const base_uint& b)

11140.

11141.

for (int i = 0; i < WIDTH; i++)

11142.

pn[i] |= b.pn[i];

11143.

return *this;

11144.

11145.

base_uint& operator^=(uint64 b)

11146.

11147.

pn[0] ^= (unsigned int)b;

11148.

pn[1] ^= (unsigned int)(b >> 32);

11149.

return *this;

11150.

11151.

base_uint& operator&=(uint64 b)

11152.

11153.

pn[0] &= (unsigned int)b;

11154.

pn[1] &= (unsigned int)(b >> 32);

11155.

return *this;

11156.

11157.

base_uint& operator|=(uint64 b)

11158.

11159.

pn[0] |= (unsigned int)b;

11160.

pn[1] |= (unsigned int)(b >> 32);

11161.

return *this;

11162.

11163.

base_uint& operator<<=(unsigned int shift)

11164.

11165.

base_uint a(*this);

11166.

for (int i = 0; i < WIDTH; i++)

11167.

pn[i] = 0;

11168.

int k = shift / 32;

11169.

shift = shift % 32;

11170.

for (int i = 0; i < WIDTH; i++)

11171.

11172.

if (i+k+1 < WIDTH && shift != 0)

11173.

pn[i+k+1] |= (a.pn[i] >> (32-shift));

11174.

if (i+k < WIDTH)

11175.

pn[i+k] |= (a.pn[i] << shift);

11176.

11177.

return *this;

11178.

11179.

base_uint& operator>>=(unsigned int shift)

11180.

11181.

base_uint a(*this);

11182.

for (int i = 0; i < WIDTH; i++)

11183.

pn[i] = 0;

11184.

int k = shift / 32;

11185.

shift = shift % 32;

11186.

for (int i = 0; i < WIDTH; i++)

11187.

11188.

if (i-k-1 >= 0 && shift != 0)

11189.

pn[i-k-1] |= (a.pn[i] << (32-shift));

11190.

if (i-k >= 0)

11191.

pn[i-k] |= (a.pn[i] >> shift);

11192.

11193.

return *this;

11194.

11195.

base_uint& operator+=(const base_uint& b)

11196.

11197.

uint64 carry = 0;

11198.

for (int i = 0; i < WIDTH; i++)

11199.

11200.

uint64 n = carry + pn[i] + b.pn[i];

11201.

pn[i] = n & 0xffffffff;

11202.

carry = n >> 32;

11203.

11204.

return *this;

11205.

11206.

base_uint& operator-=(const base_uint& b)

11207.

11208.

*this += -b;

11209.

return *this;

11210.

11211.

base_uint& operator+=(uint64 b64)

11212.

11213.

base_uint b;

11214.

b = b64;

11215.

*this += b;

11216.

return *this;

11217.

11218.

base_uint& operator-=(uint64 b64)

11219.

11220.

base_uint b;

11221.

b = b64;

11222.

*this += -b;

11223.

return *this;

11224.

11225.

base_uint& operator++()

11226.

11227.

int i = 0;

11228.

while (++pn[i] == 0 && i < WIDTH-1)

11229.

i++;

11230.

return *this;

11231.

11232.

const base_uint operator++(int)

11233.

11234.

const base_uint ret = *this;

11235.

++(*this);

11236.

return ret;

11237.

11238.

base_uint& operator--()

11239.

11240.

int i = 0;

11241.

while (--pn[i] == -1 && i < WIDTH-1)

11242.

i++;

11243.

return *this;

11244.

11245.

const base_uint operator--(int)

11246.

11247.

const base_uint ret = *this;

11248.

--(*this);

11249.

return ret;

11250.

11251.

friend inline bool operator<(const base_uint& a, const base_uint& b)

11252.

11253.

for (int i = base_uint::WIDTH-1; i >= 0; i--)

11254.

11255.

if (a.pn[i] < b.pn[i])

11256.

return true;

11257.

else if (a.pn[i] > b.pn[i])

11258.

return false;

11259.

11260.

return false;

11261.

11262.

friend inline bool operator<=(const base_uint& a, const base_uint& b)

11263.

11264.

for (int i = base_uint::WIDTH-1; i >= 0; i--)

11265.

11266.

if (a.pn[i] < b.pn[i])

11267.

return true;

11268.

else if (a.pn[i] > b.pn[i])

11269.

return false;

11270.

11271.

return true;

11272.

11273.

friend inline bool operator>(const base_uint& a, const base_uint& b)

11274.

11275.

for (int i = base_uint::WIDTH-1; i >= 0; i--)

11276.

11277.

if (a.pn[i] > b.pn[i])

11278.

return true;

11279.

else if (a.pn[i] < b.pn[i])

11280.

return false;

11281.

11282.

return false;

11283.

11284.

friend inline bool operator>=(const base_uint& a, const base_uint& b)

11285.

11286.

for (int i = base_uint::WIDTH-1; i >= 0; i--)

11287.

11288.

if (a.pn[i] > b.pn[i])

11289.

return true;

11290.

else if (a.pn[i] < b.pn[i])

11291.

return false;

11292.

11293.

return true;

11294.

11295.

friend inline bool operator==(const base_uint& a, const base_uint& b)

11296.

11297.

for (int i = 0; i < base_uint::WIDTH; i++)

11298.

if (a.pn[i] != b.pn[i])

11299.

return false;

11300.

return true;

11301.

11302.

friend inline bool operator==(const base_uint& a, uint64 b)

11303.

11304.

if (a.pn[0] != (unsigned int)b)

11305.

return false;

11306.

if (a.pn[1] != (unsigned int)(b >> 32))

11307.

return false;

11308.

for (int i = 2; i < base_uint::WIDTH; i++)

11309.

if (a.pn[i] != 0)

11310.

return false;

11311.

return true;

11312.

11313.

friend inline bool operator!=(const base_uint& a, const base_uint& b)

11314.

11315.

return (!(a == b));

11316.

11317.

friend inline bool operator!=(const base_uint& a, uint64 b)

11318.

11319.

return (!(a == b));

11320.

11321.

std::string GetHex() const

11322.

11323.

char psz[sizeof(pn)*2 + 1];

11324.

for (int i = 0; i < sizeof(pn); i++)

11325.

sprintf(psz + i*2, "%02x", ((unsigned char*)pn)[sizeof(pn) - i - 1]);

11326.

return string(psz, psz + sizeof(pn)*2);

11327.

11328.

void SetHex(const std::string& str)

11329.

11330.

for (int i = 0; i < WIDTH; i++)

11331.

pn[i] = 0;

11332.

const char* psz = str.c_str();

11333.

while (isspace(*psz))

11334.

psz++;

11335.

if (psz[0] == '0' && tolower(psz[1]) == 'x')

11336.

psz += 2;

11337.

while (isspace(*psz))

11338.

psz++;

11339.

static char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,


0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0
};

11340.

const char* pbegin = psz;

11341.

while (phexdigit[*psz] || *psz == '0')

11342.

psz++;

11343.

psz--;

11344.

unsigned char* p1 = (unsigned char*)pn;

11345.

unsigned char* pend = p1 + WIDTH * 4;

11346.

while (psz >= pbegin && p1 < pend)

11347.

11348.

*p1 = phexdigit[(unsigned char)*psz--];

11349.

if (psz >= pbegin)

11350.

11351.

*p1 |= (phexdigit[(unsigned char)*psz--] << 4);

11352.

p1++;

11353.

11354.

11355.

11356.

std::string ToString() const

11357.

11358.

return (GetHex());

11359.

11360.

unsigned char* begin()

11361.

11362.

return (unsigned char*)&pn[0];

11363.

11364.

unsigned char* end()

11365.

11366.

return (unsigned char*)&pn[WIDTH];

11367.

11368.

unsigned int size()

11369.

11370.

return sizeof(pn);

11371.

11372.

unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const

11373.

11374.

return sizeof(pn);

11375.

11376.

template<typename Stream>

11377.

void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const

11378.

11379.

s.write((char*)pn, sizeof(pn));

11380.

11381.

template<typename Stream>

11382.

void Unserialize(Stream& s, int nType=0, int nVersion=VERSION)

11383.

11384.

s.read((char*)pn, sizeof(pn));

11385.

11386.

friend class uint160;

11387.

friend class uint256;

11388.

friend inline int Testuint256AdHoc(vector<string> vArg);

11389. };
11390. typedef base_uint<160> base_uint160;
11391. typedef base_uint<256> base_uint256;
11392. class uint160 : public base_uint160
11393. {
11394. public:
11395.

typedef base_uint160 basetype;

11396.

uint160()

11397.

11398.

11399.

uint160(const basetype& b)

11400.

11401.

for (int i = 0; i < WIDTH; i++)

11402.

pn[i] = b.pn[i];

11403.

11404.

uint160& operator=(const basetype& b)

11405.

11406.

for (int i = 0; i < WIDTH; i++)

11407.

pn[i] = b.pn[i];

11408.

return *this;

11409.

11410.

uint160(uint64 b)

11411.

11412.

pn[0] = (unsigned int)b;

11413.

pn[1] = (unsigned int)(b >> 32);

11414.

for (int i = 2; i < WIDTH; i++)

11415.

pn[i] = 0;

11416.

11417.

uint160& operator=(uint64 b)

11418.

11419.

pn[0] = (unsigned int)b;

11420.

pn[1] = (unsigned int)(b >> 32);

11421.

for (int i = 2; i < WIDTH; i++)

11422.

pn[i] = 0;

11423.

return *this;

11424.

11425.

explicit uint160(const std::string& str)

11426.

11427.

SetHex(str);

11428.

11429.

explicit uint160(const std::vector<unsigned char>& vch)

11430.

11431.

if (vch.size() == sizeof(pn))

11432.

memcpy(pn, &vch[0], sizeof(pn));

11433.

else

11434.
11435.

*this = 0;
}

11436. };
11437. inline bool operator==(const uint160& a, uint64 b)
11438. inline bool operator!=(const uint160& a, uint64 b)

{ return (base_uint160)a == b; }
{ return (base_uint160)a != b; }

11439. inline const uint160 operator<<(const base_uint160& a, unsigned int shift) { return uint160(a) <<= shift; }
11440. inline const uint160 operator>>(const base_uint160& a, unsigned int shift) { return uint160(a) >>= shift; }
11441. inline const uint160 operator<<(const uint160& a, unsigned int shift)

{ return uint160(a) <<= shift; }

11442. inline const uint160 operator>>(const uint160& a, unsigned int shift)

{ return uint160(a) >>= shift; }

11443. inline const uint160 operator^(const base_uint160& a, const base_uint160& b) { return uint160(a) ^= b; }
11444. inline const uint160 operator&(const base_uint160& a, const base_uint160& b) { return uint160(a) &= b; }
11445. inline const uint160 operator|(const base_uint160& a, const base_uint160& b) { return uint160(a) |= b; }
11446. inline const uint160 operator+(const base_uint160& a, const base_uint160& b) { return uint160(a) += b; }
11447. inline const uint160 operator-(const base_uint160& a, const base_uint160& b) { return uint160(a) -= b; }
11448. inline bool operator<(const base_uint160& a, const uint160& b)

{ return (base_uint160)a < (base_uint160)b; }

11449. inline bool operator<=(const base_uint160& a, const uint160& b)

{ return (base_uint160)a <= (base_uint160)b; }

11450. inline bool operator>(const base_uint160& a, const uint160& b)

{ return (base_uint160)a > (base_uint160)b; }

11451. inline bool operator>=(const base_uint160& a, const uint160& b)

{ return (base_uint160)a >= (base_uint160)b; }

11452. inline bool operator==(const base_uint160& a, const uint160& b)

{ return (base_uint160)a == (base_uint160)b; }

11453. inline bool operator!=(const base_uint160& a, const uint160& b)

{ return (base_uint160)a != (base_uint160)b; }

11454. inline const uint160 operator^(const base_uint160& a, const uint160& b) { return (base_uint160)a ^ (base_uint160)b; }
11455. inline const uint160 operator&(const base_uint160& a, const uint160& b) { return (base_uint160)a & (base_uint160)b; }
11456. inline const uint160 operator|(const base_uint160& a, const uint160& b) { return (base_uint160)a | (base_uint160)b; }
11457. inline const uint160 operator+(const base_uint160& a, const uint160& b) { return (base_uint160)a + (base_uint160)b; }
11458. inline const uint160 operator-(const base_uint160& a, const uint160& b) { return (base_uint160)a - (base_uint160)b; }
11459. inline bool operator<(const uint160& a, const base_uint160& b)

{ return (base_uint160)a < (base_uint160)b; }

11460. inline bool operator<=(const uint160& a, const base_uint160& b)

{ return (base_uint160)a <= (base_uint160)b; }

11461. inline bool operator>(const uint160& a, const base_uint160& b)

{ return (base_uint160)a > (base_uint160)b; }

11462. inline bool operator>=(const uint160& a, const base_uint160& b)

{ return (base_uint160)a >= (base_uint160)b; }

11463. inline bool operator==(const uint160& a, const base_uint160& b)

{ return (base_uint160)a == (base_uint160)b; }

11464. inline bool operator!=(const uint160& a, const base_uint160& b)

{ return (base_uint160)a != (base_uint160)b; }

11465. inline const uint160 operator^(const uint160& a, const base_uint160& b) { return (base_uint160)a ^ (base_uint160)b; }
11466. inline const uint160 operator&(const uint160& a, const base_uint160& b) { return (base_uint160)a & (base_uint160)b; }
11467. inline const uint160 operator|(const uint160& a, const base_uint160& b) { return (base_uint160)a | (base_uint160)b; }
11468. inline const uint160 operator+(const uint160& a, const base_uint160& b) { return (base_uint160)a + (base_uint160)b; }
11469. inline const uint160 operator-(const uint160& a, const base_uint160& b) { return (base_uint160)a - (base_uint160)b; }
11470. inline bool operator<(const uint160& a, const uint160& b)

{ return (base_uint160)a < (base_uint160)b; }

11471. inline bool operator<=(const uint160& a, const uint160& b)


11472. inline bool operator>(const uint160& a, const uint160& b)

{ return (base_uint160)a <= (base_uint160)b; }


{ return (base_uint160)a > (base_uint160)b; }

11473. inline bool operator>=(const uint160& a, const uint160& b)

{ return (base_uint160)a >= (base_uint160)b; }

11474. inline bool operator==(const uint160& a, const uint160& b)


11475. inline bool operator!=(const uint160& a, const uint160& b)

{ return (base_uint160)a == (base_uint160)b; }


{ return (base_uint160)a != (base_uint160)b; }

11476. inline const uint160 operator^(const uint160& a, const uint160& b)


11477. inline const uint160 operator&(const uint160& a, const uint160& b)
11478. inline const uint160 operator|(const uint160& a, const uint160& b)
11479. inline const uint160 operator+(const uint160& a, const uint160& b)

{ return (base_uint160)a ^ (base_uint160)b; }


{ return (base_uint160)a & (base_uint160)b; }
{ return (base_uint160)a | (base_uint160)b; }
{ return (base_uint160)a + (base_uint160)b; }

11480. inline const uint160 operator-(const uint160& a, const uint160& b)

{ return (base_uint160)a - (base_uint160)b; }

11481. class uint256 : public base_uint256


11482. {
11483. public:
11484.

typedef base_uint256 basetype;

11485.

uint256()

11486.

11487.

11488.

uint256(const basetype& b)

11489.

11490.

for (int i = 0; i < WIDTH; i++)

11491.

pn[i] = b.pn[i];

11492.

11493.

uint256& operator=(const basetype& b)

11494.

11495.

for (int i = 0; i < WIDTH; i++)

11496.

pn[i] = b.pn[i];

11497.

return *this;

11498.

11499.

uint256(uint64 b)

11500.

11501.

pn[0] = (unsigned int)b;

11502.

pn[1] = (unsigned int)(b >> 32);

11503.

for (int i = 2; i < WIDTH; i++)

11504.

pn[i] = 0;

11505.

11506.

uint256& operator=(uint64 b)

11507.

11508.

pn[0] = (unsigned int)b;

11509.

pn[1] = (unsigned int)(b >> 32);

11510.

for (int i = 2; i < WIDTH; i++)

11511.

pn[i] = 0;

11512.

return *this;

11513.

11514.

explicit uint256(const std::string& str)

11515.

11516.

SetHex(str);

11517.

11518.

explicit uint256(const std::vector<unsigned char>& vch)

11519.

11520.

if (vch.size() == sizeof(pn))

11521.

memcpy(pn, &vch[0], sizeof(pn));

11522.

else

11523.
11524.

*this = 0;
}

11525. };
11526. inline bool operator==(const uint256& a, uint64 b)
11527. inline bool operator!=(const uint256& a, uint64 b)

{ return (base_uint256)a == b; }
{ return (base_uint256)a != b; }

11528. inline const uint256 operator<<(const base_uint256& a, unsigned int shift) { return uint256(a) <<= shift; }
11529. inline const uint256 operator>>(const base_uint256& a, unsigned int shift) { return uint256(a) >>= shift; }
11530. inline const uint256 operator<<(const uint256& a, unsigned int shift)

{ return uint256(a) <<= shift; }

11531. inline const uint256 operator>>(const uint256& a, unsigned int shift)

{ return uint256(a) >>= shift; }

11532. inline const uint256 operator^(const base_uint256& a, const base_uint256& b) { return uint256(a) ^= b; }
11533. inline const uint256 operator&(const base_uint256& a, const base_uint256& b) { return uint256(a) &= b; }
11534. inline const uint256 operator|(const base_uint256& a, const base_uint256& b) { return uint256(a) |= b; }
11535. inline const uint256 operator+(const base_uint256& a, const base_uint256& b) { return uint256(a) += b; }
11536. inline const uint256 operator-(const base_uint256& a, const base_uint256& b) { return uint256(a) -= b; }
11537. inline bool operator<(const base_uint256& a, const uint256& b)
11538. inline bool operator<=(const base_uint256& a, const uint256& b)
11539. inline bool operator>(const base_uint256& a, const uint256& b)
11540. inline bool operator>=(const base_uint256& a, const uint256& b)
11541. inline bool operator==(const base_uint256& a, const uint256& b)
11542. inline bool operator!=(const base_uint256& a, const uint256& b)

{ return (base_uint256)a < (base_uint256)b; }


{ return (base_uint256)a <= (base_uint256)b; }
{ return (base_uint256)a > (base_uint256)b; }
{ return (base_uint256)a >= (base_uint256)b; }
{ return (base_uint256)a == (base_uint256)b; }
{ return (base_uint256)a != (base_uint256)b; }

11543. inline const uint256 operator^(const base_uint256& a, const uint256& b) { return (base_uint256)a ^ (base_uint256)b; }
11544. inline const uint256 operator&(const base_uint256& a, const uint256& b) { return (base_uint256)a & (base_uint256)b; }
11545. inline const uint256 operator|(const base_uint256& a, const uint256& b) { return (base_uint256)a | (base_uint256)b; }
11546. inline const uint256 operator+(const base_uint256& a, const uint256& b) { return (base_uint256)a + (base_uint256)b; }
11547. inline const uint256 operator-(const base_uint256& a, const uint256& b) { return (base_uint256)a - (base_uint256)b; }
11548. inline bool operator<(const uint256& a, const base_uint256& b)
11549. inline bool operator<=(const uint256& a, const base_uint256& b)
11550. inline bool operator>(const uint256& a, const base_uint256& b)
11551. inline bool operator>=(const uint256& a, const base_uint256& b)
11552. inline bool operator==(const uint256& a, const base_uint256& b)
11553. inline bool operator!=(const uint256& a, const base_uint256& b)

{ return (base_uint256)a < (base_uint256)b; }


{ return (base_uint256)a <= (base_uint256)b; }
{ return (base_uint256)a > (base_uint256)b; }
{ return (base_uint256)a >= (base_uint256)b; }
{ return (base_uint256)a == (base_uint256)b; }
{ return (base_uint256)a != (base_uint256)b; }

11554. inline const uint256 operator^(const uint256& a, const base_uint256& b) { return (base_uint256)a ^ (base_uint256)b; }
11555. inline const uint256 operator&(const uint256& a, const base_uint256& b) { return (base_uint256)a & (base_uint256)b; }
11556. inline const uint256 operator|(const uint256& a, const base_uint256& b) { return (base_uint256)a | (base_uint256)b; }
11557. inline const uint256 operator+(const uint256& a, const base_uint256& b) { return (base_uint256)a + (base_uint256)b; }
11558. inline const uint256 operator-(const uint256& a, const base_uint256& b) { return (base_uint256)a - (base_uint256)b; }
11559. inline bool operator<(const uint256& a, const uint256& b)
11560. inline bool operator<=(const uint256& a, const uint256& b)
11561. inline bool operator>(const uint256& a, const uint256& b)
11562. inline bool operator>=(const uint256& a, const uint256& b)

{ return (base_uint256)a < (base_uint256)b; }


{ return (base_uint256)a <= (base_uint256)b; }
{ return (base_uint256)a > (base_uint256)b; }
{ return (base_uint256)a >= (base_uint256)b; }

11563. inline bool operator==(const uint256& a, const uint256& b)


11564. inline bool operator!=(const uint256& a, const uint256& b)

{ return (base_uint256)a == (base_uint256)b; }


{ return (base_uint256)a != (base_uint256)b; }

11565. inline const uint256 operator^(const uint256& a, const uint256& b)


11566. inline const uint256 operator&(const uint256& a, const uint256& b)
11567. inline const uint256 operator|(const uint256& a, const uint256& b)

{ return (base_uint256)a ^ (base_uint256)b; }


{ return (base_uint256)a & (base_uint256)b; }
{ return (base_uint256)a | (base_uint256)b; }

11568. inline const uint256 operator+(const uint256& a, const uint256& b)

{ return (base_uint256)a + (base_uint256)b; }

11569. inline const uint256 operator-(const uint256& a, const uint256& b)

{ return (base_uint256)a - (base_uint256)b; }

11570. inline int Testuint256AdHoc(vector<string> vArg)


11571. {
11572.

uint256 g(0);

11573.

printf("%s\n", g.ToString().c_str());

11574.

g--; printf("g--\n");

11575.

printf("%s\n", g.ToString().c_str());

11576.

g--; printf("g--\n");

11577.

printf("%s\n", g.ToString().c_str());

11578.

g++; printf("g++\n");

11579.

printf("%s\n", g.ToString().c_str());

11580.

g++; printf("g++\n");

11581.

printf("%s\n", g.ToString().c_str());

11582.

g++; printf("g++\n");

11583.

printf("%s\n", g.ToString().c_str());

11584.

g++; printf("g++\n");

11585.

printf("%s\n", g.ToString().c_str());

11586.

uint256 a(7);

11587.

printf("a=7\n");

11588.

printf("%s\n", a.ToString().c_str());

11589.

uint256 b;

11590.

printf("b undefined\n");

11591.

printf("%s\n", b.ToString().c_str());

11592.

int c = 3;

11593.

a = c;

11594.

a.pn[3] = 15;

11595.

printf("%s\n", a.ToString().c_str());

11596.

uint256 k(c);

11597.

a = 5;

11598.

a.pn[3] = 15;

11599.

printf("%s\n", a.ToString().c_str());

11600.

b = 1;

11601.

b <<= 52;

11602.

a |= b;

11603.

a ^= 0x500;

11604.

printf("a %s\n", a.ToString().c_str());

11605.

a = a | b | (uint256)0x1000;

11606.

printf("a %s\n", a.ToString().c_str());

11607.

printf("b %s\n", b.ToString().c_str());

11608.

a = 0xfffffffe;

11609.

a.pn[4] = 9;

11610.

printf("%s\n", a.ToString().c_str());

11611.

a++;

11612.

printf("%s\n", a.ToString().c_str());

11613.

a++;

11614.

printf("%s\n", a.ToString().c_str());

11615.

a++;

11616.

printf("%s\n", a.ToString().c_str());

11617.

a++;

11618.

printf("%s\n", a.ToString().c_str());

11619.

a--;

11620.

printf("%s\n", a.ToString().c_str());

11621.

a--;

11622.

printf("%s\n", a.ToString().c_str());

11623.

a--;

11624.

printf("%s\n", a.ToString().c_str());

11625.

uint256 d = a--;

11626.

printf("%s\n", d.ToString().c_str());

11627.

printf("%s\n", a.ToString().c_str());

11628.

a--;

11629.

printf("%s\n", a.ToString().c_str());

11630.

a--;

11631.

printf("%s\n", a.ToString().c_str());

11632.

d = a;

11633.

printf("%s\n", d.ToString().c_str());

11634.

for (int i = uint256::WIDTH-1; i >= 0; i--) printf("%08x", d.pn[i]); printf("\n");

11635.

uint256 neg = d;

11636.

neg = ~neg;

11637.

printf("%s\n", neg.ToString().c_str());

11638.

uint256 e = uint256("0xABCDEF123abcdef12345678909832180000011111111");

11639.

printf("\n");

11640.

printf("%s\n", e.ToString().c_str());

11641.

printf("\n");

11642.

uint256 x1 = uint256("0xABCDEF123abcdef12345678909832180000011111111");

11643.

uint256 x2;

11644.

printf("%s\n", x1.ToString().c_str());

11645.

for (int i = 0; i < 270; i += 4)

11646.

11647.

x2 = x1 << i;

11648.

printf("%s\n", x2.ToString().c_str());

11649.

11650.

printf("\n");

11651.

printf("%s\n", x1.ToString().c_str());

11652.

for (int i = 0; i < 270; i += 4)

11653.

11654.

x2 = x1;

11655.

x2 >>= i;

11656.

printf("%s\n", x2.ToString().c_str());

11657.

11658.

for (int i = 0; i < 100; i++)

11659.

11660.

uint256 k = (~uint256(0) >> i);

11661.

printf("%s\n", k.ToString().c_str());

11662.

11663.

for (int i = 0; i < 100; i++)

11664.

11665.

uint256 k = (~uint256(0) << i);

11666.

printf("%s\n", k.ToString().c_str());

11667.

11668.

return (0);

11669. }
11670. #include "headers.h"
11671. bool fDebug = false;
11672. static HANDLE* lock_cs;
11673. void win32_locking_callback(int mode, int type, const char* file, int line)
11674. {
11675.

if (mode & CRYPTO_LOCK)

11676.
11677.

WaitForSingleObject(lock_cs[type], INFINITE);
else

11678.

ReleaseMutex(lock_cs[type]);

11679. }
11680. class CInit
11681. {
11682. public:
11683.

CInit()

11684.

11685.

lock_cs = (HANDLE*)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(HANDLE));

11686.

for (int i = 0; i < CRYPTO_num_locks(); i++)

11687.

lock_cs[i] = CreateMutex(NULL,FALSE,NULL);

11688.

CRYPTO_set_locking_callback(win32_locking_callback);

11689.

RAND_screen();

11690.

RandAddSeed(true);

11691.

11692.

~CInit()

11693.

11694.

CRYPTO_set_locking_callback(NULL);

11695.

for (int i =0 ; i < CRYPTO_num_locks(); i++)

11696.

CloseHandle(lock_cs[i]);

11697.
11698.

OPENSSL_free(lock_cs);
}

11699. }
11700. instance_of_cinit;
11701. void RandAddSeed(bool fPerfmon)
11702. {
11703.

LARGE_INTEGER PerformanceCount;

11704.

QueryPerformanceCounter(&PerformanceCount);

11705.

RAND_add(&PerformanceCount, sizeof(PerformanceCount), 1.5);

11706.

memset(&PerformanceCount, 0, sizeof(PerformanceCount));

11707.

static int64 nLastPerfmon;

11708.

if (fPerfmon || GetTime() > nLastPerfmon + 5 * 60)

11709.

11710.

nLastPerfmon = GetTime();

11711.

unsigned char pdata[250000];

11712.

memset(pdata, 0, sizeof(pdata));

11713.

unsigned long nSize = sizeof(pdata);

11714.

long ret = RegQueryValueEx(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize);

11715.

RegCloseKey(HKEY_PERFORMANCE_DATA);

11716.

if (ret == ERROR_SUCCESS)

11717.

11718.

uint256 hash;

11719.

SHA256(pdata, nSize, (unsigned char*)&hash);

11720.

RAND_add(&hash, sizeof(hash), min(nSize/500.0, (double)sizeof(hash)));

11721.

hash = 0;

11722.

memset(pdata, 0, nSize);

11723.

printf("RandAddSeed() got %d bytes of performance data\n", nSize);

11724.
11725.

}
}

11726. }
11727. int my_snprintf(char* buffer, size_t limit, const char* format, ...)
11728. {

if (limit == 0)

11729.

return 0;

11730.

va_list arg_ptr;

11731.

va_start(arg_ptr, format);

11732.

int ret = _vsnprintf(buffer, limit, format, arg_ptr);

11733.

va_end(arg_ptr);

11734.

if (ret < 0 || ret >= limit)

11735.

11736.

ret = limit - 1;

11737.

buffer[limit-1] = 0;

11738.

11739.

return ret;

11740. }
11741. string strprintf(const char* format, ...)
11742. {
11743.

char buffer[50000];

11744.

char* p = buffer;

11745.

int limit = sizeof(buffer);

11746.

int ret;

11747.

loop

11748.

11749.

va_list arg_ptr;

11750.

va_start(arg_ptr, format);

11751.

ret = _vsnprintf(p, limit, format, arg_ptr);

11752.

va_end(arg_ptr);

11753.

if (ret >= 0 && ret < limit)

11754.

break;

11755.

if (p != buffer)

11756.

delete p;

11757.

limit *= 2;

11758.

p = new char[limit];

11759.

if (p == NULL)

11760.
11761.

throw std::bad_alloc();
}

11762. #ifdef _MSC_VER


11763.

if (p == buffer)

11764.

return string(p, p+ret);

11765. #endif
11766.

string str(p, p+ret);

11767.

if (p != buffer)

11768.
11769.

delete p;
return str;

11770. }
11771. bool error(const char* format, ...)
11772. {
11773.

char buffer[50000];

11774.

int limit = sizeof(buffer);

11775.

va_list arg_ptr;

11776.

va_start(arg_ptr, format);

11777.

int ret = _vsnprintf(buffer, limit, format, arg_ptr);

11778.

va_end(arg_ptr);

11779.

if (ret < 0 || ret >= limit)

11780.

11781.

ret = limit - 1;

11782.

buffer[limit-1] = 0;

11783.

11784.

printf("ERROR: %s\n", buffer);

11785.

return false;

11786. }
11787. void PrintException(std::exception* pex, const char* pszThread)
11788. {
11789.

char pszModule[260];

11790.

pszModule[0] = '\0';

11791.

GetModuleFileName(NULL, pszModule, sizeof(pszModule));

11792.

_strlwr(pszModule);

11793.

char pszMessage[1000];

11794.

if (pex)

11795.

snprintf(pszMessage, sizeof(pszMessage),

11796.
11797.

"EXCEPTION: %s

\n%s

\n%s in %s

\n", typeid(*pex).name(), pex->what(), pszModule, pszThread);

else

11798.

snprintf(pszMessage, sizeof(pszMessage),

11799.

"UNKNOWN EXCEPTION

\n%s in %s

\n", pszModule, pszThread);

11800.

printf("\n\n************************\n%s", pszMessage);

11801.

if (wxTheApp)

11802.
11803.

wxMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR);


throw;

11804. }
11805. void ParseString(const string& str, char c, vector<string>& v)
11806. {
11807.

unsigned int i1 = 0;

11808.

unsigned int i2;

11809.

do

11810.

11811.

i2 = str.find(c, i1);

11812.

v.push_back(str.substr(i1, i2-i1));

11813.

i1 = i2+1;

11814.

11815.

while (i2 != str.npos);

11816. }
11817. string FormatMoney(int64 n, bool fPlus)
11818. {
11819.

n /= CENT;

11820.

string str = strprintf("%I64d.%02I64d", (n > 0 ? n : -n)/100, (n > 0 ? n : -n)%100);

11821.

for (int i = 6; i < str.size(); i += 4)

11822.

if (isdigit(str[str.size() - i - 1]))

11823.
11824.

str.insert(str.size() - i, 1, ',');
if (n < 0)

11825.
11826.

str.insert((unsigned int)0, 1, '-');


else if (fPlus && n > 0)

11827.
11828.

str.insert((unsigned int)0, 1, '+');


return str;

11829. }
11830. bool ParseMoney(const char* pszIn, int64& nRet)
11831. {
11832.

string strWhole;

11833.

int64 nCents = 0;

11834.

const char* p = pszIn;

11835.

while (isspace(*p))

11836.

p++;

11837.

for (; *p; p++)

11838.

11839.

if (*p == ',' && p > pszIn && isdigit(p[-1]) && isdigit(p[1]) && isdigit(p[2]) && isdigit(p[3]) && !isdigit(p[4]))

11840.

continue;

11841.

if (*p == '.')

11842.

11843.

p++;

11844.

if (!isdigit(p[0]) || !isdigit(p[1]))

11845.

return false;

11846.

nCents = atoi64(p);

11847.

if (nCents < 0 || nCents > 99)

11848.

return false;

11849.

p += 2;

11850.

break;

11851.

11852.

if (isspace(*p))

11853.

break;

11854.

if (!isdigit(*p))

11855.

return false;

11856.

strWhole.insert(strWhole.end(), *p);

11857.

11858.

for (; *p; p++)

11859.

if (!isspace(*p))

11860.
11861.
11862.

return false;
if (strWhole.size() > 17)
return false;

11863.

int64 nWhole = atoi64(strWhole);

11864.

int64 nValue = nWhole * 100 + nCents;

11865.

if (nValue / 100 != nWhole)

11866.

return false;

11867.

nValue *= CENT;

11868.

nRet = nValue;

11869.

return true;

11870. }
11871. bool FileExists(const char* psz)
11872. {
11873. #ifdef WIN32
11874.

return GetFileAttributes(psz) != -1;

11875. #else
11876.

return access(psz, 0) != -1;

11877. #endif
11878. }
11879. int GetFilesize(FILE* file)
11880. {
11881.

int nSavePos = ftell(file);

11882.

int nFilesize = -1;

11883.

if (fseek(file, 0, SEEK_END) == 0)

11884.

nFilesize = ftell(file);

11885.

fseek(file, nSavePos, SEEK_SET);

11886.

return nFilesize;

11887. }
11888. uint64 GetRand(uint64 nMax)
11889. {
11890.
11891.

if (nMax == 0)
return 0;

11892.

uint64 nRange = (_UI64_MAX / nMax) * nMax;

11893.

uint64 nRand = 0;

11894.

do

11895.

RAND_bytes((unsigned char*)&nRand, sizeof(nRand));

11896.

while (nRand >= nRange);

11897.

return (nRand % nMax);

11898. }
11899. int64 GetTime()
11900. {
11901.

return time(NULL);

11902. }
11903. static int64 nTimeOffset = 0;
11904. int64 GetAdjustedTime()
11905. {
11906.

return GetTime() + nTimeOffset;

11907. }
11908.
11909. void AddTimeData(unsigned int ip, int64 nTime)
11910. {
11911.

int64 nOffsetSample = nTime - GetTime();

11912.

static set<unsigned int> setKnown;

11913.

if (!setKnown.insert(ip).second)

11914.

return;

11915.

static vector<int64> vTimeOffsets;

11916.

if (vTimeOffsets.empty())

11917.

vTimeOffsets.push_back(0);

11918.

vTimeOffsets.push_back(nOffsetSample);

11919.

printf("Added time data, samples %d, ip %08x, offset %+I64d (%+I64d minutes)\n", vTimeOffsets.size(), ip, vTimeOffsets.back(),
vTimeOffsets.back()/60);

11920.

if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1)

11921.

11922.

sort(vTimeOffsets.begin(), vTimeOffsets.end());

11923.

int64 nMedian = vTimeOffsets[vTimeOffsets.size()/2];

11924.

nTimeOffset = nMedian;

11925.

if ((nMedian > 0 ? nMedian : -nMedian) > 5 * 60)

11926.

11927.

11928.

foreach(int64 n, vTimeOffsets)

11929.

printf("%+I64d ", n);

11930.
11931.

printf("| nTimeOffset = %+I64d (%+I64d minutes)\n", nTimeOffset, nTimeOffset/60);


}

11932. }
11933. #if defined(_MSC_VER) || defined(__BORLANDC__)
11934. typedef __int64 int64;
11935. typedef unsigned __int64 uint64;
11936. #else
11937. typedef long long int64;
11938. typedef unsigned long long uint64;
11939. #endif
11940. #if defined(_MSC_VER) && _MSC_VER < 1300
11941. #define for if (false) ; else for
11942. #endif
11943. #ifndef _MSC_VER
11944. #define __forceinline inline
11945. #endif
11946. #define foreach
11947. #define loop

BOOST_FOREACH
for (;;)

11948. #define BEGIN(a)

((char*)&(a))

11949. #define END(a)

((char*)&((&(a))[1]))

11950. #define UBEGIN(a)

((unsigned char*)&(a))

11951. #define UEND(a)

((unsigned char*)&((&(a))[1]))

11952. #define ARRAYLEN(array)

(sizeof(array)/sizeof((array)[0]))

11953. #ifdef _WINDOWS


11954. #define printf

OutputDebugStringF

11955. #endif
11956. #ifdef snprintf
11957. #undef snprintf
11958. #endif
11959. #define snprintf my_snprintf
11960. #ifndef PRId64
11961. #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MSVCRT__)
11962. #define PRId64 "I64d"
11963. #define PRIu64 "I64u"
11964. #define PRIx64 "I64x"
11965. #else
11966. #define PRId64 "lld"
11967. #define PRIu64 "llu"
11968. #define PRIx64 "llx"
11969. #endif
11970. #endif
11971. #define PAIRTYPE(t1, t2)
11972. template<typename T>
11973. inline T& REF(const T& val)
11974. {
11975.
11976. }

return (T&)val;

pair<t1, t2>

11977. extern bool fDebug;


11978. void RandAddSeed(bool fPerfmon=false);
11979. int my_snprintf(char* buffer, size_t limit, const char* format, ...);
11980. string strprintf(const char* format, ...);
11981. bool error(const char* format, ...);
11982. void PrintException(std::exception* pex, const char* pszThread);
11983. void ParseString(const string& str, char c, vector<string>& v);
11984. string FormatMoney(int64 n, bool fPlus=false);
11985. bool ParseMoney(const char* pszIn, int64& nRet);
11986. bool FileExists(const char* psz);
11987. int GetFilesize(FILE* file);
11988. uint64 GetRand(uint64 nMax);
11989. int64 GetTime();
11990. int64 GetAdjustedTime();
11991. void AddTimeData(unsigned int ip, int64 nTime);
11992. class CCriticalSection
11993. {
11994. protected:
11995.

CRITICAL_SECTION cs;

11996. public:
11997.

char* pszFile;

11998.

int nLine;

11999.

explicit CCriticalSection() { InitializeCriticalSection(&cs); }

12000.

~CCriticalSection() { DeleteCriticalSection(&cs); }

12001.

void Enter() { EnterCriticalSection(&cs); }

12002.

void Leave() { LeaveCriticalSection(&cs); }

12003.

bool TryEnter() { return TryEnterCriticalSection(&cs); }

12004.

CRITICAL_SECTION* operator&() { return &cs; }

12005. };
12006. class CCriticalBlock
12007. {
12008. protected:
12009.

CRITICAL_SECTION* pcs;

12010. public:
12011.

CCriticalBlock(CRITICAL_SECTION& csIn) { pcs = &csIn; EnterCriticalSection(pcs); }

12012.

CCriticalBlock(CCriticalSection& csIn) { pcs = &csIn; EnterCriticalSection(pcs); }

12013.

~CCriticalBlock() { LeaveCriticalSection(pcs); }

12014. };
12015. #define CRITICAL_BLOCK(cs)
12016.

for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by CRITICAL_BLOCK!", !fcriticalblockonce)), fcriticalblockonce=false) \

12017.

for (CCriticalBlock criticalblock(cs); fcriticalblockonce && (cs.pszFile=__FILE__, cs.nLine=__LINE__, true); fcriticalblockonce=false,


cs.pszFile=NULL, cs.nLine=0)

12018. class CTryCriticalBlock


12019. {
12020. protected:
12021.

CRITICAL_SECTION* pcs;

12022. public:
12023.

CTryCriticalBlock(CRITICAL_SECTION& csIn) { pcs = (TryEnterCriticalSection(&csIn) ? &csIn : NULL); }

12024.

CTryCriticalBlock(CCriticalSection& csIn) { pcs = (TryEnterCriticalSection(&csIn) ? &csIn : NULL); }

12025.

~CTryCriticalBlock() { if (pcs) LeaveCriticalSection(pcs); }

12026.

bool Entered() { return pcs != NULL; }

12027. };
12028. #define TRY_CRITICAL_BLOCK(cs)
12029.

for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by TRY_CRITICAL_BLOCK!", !fcriticalblockonce)),


fcriticalblockonce=false) \

12030.

for (CTryCriticalBlock criticalblock(cs); fcriticalblockonce && (fcriticalblockonce = criticalblock.Entered()) && (cs.pszFile=__FILE__,


cs.nLine=__LINE__, true); fcriticalblockonce=false, cs.pszFile=NULL, cs.nLine=0)

12031. inline string i64tostr(int64 n)


12032. {
12033.

return strprintf("%"PRId64, n);

12034. }
12035. inline string itostr(int n)
12036. {
12037.

return strprintf("%d", n);

12038. }
12039. inline int64 atoi64(const char* psz)
12040. {
12041. #ifdef _MSC_VER
12042.

return _atoi64(psz);

12043. #else
12044.

return strtoll(psz, NULL, 10);

12045. #endif
12046. }
12047. inline int64 atoi64(const string& str)
12048. {
12049. #ifdef _MSC_VER
12050.

return _atoi64(str.c_str());

12051. #else
12052.

return strtoll(str.c_str(), NULL, 10);

12053. #endif
12054. }
12055. inline int atoi(const string& str)
12056. {

12057.

return atoi(str.c_str());

12058. }
12059. inline int roundint(double d)
12060. {
12061.

return (int)(d > 0 ? d + 0.5 : d - 0.5);

12062. }
12063. template<typename T>
12064. string HexStr(const T itbegin, const T itend, bool fSpaces=true)
12065. {
12066.

const unsigned char* pbegin = (const unsigned char*)&itbegin[0];

12067.

const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]);

12068.

string str;

12069.

for (const unsigned char* p = pbegin; p != pend; p++)

12070.
12071.

str += strprintf((fSpaces && p != pend-1 ? "%02x " : "%02x"), *p);


return str;

12072. }
12073. template<typename T>
12074. string HexNumStr(const T itbegin, const T itend, bool f0x=true)
12075. {
12076.

const unsigned char* pbegin = (const unsigned char*)&itbegin[0];

12077.

const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]);

12078.

string str = (f0x ? "0x" : "");

12079.

for (const unsigned char* p = pend-1; p >= pbegin; p--)

12080.
12081.

str += strprintf("%02X", *p);


return str;

12082. }
12083. template<typename T>
12084. void PrintHex(const T pbegin, const T pend, const char* pszFormat="%s", bool fSpaces=true)
12085. {
12086.

printf(pszFormat, HexStr(pbegin, pend, fSpaces).c_str());

12087. }
12088. inline int OutputDebugStringF(const char* pszFormat, ...)
12089. {
12090. #ifdef __WXDEBUG__
12091.

FILE* fileout = fopen("debug.log", "a");

12092.

if (fileout)

12093.

12094.

va_list arg_ptr;

12095.

va_start(arg_ptr, pszFormat);

12096.

vfprintf(fileout, pszFormat, arg_ptr);

12097.

va_end(arg_ptr);

12098.

fclose(fileout);

12099.

12100.

static CCriticalSection cs_OutputDebugStringF;

12101.

CRITICAL_BLOCK(cs_OutputDebugStringF)

12102.

12103.

static char pszBuffer[50000];

12104.

static char* pend;

12105.

if (pend == NULL)

12106.

pend = pszBuffer;

12107.

va_list arg_ptr;

12108.

va_start(arg_ptr, pszFormat);

12109.

int limit = END(pszBuffer) - pend - 2;

12110.

int ret = _vsnprintf(pend, limit, pszFormat, arg_ptr);

12111.

va_end(arg_ptr);

12112.

if (ret < 0 || ret >= limit)

12113.

12114.

pend = END(pszBuffer) - 2;

12115.

*pend++ = '\n';

12116.

12117.

else

12118.

pend += ret;

12119.

*pend = '\0';

12120.

char* p1 = pszBuffer;

12121.

char* p2;

12122.

while (p2 = strchr(p1, '\n'))

12123.

12124.

p2++;

12125.

char c = *p2;

12126.

*p2 = '\0';

12127.

OutputDebugString(p1);

12128.

*p2 = c;

12129.

p1 = p2;

12130.

12131.

if (p1 != pszBuffer)

12132.

memmove(pszBuffer, p1, pend - p1 + 1);

12133.

pend -= (p1 - pszBuffer);

12134.
12135.

return ret;
}

12136. #endif
12137.

if (!wxTheApp)

12138.

12139.

va_list arg_ptr;

12140.

va_start(arg_ptr, pszFormat);

12141.

vprintf(pszFormat, arg_ptr);

12142.

va_end(arg_ptr);

12143.

12144.

return 0;

12145. }
12146. inline void heapchk()
12147. {
12148.

if (_heapchk() != _HEAPOK)

12149.

DebugBreak();

12150. }
12151. #define IMPLEMENT_RANDOMIZE_STACK(ThreadFn)
12152.

12153.

static char nLoops;

12154.

if (nLoops <= 0)

12155.

if (nLoops-- > 1)

12157.

\
\
\

12158.

ThreadFn;

12159.

return;

12161.

\
\

nLoops = GetRand(50) + 1;

12156.

12160.

\
\

12162. #define CATCH_PRINT_EXCEPTION(pszFn)


12163.

catch (std::exception& e) {

12164.
12165.

PrintException(&e, (pszFn));
} catch (...) {

12166.
12167.

\
\

PrintException(NULL, (pszFn)); \
}

12168. template<typename T1>


12169. inline uint256 Hash(const T1 pbegin, const T1 pend)
12170. {
12171.

uint256 hash1;

12172.

SHA256((unsigned char*)&pbegin[0], (pend - pbegin) * sizeof(pbegin[0]), (unsigned char*)&hash1);

12173.

uint256 hash2;

12174.

SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);

12175.

return hash2;

12176. }
12177. template<typename T1, typename T2>
12178. inline uint256 Hash(const T1 p1begin, const T1 p1end,
12179.

const T2 p2begin, const T2 p2end)

12180. {
12181.

uint256 hash1;

12182.

SHA256_CTX ctx;

12183.

SHA256_Init(&ctx);

12184.

SHA256_Update(&ctx, (unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0]));

12185.

SHA256_Update(&ctx, (unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0]));

12186.

SHA256_Final((unsigned char*)&hash1, &ctx);

12187.

uint256 hash2;

12188.

SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);

12189.

return hash2;

12190. }
12191. template<typename T1, typename T2, typename T3>
12192. inline uint256 Hash(const T1 p1begin, const T1 p1end,
12193.

const T2 p2begin, const T2 p2end,

12194.

const T3 p3begin, const T3 p3end)

12195. {
12196.

uint256 hash1;

12197.

SHA256_CTX ctx;

12198.

SHA256_Init(&ctx);

12199.

SHA256_Update(&ctx, (unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0]));

12200.

SHA256_Update(&ctx, (unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0]));

12201.

SHA256_Update(&ctx, (unsigned char*)&p3begin[0], (p3end - p3begin) * sizeof(p3begin[0]));

12202.

SHA256_Final((unsigned char*)&hash1, &ctx);

12203.

uint256 hash2;

12204.

SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);

12205.

return hash2;

12206. }
12207. template<typename T>
12208. uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=VERSION)
12209. {
12210.

CDataStream ss(nType, nVersion);

12211.

ss.reserve(10000);

12212.

ss << obj;

12213.

return Hash(ss.begin(), ss.end());

12214. }
12215. inline uint160 Hash160(const vector<unsigned char>& vch)
12216. {
12217.

uint256 hash1;

12218.

SHA256(&vch[0], vch.size(), (unsigned char*)&hash1);

12219.

uint160 hash2;

12220.

RIPEMD160((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);

12221.

return hash2;

12222. }

RAW Paste Data

create a new version of this paste

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;
vector<unsigned char> vchTmp(pend-pbegin+1, 0);
reverse_copy(pbegin, pend, vchTmp.begin());
CBigNum bn;
bn.setvch(vchTmp);
string str;
str.reserve((pend - pbegin) * 138 / 100 + 1);
CBigNum dv;
CBigNum rem;
while (bn > bn0)
Pastebin.com
Tools & Applications
{

iPhone/iPad
Windows
Firefox
if (!BN_div(&dv, &rem,
&bn, &bn58, pctx))

Chrome

WebOS

Android

Mac

Opera

Click.to

throw bignum_error("EncodeBase58 : BN_div failed");


bn = dv;

create new paste | api | trends | users | faq | tools | privacy | cookies policy | contact | stats | go pro

unsigned int c = rem.getulong();

Follow us: pastebin on facebook | pastebin on twitter | pastebin in the news

str += pszBase58[c];
}

Dedicated Server Hosting by Steadfast


Pastebin v3.11 rendered in: 0.049 seconds

for (const unsigned char* p = pbegin; p < pend && *p == 0; p++)


str += pszBase58[0];

UNIX

WinPhone

You might also like