tree checksum vpatch file split hunks

all signers: mod6

antecedents:

press order:

genesismod6

patch:

-
+ 6654C7489C311585D7D327DEA2E6605288709195898F48F1E6747DC5934AE34A20BFBE89F0AC41F878AFEA226A7F9DA2B04C3E0672BD05F677506A2219738E97
bitcoin/.gitignore
(0 . 0)(1 . 21)
5 src/*.exe
6 src/bitcoin
7 src/bitcoind
8 .*.swp
9 *.*~*
10 *.bak
11 *.rej
12 *.orig
13 *.o
14 *.patch
15 .bitcoin
16 #compilation and Qt preprocessor part
17 *.qm
18 Makefile
19 bitcoin-qt
20 #resources cpp
21 qrc_*.cpp
22 #qt creator
23 *.pro.user
24 #mac specific
25 .DS_Store
-
+ EB63B0235E5D23876F57ED4EB3307FA00792E5706D83A55ADF9F0997DE434470C3ACE8D16B146FF6EF0C42177C53A748C15BC63558E6F89DB5276C5419FBACFE
bitcoin/COPYING
(0 . 0)(1 . 19)
30 Copyright (c) 2009-2012 Bitcoin Developers
31
32 Permission is hereby granted, free of charge, to any person obtaining a copy
33 of this software and associated documentation files (the "Software"), to deal
34 in the Software without restriction, including without limitation the rights
35 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
36 copies of the Software, and to permit persons to whom the Software is
37 furnished to do so, subject to the following conditions:
38
39 The above copyright notice and this permission notice shall be included in
40 all copies or substantial portions of the Software.
41
42 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
43 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
44 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
45 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
46 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
47 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
48 THE SOFTWARE.
-
+ C9414DD278719A028B904826086E3D241AC1402BBCBAF265C6E03B2DFE0451833A8E6CC11CDCC90E67E64C41056C9A2725CEC1F0A6E251A0EF76835BA3D173B4
bitcoin/src/base58.h
(0 . 0)(1 . 323)
53 // Copyright (c) 2009-2010 Satoshi Nakamoto
54 // Copyright (c) 2011 The Bitcoin Developers
55 // Distributed under the MIT/X11 software license, see the accompanying
56 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
57
58
59 //
60 // Why base-58 instead of standard base-64 encoding?
61 // - Don't want 0OIl characters that look the same in some fonts and
62 // could be used to create visually identical looking account numbers.
63 // - A string with non-alphanumeric characters is not as easily accepted as an account number.
64 // - E-mail usually won't line-break if there's no punctuation to break at.
65 // - Doubleclicking selects the whole number as one word if it's all alphanumeric.
66 //
67 #ifndef BITCOIN_BASE58_H
68 #define BITCOIN_BASE58_H
69
70 #include <string>
71 #include <vector>
72 #include "bignum.h"
73
74 static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
75
76 // Encode a byte sequence as a base58-encoded string
77 inline std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend)
78 {
79 CAutoBN_CTX pctx;
80 CBigNum bn58 = 58;
81 CBigNum bn0 = 0;
82
83 // Convert big endian data to little endian
84 // Extra zero at the end make sure bignum will interpret as a positive number
85 std::vector<unsigned char> vchTmp(pend-pbegin+1, 0);
86 reverse_copy(pbegin, pend, vchTmp.begin());
87
88 // Convert little endian data to bignum
89 CBigNum bn;
90 bn.setvch(vchTmp);
91
92 // Convert bignum to std::string
93 std::string str;
94 // Expected size increase from base58 conversion is approximately 137%
95 // use 138% to be safe
96 str.reserve((pend - pbegin) * 138 / 100 + 1);
97 CBigNum dv;
98 CBigNum rem;
99 while (bn > bn0)
100 {
101 if (!BN_div(&dv, &rem, &bn, &bn58, pctx))
102 throw bignum_error("EncodeBase58 : BN_div failed");
103 bn = dv;
104 unsigned int c = rem.getulong();
105 str += pszBase58[c];
106 }
107
108 // Leading zeroes encoded as base58 zeros
109 for (const unsigned char* p = pbegin; p < pend && *p == 0; p++)
110 str += pszBase58[0];
111
112 // Convert little endian std::string to big endian
113 reverse(str.begin(), str.end());
114 return str;
115 }
116
117 // Encode a byte vector as a base58-encoded string
118 inline std::string EncodeBase58(const std::vector<unsigned char>& vch)
119 {
120 return EncodeBase58(&vch[0], &vch[0] + vch.size());
121 }
122
123 // Decode a base58-encoded string psz into byte vector vchRet
124 // returns true if decoding is succesful
125 inline bool DecodeBase58(const char* psz, std::vector<unsigned char>& vchRet)
126 {
127 CAutoBN_CTX pctx;
128 vchRet.clear();
129 CBigNum bn58 = 58;
130 CBigNum bn = 0;
131 CBigNum bnChar;
132 while (isspace(*psz))
133 psz++;
134
135 // Convert big endian string to bignum
136 for (const char* p = psz; *p; p++)
137 {
138 const char* p1 = strchr(pszBase58, *p);
139 if (p1 == NULL)
140 {
141 while (isspace(*p))
142 p++;
143 if (*p != '\0')
144 return false;
145 break;
146 }
147 bnChar.setulong(p1 - pszBase58);
148 if (!BN_mul(&bn, &bn, &bn58, pctx))
149 throw bignum_error("DecodeBase58 : BN_mul failed");
150 bn += bnChar;
151 }
152
153 // Get bignum as little endian data
154 std::vector<unsigned char> vchTmp = bn.getvch();
155
156 // Trim off sign byte if present
157 if (vchTmp.size() >= 2 && vchTmp.end()[-1] == 0 && vchTmp.end()[-2] >= 0x80)
158 vchTmp.erase(vchTmp.end()-1);
159
160 // Restore leading zeros
161 int nLeadingZeros = 0;
162 for (const char* p = psz; *p == pszBase58[0]; p++)
163 nLeadingZeros++;
164 vchRet.assign(nLeadingZeros + vchTmp.size(), 0);
165
166 // Convert little endian data to big endian
167 reverse_copy(vchTmp.begin(), vchTmp.end(), vchRet.end() - vchTmp.size());
168 return true;
169 }
170
171 // Decode a base58-encoded string str into byte vector vchRet
172 // returns true if decoding is succesful
173 inline bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet)
174 {
175 return DecodeBase58(str.c_str(), vchRet);
176 }
177
178
179
180
181 // Encode a byte vector to a base58-encoded string, including checksum
182 inline std::string EncodeBase58Check(const std::vector<unsigned char>& vchIn)
183 {
184 // add 4-byte hash check to the end
185 std::vector<unsigned char> vch(vchIn);
186 uint256 hash = Hash(vch.begin(), vch.end());
187 vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4);
188 return EncodeBase58(vch);
189 }
190
191 // Decode a base58-encoded string psz that includes a checksum, into byte vector vchRet
192 // returns true if decoding is succesful
193 inline bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet)
194 {
195 if (!DecodeBase58(psz, vchRet))
196 return false;
197 if (vchRet.size() < 4)
198 {
199 vchRet.clear();
200 return false;
201 }
202 uint256 hash = Hash(vchRet.begin(), vchRet.end()-4);
203 if (memcmp(&hash, &vchRet.end()[-4], 4) != 0)
204 {
205 vchRet.clear();
206 return false;
207 }
208 vchRet.resize(vchRet.size()-4);
209 return true;
210 }
211
212 // Decode a base58-encoded string str that includes a checksum, into byte vector vchRet
213 // returns true if decoding is succesful
214 inline bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet)
215 {
216 return DecodeBase58Check(str.c_str(), vchRet);
217 }
218
219
220
221
222
223 // Base class for all base58-encoded data
224 class CBase58Data
225 {
226 protected:
227 // the version byte
228 unsigned char nVersion;
229
230 // the actually encoded data
231 std::vector<unsigned char> vchData;
232
233 CBase58Data()
234 {
235 nVersion = 0;
236 vchData.clear();
237 }
238
239 ~CBase58Data()
240 {
241 // zero the memory, as it may contain sensitive data
242 if (!vchData.empty())
243 memset(&vchData[0], 0, vchData.size());
244 }
245
246 void SetData(int nVersionIn, const void* pdata, size_t nSize)
247 {
248 nVersion = nVersionIn;
249 vchData.resize(nSize);
250 if (!vchData.empty())
251 memcpy(&vchData[0], pdata, nSize);
252 }
253
254 void SetData(int nVersionIn, const unsigned char *pbegin, const unsigned char *pend)
255 {
256 SetData(nVersionIn, (void*)pbegin, pend - pbegin);
257 }
258
259 public:
260 bool SetString(const char* psz)
261 {
262 std::vector<unsigned char> vchTemp;
263 DecodeBase58Check(psz, vchTemp);
264 if (vchTemp.empty())
265 {
266 vchData.clear();
267 nVersion = 0;
268 return false;
269 }
270 nVersion = vchTemp[0];
271 vchData.resize(vchTemp.size() - 1);
272 if (!vchData.empty())
273 memcpy(&vchData[0], &vchTemp[1], vchData.size());
274 memset(&vchTemp[0], 0, vchTemp.size());
275 return true;
276 }
277
278 bool SetString(const std::string& str)
279 {
280 return SetString(str.c_str());
281 }
282
283 std::string ToString() const
284 {
285 std::vector<unsigned char> vch(1, nVersion);
286 vch.insert(vch.end(), vchData.begin(), vchData.end());
287 return EncodeBase58Check(vch);
288 }
289
290 int CompareTo(const CBase58Data& b58) const
291 {
292 if (nVersion < b58.nVersion) return -1;
293 if (nVersion > b58.nVersion) return 1;
294 if (vchData < b58.vchData) return -1;
295 if (vchData > b58.vchData) return 1;
296 return 0;
297 }
298
299 bool operator==(const CBase58Data& b58) const { return CompareTo(b58) == 0; }
300 bool operator<=(const CBase58Data& b58) const { return CompareTo(b58) <= 0; }
301 bool operator>=(const CBase58Data& b58) const { return CompareTo(b58) >= 0; }
302 bool operator< (const CBase58Data& b58) const { return CompareTo(b58) < 0; }
303 bool operator> (const CBase58Data& b58) const { return CompareTo(b58) > 0; }
304 };
305
306 // base58-encoded bitcoin addresses
307 // Addresses have version 0 or 111 (testnet)
308 // The data vector contains RIPEMD160(SHA256(pubkey)), where pubkey is the serialized public key
309 class CBitcoinAddress : public CBase58Data
310 {
311 public:
312 bool SetHash160(const uint160& hash160)
313 {
314 SetData(fTestNet ? 111 : 0, &hash160, 20);
315 return true;
316 }
317
318 bool SetPubKey(const std::vector<unsigned char>& vchPubKey)
319 {
320 return SetHash160(Hash160(vchPubKey));
321 }
322
323 bool IsValid() const
324 {
325 int nExpectedSize = 20;
326 bool fExpectTestNet = false;
327 switch(nVersion)
328 {
329 case 0:
330 break;
331
332 case 111:
333 fExpectTestNet = true;
334 break;
335
336 default:
337 return false;
338 }
339 return fExpectTestNet == fTestNet && vchData.size() == nExpectedSize;
340 }
341
342 CBitcoinAddress()
343 {
344 }
345
346 CBitcoinAddress(uint160 hash160In)
347 {
348 SetHash160(hash160In);
349 }
350
351 CBitcoinAddress(const std::vector<unsigned char>& vchPubKey)
352 {
353 SetPubKey(vchPubKey);
354 }
355
356 CBitcoinAddress(const std::string& strAddress)
357 {
358 SetString(strAddress);
359 }
360
361 CBitcoinAddress(const char* pszAddress)
362 {
363 SetString(pszAddress);
364 }
365
366 uint160 GetHash160() const
367 {
368 assert(vchData.size() == 20);
369 uint160 hash160;
370 memcpy(&hash160, &vchData[0], 20);
371 return hash160;
372 }
373 };
374
375 #endif
-
+ 50F0E628773C067FFD2E796319FED525C520B5F97640AAFD2EE87B4834A018ED48772E8E347E088A4566D6E2CAC9D836E2ED4A607457589635B6EB46E928D055
bitcoin/src/bignum.h
(0 . 0)(1 . 538)
380 // Copyright (c) 2009-2010 Satoshi Nakamoto
381 // Copyright (c) 2011 The Bitcoin developers
382 // Distributed under the MIT/X11 software license, see the accompanying
383 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
384 #ifndef BITCOIN_BIGNUM_H
385 #define BITCOIN_BIGNUM_H
386
387 #include <stdexcept>
388 #include <vector>
389 #include <openssl/bn.h>
390
391 #include "util.h"
392
393 class bignum_error : public std::runtime_error
394 {
395 public:
396 explicit bignum_error(const std::string& str) : std::runtime_error(str) {}
397 };
398
399
400
401 class CAutoBN_CTX
402 {
403 protected:
404 BN_CTX* pctx;
405 BN_CTX* operator=(BN_CTX* pnew) { return pctx = pnew; }
406
407 public:
408 CAutoBN_CTX()
409 {
410 pctx = BN_CTX_new();
411 if (pctx == NULL)
412 throw bignum_error("CAutoBN_CTX : BN_CTX_new() returned NULL");
413 }
414
415 ~CAutoBN_CTX()
416 {
417 if (pctx != NULL)
418 BN_CTX_free(pctx);
419 }
420
421 operator BN_CTX*() { return pctx; }
422 BN_CTX& operator*() { return *pctx; }
423 BN_CTX** operator&() { return &pctx; }
424 bool operator!() { return (pctx == NULL); }
425 };
426
427
428
429 class CBigNum : public BIGNUM
430 {
431 public:
432 CBigNum()
433 {
434 BN_init(this);
435 }
436
437 CBigNum(const CBigNum& b)
438 {
439 BN_init(this);
440 if (!BN_copy(this, &b))
441 {
442 BN_clear_free(this);
443 throw bignum_error("CBigNum::CBigNum(const CBigNum&) : BN_copy failed");
444 }
445 }
446
447 CBigNum& operator=(const CBigNum& b)
448 {
449 if (!BN_copy(this, &b))
450 throw bignum_error("CBigNum::operator= : BN_copy failed");
451 return (*this);
452 }
453
454 ~CBigNum()
455 {
456 BN_clear_free(this);
457 }
458
459 CBigNum(char n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
460 CBigNum(short n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
461 CBigNum(int n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
462 CBigNum(long n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
463 CBigNum(int64 n) { BN_init(this); setint64(n); }
464 CBigNum(unsigned char n) { BN_init(this); setulong(n); }
465 CBigNum(unsigned short n) { BN_init(this); setulong(n); }
466 CBigNum(unsigned int n) { BN_init(this); setulong(n); }
467 CBigNum(unsigned long n) { BN_init(this); setulong(n); }
468 CBigNum(uint64 n) { BN_init(this); setuint64(n); }
469 explicit CBigNum(uint256 n) { BN_init(this); setuint256(n); }
470
471 explicit CBigNum(const std::vector<unsigned char>& vch)
472 {
473 BN_init(this);
474 setvch(vch);
475 }
476
477 void setulong(unsigned long n)
478 {
479 if (!BN_set_word(this, n))
480 throw bignum_error("CBigNum conversion from unsigned long : BN_set_word failed");
481 }
482
483 unsigned long getulong() const
484 {
485 return BN_get_word(this);
486 }
487
488 unsigned int getuint() const
489 {
490 return BN_get_word(this);
491 }
492
493 int getint() const
494 {
495 unsigned long n = BN_get_word(this);
496 if (!BN_is_negative(this))
497 return (n > INT_MAX ? INT_MAX : n);
498 else
499 return (n > INT_MAX ? INT_MIN : -(int)n);
500 }
501
502 void setint64(int64 n)
503 {
504 unsigned char pch[sizeof(n) + 6];
505 unsigned char* p = pch + 4;
506 bool fNegative = false;
507 if (n < (int64)0)
508 {
509 n = -n;
510 fNegative = true;
511 }
512 bool fLeadingZeroes = true;
513 for (int i = 0; i < 8; i++)
514 {
515 unsigned char c = (n >> 56) & 0xff;
516 n <<= 8;
517 if (fLeadingZeroes)
518 {
519 if (c == 0)
520 continue;
521 if (c & 0x80)
522 *p++ = (fNegative ? 0x80 : 0);
523 else if (fNegative)
524 c |= 0x80;
525 fLeadingZeroes = false;
526 }
527 *p++ = c;
528 }
529 unsigned int nSize = p - (pch + 4);
530 pch[0] = (nSize >> 24) & 0xff;
531 pch[1] = (nSize >> 16) & 0xff;
532 pch[2] = (nSize >> 8) & 0xff;
533 pch[3] = (nSize) & 0xff;
534 BN_mpi2bn(pch, p - pch, this);
535 }
536
537 void setuint64(uint64 n)
538 {
539 unsigned char pch[sizeof(n) + 6];
540 unsigned char* p = pch + 4;
541 bool fLeadingZeroes = true;
542 for (int i = 0; i < 8; i++)
543 {
544 unsigned char c = (n >> 56) & 0xff;
545 n <<= 8;
546 if (fLeadingZeroes)
547 {
548 if (c == 0)
549 continue;
550 if (c & 0x80)
551 *p++ = 0;
552 fLeadingZeroes = false;
553 }
554 *p++ = c;
555 }
556 unsigned int nSize = p - (pch + 4);
557 pch[0] = (nSize >> 24) & 0xff;
558 pch[1] = (nSize >> 16) & 0xff;
559 pch[2] = (nSize >> 8) & 0xff;
560 pch[3] = (nSize) & 0xff;
561 BN_mpi2bn(pch, p - pch, this);
562 }
563
564 void setuint256(uint256 n)
565 {
566 unsigned char pch[sizeof(n) + 6];
567 unsigned char* p = pch + 4;
568 bool fLeadingZeroes = true;
569 unsigned char* pbegin = (unsigned char*)&n;
570 unsigned char* psrc = pbegin + sizeof(n);
571 while (psrc != pbegin)
572 {
573 unsigned char c = *(--psrc);
574 if (fLeadingZeroes)
575 {
576 if (c == 0)
577 continue;
578 if (c & 0x80)
579 *p++ = 0;
580 fLeadingZeroes = false;
581 }
582 *p++ = c;
583 }
584 unsigned int nSize = p - (pch + 4);
585 pch[0] = (nSize >> 24) & 0xff;
586 pch[1] = (nSize >> 16) & 0xff;
587 pch[2] = (nSize >> 8) & 0xff;
588 pch[3] = (nSize >> 0) & 0xff;
589 BN_mpi2bn(pch, p - pch, this);
590 }
591
592 uint256 getuint256()
593 {
594 unsigned int nSize = BN_bn2mpi(this, NULL);
595 if (nSize < 4)
596 return 0;
597 std::vector<unsigned char> vch(nSize);
598 BN_bn2mpi(this, &vch[0]);
599 if (vch.size() > 4)
600 vch[4] &= 0x7f;
601 uint256 n = 0;
602 for (int i = 0, j = vch.size()-1; i < sizeof(n) && j >= 4; i++, j--)
603 ((unsigned char*)&n)[i] = vch[j];
604 return n;
605 }
606
607 void setvch(const std::vector<unsigned char>& vch)
608 {
609 std::vector<unsigned char> vch2(vch.size() + 4);
610 unsigned int nSize = vch.size();
611 // BIGNUM's byte stream format expects 4 bytes of
612 // big endian size data info at the front
613 vch2[0] = (nSize >> 24) & 0xff;
614 vch2[1] = (nSize >> 16) & 0xff;
615 vch2[2] = (nSize >> 8) & 0xff;
616 vch2[3] = (nSize >> 0) & 0xff;
617 // swap data to big endian
618 reverse_copy(vch.begin(), vch.end(), vch2.begin() + 4);
619 BN_mpi2bn(&vch2[0], vch2.size(), this);
620 }
621
622 std::vector<unsigned char> getvch() const
623 {
624 unsigned int nSize = BN_bn2mpi(this, NULL);
625 if (nSize < 4)
626 return std::vector<unsigned char>();
627 std::vector<unsigned char> vch(nSize);
628 BN_bn2mpi(this, &vch[0]);
629 vch.erase(vch.begin(), vch.begin() + 4);
630 reverse(vch.begin(), vch.end());
631 return vch;
632 }
633
634 CBigNum& SetCompact(unsigned int nCompact)
635 {
636 unsigned int nSize = nCompact >> 24;
637 std::vector<unsigned char> vch(4 + nSize);
638 vch[3] = nSize;
639 if (nSize >= 1) vch[4] = (nCompact >> 16) & 0xff;
640 if (nSize >= 2) vch[5] = (nCompact >> 8) & 0xff;
641 if (nSize >= 3) vch[6] = (nCompact >> 0) & 0xff;
642 BN_mpi2bn(&vch[0], vch.size(), this);
643 return *this;
644 }
645
646 unsigned int GetCompact() const
647 {
648 unsigned int nSize = BN_bn2mpi(this, NULL);
649 std::vector<unsigned char> vch(nSize);
650 nSize -= 4;
651 BN_bn2mpi(this, &vch[0]);
652 unsigned int nCompact = nSize << 24;
653 if (nSize >= 1) nCompact |= (vch[4] << 16);
654 if (nSize >= 2) nCompact |= (vch[5] << 8);
655 if (nSize >= 3) nCompact |= (vch[6] << 0);
656 return nCompact;
657 }
658
659 void SetHex(const std::string& str)
660 {
661 // skip 0x
662 const char* psz = str.c_str();
663 while (isspace(*psz))
664 psz++;
665 bool fNegative = false;
666 if (*psz == '-')
667 {
668 fNegative = true;
669 psz++;
670 }
671 if (psz[0] == '0' && tolower(psz[1]) == 'x')
672 psz += 2;
673 while (isspace(*psz))
674 psz++;
675
676 // hex string to bignum
677 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 };
678 *this = 0;
679 while (isxdigit(*psz))
680 {
681 *this <<= 4;
682 int n = phexdigit[*psz++];
683 *this += n;
684 }
685 if (fNegative)
686 *this = 0 - *this;
687 }
688
689 std::string ToString(int nBase=10) const
690 {
691 CAutoBN_CTX pctx;
692 CBigNum bnBase = nBase;
693 CBigNum bn0 = 0;
694 std::string str;
695 CBigNum bn = *this;
696 BN_set_negative(&bn, false);
697 CBigNum dv;
698 CBigNum rem;
699 if (BN_cmp(&bn, &bn0) == 0)
700 return "0";
701 while (BN_cmp(&bn, &bn0) > 0)
702 {
703 if (!BN_div(&dv, &rem, &bn, &bnBase, pctx))
704 throw bignum_error("CBigNum::ToString() : BN_div failed");
705 bn = dv;
706 unsigned int c = rem.getulong();
707 str += "0123456789abcdef"[c];
708 }
709 if (BN_is_negative(this))
710 str += "-";
711 reverse(str.begin(), str.end());
712 return str;
713 }
714
715 std::string GetHex() const
716 {
717 return ToString(16);
718 }
719
720 unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const
721 {
722 return ::GetSerializeSize(getvch(), nType, nVersion);
723 }
724
725 template<typename Stream>
726 void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const
727 {
728 ::Serialize(s, getvch(), nType, nVersion);
729 }
730
731 template<typename Stream>
732 void Unserialize(Stream& s, int nType=0, int nVersion=VERSION)
733 {
734 std::vector<unsigned char> vch;
735 ::Unserialize(s, vch, nType, nVersion);
736 setvch(vch);
737 }
738
739
740 bool operator!() const
741 {
742 return BN_is_zero(this);
743 }
744
745 CBigNum& operator+=(const CBigNum& b)
746 {
747 if (!BN_add(this, this, &b))
748 throw bignum_error("CBigNum::operator+= : BN_add failed");
749 return *this;
750 }
751
752 CBigNum& operator-=(const CBigNum& b)
753 {
754 *this = *this - b;
755 return *this;
756 }
757
758 CBigNum& operator*=(const CBigNum& b)
759 {
760 CAutoBN_CTX pctx;
761 if (!BN_mul(this, this, &b, pctx))
762 throw bignum_error("CBigNum::operator*= : BN_mul failed");
763 return *this;
764 }
765
766 CBigNum& operator/=(const CBigNum& b)
767 {
768 *this = *this / b;
769 return *this;
770 }
771
772 CBigNum& operator%=(const CBigNum& b)
773 {
774 *this = *this % b;
775 return *this;
776 }
777
778 CBigNum& operator<<=(unsigned int shift)
779 {
780 if (!BN_lshift(this, this, shift))
781 throw bignum_error("CBigNum:operator<<= : BN_lshift failed");
782 return *this;
783 }
784
785 CBigNum& operator>>=(unsigned int shift)
786 {
787 // Note: BN_rshift segfaults on 64-bit if 2^shift is greater than the number
788 // if built on ubuntu 9.04 or 9.10, probably depends on version of openssl
789 CBigNum a = 1;
790 a <<= shift;
791 if (BN_cmp(&a, this) > 0)
792 {
793 *this = 0;
794 return *this;
795 }
796
797 if (!BN_rshift(this, this, shift))
798 throw bignum_error("CBigNum:operator>>= : BN_rshift failed");
799 return *this;
800 }
801
802
803 CBigNum& operator++()
804 {
805 // prefix operator
806 if (!BN_add(this, this, BN_value_one()))
807 throw bignum_error("CBigNum::operator++ : BN_add failed");
808 return *this;
809 }
810
811 const CBigNum operator++(int)
812 {
813 // postfix operator
814 const CBigNum ret = *this;
815 ++(*this);
816 return ret;
817 }
818
819 CBigNum& operator--()
820 {
821 // prefix operator
822 CBigNum r;
823 if (!BN_sub(&r, this, BN_value_one()))
824 throw bignum_error("CBigNum::operator-- : BN_sub failed");
825 *this = r;
826 return *this;
827 }
828
829 const CBigNum operator--(int)
830 {
831 // postfix operator
832 const CBigNum ret = *this;
833 --(*this);
834 return ret;
835 }
836
837
838 friend inline const CBigNum operator-(const CBigNum& a, const CBigNum& b);
839 friend inline const CBigNum operator/(const CBigNum& a, const CBigNum& b);
840 friend inline const CBigNum operator%(const CBigNum& a, const CBigNum& b);
841 };
842
843
844
845 inline const CBigNum operator+(const CBigNum& a, const CBigNum& b)
846 {
847 CBigNum r;
848 if (!BN_add(&r, &a, &b))
849 throw bignum_error("CBigNum::operator+ : BN_add failed");
850 return r;
851 }
852
853 inline const CBigNum operator-(const CBigNum& a, const CBigNum& b)
854 {
855 CBigNum r;
856 if (!BN_sub(&r, &a, &b))
857 throw bignum_error("CBigNum::operator- : BN_sub failed");
858 return r;
859 }
860
861 inline const CBigNum operator-(const CBigNum& a)
862 {
863 CBigNum r(a);
864 BN_set_negative(&r, !BN_is_negative(&r));
865 return r;
866 }
867
868 inline const CBigNum operator*(const CBigNum& a, const CBigNum& b)
869 {
870 CAutoBN_CTX pctx;
871 CBigNum r;
872 if (!BN_mul(&r, &a, &b, pctx))
873 throw bignum_error("CBigNum::operator* : BN_mul failed");
874 return r;
875 }
876
877 inline const CBigNum operator/(const CBigNum& a, const CBigNum& b)
878 {
879 CAutoBN_CTX pctx;
880 CBigNum r;
881 if (!BN_div(&r, NULL, &a, &b, pctx))
882 throw bignum_error("CBigNum::operator/ : BN_div failed");
883 return r;
884 }
885
886 inline const CBigNum operator%(const CBigNum& a, const CBigNum& b)
887 {
888 CAutoBN_CTX pctx;
889 CBigNum r;
890 if (!BN_mod(&r, &a, &b, pctx))
891 throw bignum_error("CBigNum::operator% : BN_div failed");
892 return r;
893 }
894
895 inline const CBigNum operator<<(const CBigNum& a, unsigned int shift)
896 {
897 CBigNum r;
898 if (!BN_lshift(&r, &a, shift))
899 throw bignum_error("CBigNum:operator<< : BN_lshift failed");
900 return r;
901 }
902
903 inline const CBigNum operator>>(const CBigNum& a, unsigned int shift)
904 {
905 CBigNum r = a;
906 r >>= shift;
907 return r;
908 }
909
910 inline bool operator==(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) == 0); }
911 inline bool operator!=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) != 0); }
912 inline bool operator<=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) <= 0); }
913 inline bool operator>=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) >= 0); }
914 inline bool operator<(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) < 0); }
915 inline bool operator>(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) > 0); }
916
917 #endif
-
+ 631071B1ECB5BE290EC5C3976C3262F5C05813E0612912890BCC97CF25AF5696FD20C46BB9FB50823DF1B6BEA2C35AEAFDEA4462ABC50933A10D1CC13A19FE69
bitcoin/src/bitcoinrpc.cpp
(0 . 0)(1 . 2573)
922 // Copyright (c) 2010 Satoshi Nakamoto
923 // Copyright (c) 2009-2012 The Bitcoin developers
924 // Distributed under the MIT/X11 software license, see the accompanying
925 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
926
927 #include "headers.h"
928 #include "db.h"
929 #include "net.h"
930 #include "init.h"
931 #undef printf
932 #include <boost/asio.hpp>
933 #include <boost/iostreams/concepts.hpp>
934 #include <boost/iostreams/stream.hpp>
935 #include <boost/algorithm/string.hpp>
936 #ifdef USE_SSL
937 #include <boost/asio/ssl.hpp>
938 #include <boost/filesystem.hpp>
939 #include <boost/filesystem/fstream.hpp>
940 typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> SSLStream;
941 #endif
942 #include "json/json_spirit_reader_template.h"
943 #include "json/json_spirit_writer_template.h"
944 #include "json/json_spirit_utils.h"
945 #define printf OutputDebugStringF
946 // MinGW 3.4.5 gets "fatal error: had to relocate PCH" if the json headers are
947 // precompiled in headers.h. The problem might be when the pch file goes over
948 // a certain size around 145MB. If we need access to json_spirit outside this
949 // file, we could use the compiled json_spirit option.
950
951 using namespace std;
952 using namespace boost;
953 using namespace boost::asio;
954 using namespace json_spirit;
955
956 void ThreadRPCServer2(void* parg);
957 typedef Value(*rpcfn_type)(const Array& params, bool fHelp);
958 extern map<string, rpcfn_type> mapCallTable;
959
960 static std::string strRPCUserColonPass;
961
962 static int64 nWalletUnlockTime;
963 static CCriticalSection cs_nWalletUnlockTime;
964
965
966 Object JSONRPCError(int code, const string& message)
967 {
968 Object error;
969 error.push_back(Pair("code", code));
970 error.push_back(Pair("message", message));
971 return error;
972 }
973
974
975 void PrintConsole(const std::string &format, ...)
976 {
977 char buffer[50000];
978 int limit = sizeof(buffer);
979 va_list arg_ptr;
980 va_start(arg_ptr, format);
981 int ret = _vsnprintf(buffer, limit, format.c_str(), arg_ptr);
982 va_end(arg_ptr);
983 if (ret < 0 || ret >= limit)
984 {
985 ret = limit - 1;
986 buffer[limit-1] = 0;
987 }
988 printf("%s", buffer);
989 fprintf(stdout, "%s", buffer);
990 }
991
992
993 int64 AmountFromValue(const Value& value)
994 {
995 double dAmount = value.get_real();
996 if (dAmount <= 0.0 || dAmount > 21000000.0)
997 throw JSONRPCError(-3, "Invalid amount");
998 int64 nAmount = roundint64(dAmount * COIN);
999 if (!MoneyRange(nAmount))
1000 throw JSONRPCError(-3, "Invalid amount");
1001 return nAmount;
1002 }
1003
1004 Value ValueFromAmount(int64 amount)
1005 {
1006 return (double)amount / (double)COIN;
1007 }
1008
1009 void WalletTxToJSON(const CWalletTx& wtx, Object& entry)
1010 {
1011 entry.push_back(Pair("confirmations", wtx.GetDepthInMainChain()));
1012 entry.push_back(Pair("txid", wtx.GetHash().GetHex()));
1013 entry.push_back(Pair("time", (boost::int64_t)wtx.GetTxTime()));
1014 BOOST_FOREACH(const PAIRTYPE(string,string)& item, wtx.mapValue)
1015 entry.push_back(Pair(item.first, item.second));
1016 }
1017
1018 string AccountFromValue(const Value& value)
1019 {
1020 string strAccount = value.get_str();
1021 if (strAccount == "*")
1022 throw JSONRPCError(-11, "Invalid account name");
1023 return strAccount;
1024 }
1025
1026
1027
1028 ///
1029 /// Note: This interface may still be subject to change.
1030 ///
1031
1032
1033 Value help(const Array& params, bool fHelp)
1034 {
1035 if (fHelp || params.size() > 1)
1036 throw runtime_error(
1037 "help [command]\n"
1038 "List commands, or get help for a command.");
1039
1040 string strCommand;
1041 if (params.size() > 0)
1042 strCommand = params[0].get_str();
1043
1044 string strRet;
1045 set<rpcfn_type> setDone;
1046 for (map<string, rpcfn_type>::iterator mi = mapCallTable.begin(); mi != mapCallTable.end(); ++mi)
1047 {
1048 string strMethod = (*mi).first;
1049 // We already filter duplicates, but these deprecated screw up the sort order
1050 if (strMethod == "getamountreceived" ||
1051 strMethod == "getallreceived" ||
1052 strMethod == "getblocknumber" || // deprecated
1053 (strMethod.find("label") != string::npos))
1054 continue;
1055 if (strCommand != "" && strMethod != strCommand)
1056 continue;
1057 try
1058 {
1059 Array params;
1060 rpcfn_type pfn = (*mi).second;
1061 if (setDone.insert(pfn).second)
1062 (*pfn)(params, true);
1063 }
1064 catch (std::exception& e)
1065 {
1066 // Help text is returned in an exception
1067 string strHelp = string(e.what());
1068 if (strCommand == "")
1069 if (strHelp.find('\n') != -1)
1070 strHelp = strHelp.substr(0, strHelp.find('\n'));
1071 strRet += strHelp + "\n";
1072 }
1073 }
1074 if (strRet == "")
1075 strRet = strprintf("help: unknown command: %s\n", strCommand.c_str());
1076 strRet = strRet.substr(0,strRet.size()-1);
1077 return strRet;
1078 }
1079
1080
1081 Value stop(const Array& params, bool fHelp)
1082 {
1083 if (fHelp || params.size() != 0)
1084 throw runtime_error(
1085 "stop\n"
1086 "Stop bitcoin server.");
1087 #ifndef QT_GUI
1088 // Shutdown will take long enough that the response should get back
1089 CreateThread(Shutdown, NULL);
1090 return "bitcoin server stopping";
1091 #else
1092 throw runtime_error("NYI: cannot shut down GUI with RPC command");
1093 #endif
1094 }
1095
1096
1097 Value getblockcount(const Array& params, bool fHelp)
1098 {
1099 if (fHelp || params.size() != 0)
1100 throw runtime_error(
1101 "getblockcount\n"
1102 "Returns the number of blocks in the longest block chain.");
1103
1104 return nBestHeight;
1105 }
1106
1107
1108 // deprecated
1109 Value getblocknumber(const Array& params, bool fHelp)
1110 {
1111 if (fHelp || params.size() != 0)
1112 throw runtime_error(
1113 "getblocknumber\n"
1114 "Deprecated. Use getblockcount.");
1115
1116 return nBestHeight;
1117 }
1118
1119
1120 Value getconnectioncount(const Array& params, bool fHelp)
1121 {
1122 if (fHelp || params.size() != 0)
1123 throw runtime_error(
1124 "getconnectioncount\n"
1125 "Returns the number of connections to other nodes.");
1126
1127 return (int)vNodes.size();
1128 }
1129
1130
1131 double GetDifficulty()
1132 {
1133 // Floating point number that is a multiple of the minimum difficulty,
1134 // minimum difficulty = 1.0.
1135
1136 if (pindexBest == NULL)
1137 return 1.0;
1138 int nShift = (pindexBest->nBits >> 24) & 0xff;
1139
1140 double dDiff =
1141 (double)0x0000ffff / (double)(pindexBest->nBits & 0x00ffffff);
1142
1143 while (nShift < 29)
1144 {
1145 dDiff *= 256.0;
1146 nShift++;
1147 }
1148 while (nShift > 29)
1149 {
1150 dDiff /= 256.0;
1151 nShift--;
1152 }
1153
1154 return dDiff;
1155 }
1156
1157 Value getdifficulty(const Array& params, bool fHelp)
1158 {
1159 if (fHelp || params.size() != 0)
1160 throw runtime_error(
1161 "getdifficulty\n"
1162 "Returns the proof-of-work difficulty as a multiple of the minimum difficulty.");
1163
1164 return GetDifficulty();
1165 }
1166
1167
1168 Value getgenerate(const Array& params, bool fHelp)
1169 {
1170 if (fHelp || params.size() != 0)
1171 throw runtime_error(
1172 "getgenerate\n"
1173 "Returns true or false.");
1174
1175 return (bool)fGenerateBitcoins;
1176 }
1177
1178
1179 Value setgenerate(const Array& params, bool fHelp)
1180 {
1181 if (fHelp || params.size() < 1 || params.size() > 2)
1182 throw runtime_error(
1183 "setgenerate <generate> [genproclimit]\n"
1184 "<generate> is true or false to turn generation on or off.\n"
1185 "Generation is limited to [genproclimit] processors, -1 is unlimited.");
1186
1187 bool fGenerate = true;
1188 if (params.size() > 0)
1189 fGenerate = params[0].get_bool();
1190
1191 if (params.size() > 1)
1192 {
1193 int nGenProcLimit = params[1].get_int();
1194 fLimitProcessors = (nGenProcLimit != -1);
1195 WriteSetting("fLimitProcessors", fLimitProcessors);
1196 if (nGenProcLimit != -1)
1197 WriteSetting("nLimitProcessors", nLimitProcessors = nGenProcLimit);
1198 if (nGenProcLimit == 0)
1199 fGenerate = false;
1200 }
1201
1202 GenerateBitcoins(fGenerate, pwalletMain);
1203 return Value::null;
1204 }
1205
1206
1207 Value gethashespersec(const Array& params, bool fHelp)
1208 {
1209 if (fHelp || params.size() != 0)
1210 throw runtime_error(
1211 "gethashespersec\n"
1212 "Returns a recent hashes per second performance measurement while generating.");
1213
1214 if (GetTimeMillis() - nHPSTimerStart > 8000)
1215 return (boost::int64_t)0;
1216 return (boost::int64_t)dHashesPerSec;
1217 }
1218
1219
1220 Value getinfo(const Array& params, bool fHelp)
1221 {
1222 if (fHelp || params.size() != 0)
1223 throw runtime_error(
1224 "getinfo\n"
1225 "Returns an object containing various state info.");
1226
1227 Object obj;
1228 obj.push_back(Pair("version", (int)VERSION));
1229 obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance())));
1230 obj.push_back(Pair("blocks", (int)nBestHeight));
1231 obj.push_back(Pair("connections", (int)vNodes.size()));
1232 obj.push_back(Pair("proxy", (fUseProxy ? addrProxy.ToStringIPPort() : string())));
1233 obj.push_back(Pair("generate", (bool)fGenerateBitcoins));
1234 obj.push_back(Pair("genproclimit", (int)(fLimitProcessors ? nLimitProcessors : -1)));
1235 obj.push_back(Pair("difficulty", (double)GetDifficulty()));
1236 obj.push_back(Pair("hashespersec", gethashespersec(params, false)));
1237 obj.push_back(Pair("testnet", fTestNet));
1238 obj.push_back(Pair("keypoololdest", (boost::int64_t)pwalletMain->GetOldestKeyPoolTime()));
1239 obj.push_back(Pair("keypoolsize", pwalletMain->GetKeyPoolSize()));
1240 obj.push_back(Pair("paytxfee", ValueFromAmount(nTransactionFee)));
1241 if (pwalletMain->IsCrypted())
1242 obj.push_back(Pair("unlocked_until", (boost::int64_t)nWalletUnlockTime / 1000));
1243 obj.push_back(Pair("errors", GetWarnings("statusbar")));
1244 return obj;
1245 }
1246
1247
1248 Value getnewaddress(const Array& params, bool fHelp)
1249 {
1250 if (fHelp || params.size() > 1)
1251 throw runtime_error(
1252 "getnewaddress [account]\n"
1253 "Returns a new bitcoin address for receiving payments. "
1254 "If [account] is specified (recommended), it is added to the address book "
1255 "so payments received with the address will be credited to [account].");
1256
1257 // Parse the account first so we don't generate a key if there's an error
1258 string strAccount;
1259 if (params.size() > 0)
1260 strAccount = AccountFromValue(params[0]);
1261
1262 if (!pwalletMain->IsLocked())
1263 pwalletMain->TopUpKeyPool();
1264
1265 // Generate a new key that is added to wallet
1266 std::vector<unsigned char> newKey;
1267 if (!pwalletMain->GetKeyFromPool(newKey, false))
1268 throw JSONRPCError(-12, "Error: Keypool ran out, please call keypoolrefill first");
1269 CBitcoinAddress address(newKey);
1270
1271 pwalletMain->SetAddressBookName(address, strAccount);
1272
1273 return address.ToString();
1274 }
1275
1276
1277 CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false)
1278 {
1279 CWalletDB walletdb(pwalletMain->strWalletFile);
1280
1281 CAccount account;
1282 walletdb.ReadAccount(strAccount, account);
1283
1284 bool bKeyUsed = false;
1285
1286 // Check if the current key has been used
1287 if (!account.vchPubKey.empty())
1288 {
1289 CScript scriptPubKey;
1290 scriptPubKey.SetBitcoinAddress(account.vchPubKey);
1291 for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin();
1292 it != pwalletMain->mapWallet.end() && !account.vchPubKey.empty();
1293 ++it)
1294 {
1295 const CWalletTx& wtx = (*it).second;
1296 BOOST_FOREACH(const CTxOut& txout, wtx.vout)
1297 if (txout.scriptPubKey == scriptPubKey)
1298 bKeyUsed = true;
1299 }
1300 }
1301
1302 // Generate a new key
1303 if (account.vchPubKey.empty() || bForceNew || bKeyUsed)
1304 {
1305 if (!pwalletMain->GetKeyFromPool(account.vchPubKey, false))
1306 throw JSONRPCError(-12, "Error: Keypool ran out, please call keypoolrefill first");
1307
1308 pwalletMain->SetAddressBookName(CBitcoinAddress(account.vchPubKey), strAccount);
1309 walletdb.WriteAccount(strAccount, account);
1310 }
1311
1312 return CBitcoinAddress(account.vchPubKey);
1313 }
1314
1315 Value getaccountaddress(const Array& params, bool fHelp)
1316 {
1317 if (fHelp || params.size() != 1)
1318 throw runtime_error(
1319 "getaccountaddress <account>\n"
1320 "Returns the current bitcoin address for receiving payments to this account.");
1321
1322 // Parse the account first so we don't generate a key if there's an error
1323 string strAccount = AccountFromValue(params[0]);
1324
1325 Value ret;
1326
1327 ret = GetAccountAddress(strAccount).ToString();
1328
1329 return ret;
1330 }
1331
1332
1333
1334 Value setaccount(const Array& params, bool fHelp)
1335 {
1336 if (fHelp || params.size() < 1 || params.size() > 2)
1337 throw runtime_error(
1338 "setaccount <bitcoinaddress> <account>\n"
1339 "Sets the account associated with the given address.");
1340
1341 CBitcoinAddress address(params[0].get_str());
1342 if (!address.IsValid())
1343 throw JSONRPCError(-5, "Invalid bitcoin address");
1344
1345
1346 string strAccount;
1347 if (params.size() > 1)
1348 strAccount = AccountFromValue(params[1]);
1349
1350 // Detect when changing the account of an address that is the 'unused current key' of another account:
1351 if (pwalletMain->mapAddressBook.count(address))
1352 {
1353 string strOldAccount = pwalletMain->mapAddressBook[address];
1354 if (address == GetAccountAddress(strOldAccount))
1355 GetAccountAddress(strOldAccount, true);
1356 }
1357
1358 pwalletMain->SetAddressBookName(address, strAccount);
1359
1360 return Value::null;
1361 }
1362
1363
1364 Value getaccount(const Array& params, bool fHelp)
1365 {
1366 if (fHelp || params.size() != 1)
1367 throw runtime_error(
1368 "getaccount <bitcoinaddress>\n"
1369 "Returns the account associated with the given address.");
1370
1371 CBitcoinAddress address(params[0].get_str());
1372 if (!address.IsValid())
1373 throw JSONRPCError(-5, "Invalid bitcoin address");
1374
1375 string strAccount;
1376 map<CBitcoinAddress, string>::iterator mi = pwalletMain->mapAddressBook.find(address);
1377 if (mi != pwalletMain->mapAddressBook.end() && !(*mi).second.empty())
1378 strAccount = (*mi).second;
1379 return strAccount;
1380 }
1381
1382
1383 Value getaddressesbyaccount(const Array& params, bool fHelp)
1384 {
1385 if (fHelp || params.size() != 1)
1386 throw runtime_error(
1387 "getaddressesbyaccount <account>\n"
1388 "Returns the list of addresses for the given account.");
1389
1390 string strAccount = AccountFromValue(params[0]);
1391
1392 // Find all addresses that have the given account
1393 Array ret;
1394 BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook)
1395 {
1396 const CBitcoinAddress& address = item.first;
1397 const string& strName = item.second;
1398 if (strName == strAccount)
1399 ret.push_back(address.ToString());
1400 }
1401 return ret;
1402 }
1403
1404 Value settxfee(const Array& params, bool fHelp)
1405 {
1406 if (fHelp || params.size() < 1 || params.size() > 1)
1407 throw runtime_error(
1408 "settxfee <amount>\n"
1409 "<amount> is a real and is rounded to the nearest 0.00000001");
1410
1411 // Amount
1412 int64 nAmount = 0;
1413 if (params[0].get_real() != 0.0)
1414 nAmount = AmountFromValue(params[0]); // rejects 0.0 amounts
1415
1416 nTransactionFee = nAmount;
1417 return true;
1418 }
1419
1420 Value sendtoaddress(const Array& params, bool fHelp)
1421 {
1422 if (pwalletMain->IsCrypted() && (fHelp || params.size() < 2 || params.size() > 4))
1423 throw runtime_error(
1424 "sendtoaddress <bitcoinaddress> <amount> [comment] [comment-to]\n"
1425 "<amount> is a real and is rounded to the nearest 0.00000001\n"
1426 "requires wallet passphrase to be set with walletpassphrase first");
1427 if (!pwalletMain->IsCrypted() && (fHelp || params.size() < 2 || params.size() > 4))
1428 throw runtime_error(
1429 "sendtoaddress <bitcoinaddress> <amount> [comment] [comment-to]\n"
1430 "<amount> is a real and is rounded to the nearest 0.00000001");
1431
1432 CBitcoinAddress address(params[0].get_str());
1433 if (!address.IsValid())
1434 throw JSONRPCError(-5, "Invalid bitcoin address");
1435
1436 // Amount
1437 int64 nAmount = AmountFromValue(params[1]);
1438
1439 // Wallet comments
1440 CWalletTx wtx;
1441 if (params.size() > 2 && params[2].type() != null_type && !params[2].get_str().empty())
1442 wtx.mapValue["comment"] = params[2].get_str();
1443 if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty())
1444 wtx.mapValue["to"] = params[3].get_str();
1445
1446 if (pwalletMain->IsLocked())
1447 throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
1448
1449 string strError = pwalletMain->SendMoneyToBitcoinAddress(address, nAmount, wtx);
1450 if (strError != "")
1451 throw JSONRPCError(-4, strError);
1452
1453 return wtx.GetHash().GetHex();
1454 }
1455
1456 static const string strMessageMagic = "Bitcoin Signed Message:\n";
1457
1458 Value signmessage(const Array& params, bool fHelp)
1459 {
1460 if (fHelp || params.size() != 2)
1461 throw runtime_error(
1462 "signmessage <bitcoinaddress> <message>\n"
1463 "Sign a message with the private key of an address");
1464
1465 if (pwalletMain->IsLocked())
1466 throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
1467
1468 string strAddress = params[0].get_str();
1469 string strMessage = params[1].get_str();
1470
1471 CBitcoinAddress addr(strAddress);
1472 if (!addr.IsValid())
1473 throw JSONRPCError(-3, "Invalid address");
1474
1475 CKey key;
1476 if (!pwalletMain->GetKey(addr, key))
1477 throw JSONRPCError(-4, "Private key not available");
1478
1479 CDataStream ss(SER_GETHASH);
1480 ss << strMessageMagic;
1481 ss << strMessage;
1482
1483 vector<unsigned char> vchSig;
1484 if (!key.SignCompact(Hash(ss.begin(), ss.end()), vchSig))
1485 throw JSONRPCError(-5, "Sign failed");
1486
1487 return EncodeBase64(&vchSig[0], vchSig.size());
1488 }
1489
1490 Value verifymessage(const Array& params, bool fHelp)
1491 {
1492 if (fHelp || params.size() != 3)
1493 throw runtime_error(
1494 "verifymessage <bitcoinaddress> <signature> <message>\n"
1495 "Verify a signed message");
1496
1497 string strAddress = params[0].get_str();
1498 string strSign = params[1].get_str();
1499 string strMessage = params[2].get_str();
1500
1501 CBitcoinAddress addr(strAddress);
1502 if (!addr.IsValid())
1503 throw JSONRPCError(-3, "Invalid address");
1504
1505 bool fInvalid = false;
1506 vector<unsigned char> vchSig = DecodeBase64(strSign.c_str(), &fInvalid);
1507
1508 if (fInvalid)
1509 throw JSONRPCError(-5, "Malformed base64 encoding");
1510
1511 CDataStream ss(SER_GETHASH);
1512 ss << strMessageMagic;
1513 ss << strMessage;
1514
1515 CKey key;
1516 if (!key.SetCompactSignature(Hash(ss.begin(), ss.end()), vchSig))
1517 return false;
1518
1519 return (key.GetAddress() == addr);
1520 }
1521
1522
1523 Value getreceivedbyaddress(const Array& params, bool fHelp)
1524 {
1525 if (fHelp || params.size() < 1 || params.size() > 2)
1526 throw runtime_error(
1527 "getreceivedbyaddress <bitcoinaddress> [minconf=1]\n"
1528 "Returns the total amount received by <bitcoinaddress> in transactions with at least [minconf] confirmations.");
1529
1530 // Bitcoin address
1531 CBitcoinAddress address = CBitcoinAddress(params[0].get_str());
1532 CScript scriptPubKey;
1533 if (!address.IsValid())
1534 throw JSONRPCError(-5, "Invalid bitcoin address");
1535 scriptPubKey.SetBitcoinAddress(address);
1536 if (!IsMine(*pwalletMain,scriptPubKey))
1537 return (double)0.0;
1538
1539 // Minimum confirmations
1540 int nMinDepth = 1;
1541 if (params.size() > 1)
1542 nMinDepth = params[1].get_int();
1543
1544 // Tally
1545 int64 nAmount = 0;
1546 for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
1547 {
1548 const CWalletTx& wtx = (*it).second;
1549 if (wtx.IsCoinBase() || !wtx.IsFinal())
1550 continue;
1551
1552 BOOST_FOREACH(const CTxOut& txout, wtx.vout)
1553 if (txout.scriptPubKey == scriptPubKey)
1554 if (wtx.GetDepthInMainChain() >= nMinDepth)
1555 nAmount += txout.nValue;
1556 }
1557
1558 return ValueFromAmount(nAmount);
1559 }
1560
1561
1562 void GetAccountAddresses(string strAccount, set<CBitcoinAddress>& setAddress)
1563 {
1564 BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook)
1565 {
1566 const CBitcoinAddress& address = item.first;
1567 const string& strName = item.second;
1568 if (strName == strAccount)
1569 setAddress.insert(address);
1570 }
1571 }
1572
1573
1574 Value getreceivedbyaccount(const Array& params, bool fHelp)
1575 {
1576 if (fHelp || params.size() < 1 || params.size() > 2)
1577 throw runtime_error(
1578 "getreceivedbyaccount <account> [minconf=1]\n"
1579 "Returns the total amount received by addresses with <account> in transactions with at least [minconf] confirmations.");
1580
1581 // Minimum confirmations
1582 int nMinDepth = 1;
1583 if (params.size() > 1)
1584 nMinDepth = params[1].get_int();
1585
1586 // Get the set of pub keys that have the label
1587 string strAccount = AccountFromValue(params[0]);
1588 set<CBitcoinAddress> setAddress;
1589 GetAccountAddresses(strAccount, setAddress);
1590
1591 // Tally
1592 int64 nAmount = 0;
1593 for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
1594 {
1595 const CWalletTx& wtx = (*it).second;
1596 if (wtx.IsCoinBase() || !wtx.IsFinal())
1597 continue;
1598
1599 BOOST_FOREACH(const CTxOut& txout, wtx.vout)
1600 {
1601 CBitcoinAddress address;
1602 if (ExtractAddress(txout.scriptPubKey, pwalletMain, address) && setAddress.count(address))
1603 if (wtx.GetDepthInMainChain() >= nMinDepth)
1604 nAmount += txout.nValue;
1605 }
1606 }
1607
1608 return (double)nAmount / (double)COIN;
1609 }
1610
1611
1612 int64 GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinDepth)
1613 {
1614 int64 nBalance = 0;
1615
1616 // Tally wallet transactions
1617 for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
1618 {
1619 const CWalletTx& wtx = (*it).second;
1620 if (!wtx.IsFinal())
1621 continue;
1622
1623 int64 nGenerated, nReceived, nSent, nFee;
1624 wtx.GetAccountAmounts(strAccount, nGenerated, nReceived, nSent, nFee);
1625
1626 if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth)
1627 nBalance += nReceived;
1628 nBalance += nGenerated - nSent - nFee;
1629 }
1630
1631 // Tally internal accounting entries
1632 nBalance += walletdb.GetAccountCreditDebit(strAccount);
1633
1634 return nBalance;
1635 }
1636
1637 int64 GetAccountBalance(const string& strAccount, int nMinDepth)
1638 {
1639 CWalletDB walletdb(pwalletMain->strWalletFile);
1640 return GetAccountBalance(walletdb, strAccount, nMinDepth);
1641 }
1642
1643
1644 Value getbalance(const Array& params, bool fHelp)
1645 {
1646 if (fHelp || params.size() > 2)
1647 throw runtime_error(
1648 "getbalance [account] [minconf=1]\n"
1649 "If [account] is not specified, returns the server's total available balance.\n"
1650 "If [account] is specified, returns the balance in the account.");
1651
1652 if (params.size() == 0)
1653 return ValueFromAmount(pwalletMain->GetBalance());
1654
1655 int nMinDepth = 1;
1656 if (params.size() > 1)
1657 nMinDepth = params[1].get_int();
1658
1659 if (params[0].get_str() == "*") {
1660 // Calculate total balance a different way from GetBalance()
1661 // (GetBalance() sums up all unspent TxOuts)
1662 // getbalance and getbalance '*' should always return the same number.
1663 int64 nBalance = 0;
1664 for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
1665 {
1666 const CWalletTx& wtx = (*it).second;
1667 if (!wtx.IsFinal())
1668 continue;
1669
1670 int64 allGeneratedImmature, allGeneratedMature, allFee;
1671 allGeneratedImmature = allGeneratedMature = allFee = 0;
1672 string strSentAccount;
1673 list<pair<CBitcoinAddress, int64> > listReceived;
1674 list<pair<CBitcoinAddress, int64> > listSent;
1675 wtx.GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount);
1676 if (wtx.GetDepthInMainChain() >= nMinDepth)
1677 BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listReceived)
1678 nBalance += r.second;
1679 BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listSent)
1680 nBalance -= r.second;
1681 nBalance -= allFee;
1682 nBalance += allGeneratedMature;
1683 }
1684 return ValueFromAmount(nBalance);
1685 }
1686
1687 string strAccount = AccountFromValue(params[0]);
1688
1689 int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
1690
1691 return ValueFromAmount(nBalance);
1692 }
1693
1694
1695 Value movecmd(const Array& params, bool fHelp)
1696 {
1697 if (fHelp || params.size() < 3 || params.size() > 5)
1698 throw runtime_error(
1699 "move <fromaccount> <toaccount> <amount> [minconf=1] [comment]\n"
1700 "Move from one account in your wallet to another.");
1701
1702 string strFrom = AccountFromValue(params[0]);
1703 string strTo = AccountFromValue(params[1]);
1704 int64 nAmount = AmountFromValue(params[2]);
1705 if (params.size() > 3)
1706 // unused parameter, used to be nMinDepth, keep type-checking it though
1707 (void)params[3].get_int();
1708 string strComment;
1709 if (params.size() > 4)
1710 strComment = params[4].get_str();
1711
1712 CWalletDB walletdb(pwalletMain->strWalletFile);
1713 walletdb.TxnBegin();
1714
1715 int64 nNow = GetAdjustedTime();
1716
1717 // Debit
1718 CAccountingEntry debit;
1719 debit.strAccount = strFrom;
1720 debit.nCreditDebit = -nAmount;
1721 debit.nTime = nNow;
1722 debit.strOtherAccount = strTo;
1723 debit.strComment = strComment;
1724 walletdb.WriteAccountingEntry(debit);
1725
1726 // Credit
1727 CAccountingEntry credit;
1728 credit.strAccount = strTo;
1729 credit.nCreditDebit = nAmount;
1730 credit.nTime = nNow;
1731 credit.strOtherAccount = strFrom;
1732 credit.strComment = strComment;
1733 walletdb.WriteAccountingEntry(credit);
1734
1735 walletdb.TxnCommit();
1736
1737 return true;
1738 }
1739
1740
1741 Value sendfrom(const Array& params, bool fHelp)
1742 {
1743 if (pwalletMain->IsCrypted() && (fHelp || params.size() < 3 || params.size() > 6))
1744 throw runtime_error(
1745 "sendfrom <fromaccount> <tobitcoinaddress> <amount> [minconf=1] [comment] [comment-to]\n"
1746 "<amount> is a real and is rounded to the nearest 0.00000001\n"
1747 "requires wallet passphrase to be set with walletpassphrase first");
1748 if (!pwalletMain->IsCrypted() && (fHelp || params.size() < 3 || params.size() > 6))
1749 throw runtime_error(
1750 "sendfrom <fromaccount> <tobitcoinaddress> <amount> [minconf=1] [comment] [comment-to]\n"
1751 "<amount> is a real and is rounded to the nearest 0.00000001");
1752
1753 string strAccount = AccountFromValue(params[0]);
1754 CBitcoinAddress address(params[1].get_str());
1755 if (!address.IsValid())
1756 throw JSONRPCError(-5, "Invalid bitcoin address");
1757 int64 nAmount = AmountFromValue(params[2]);
1758 int nMinDepth = 1;
1759 if (params.size() > 3)
1760 nMinDepth = params[3].get_int();
1761
1762 CWalletTx wtx;
1763 wtx.strFromAccount = strAccount;
1764 if (params.size() > 4 && params[4].type() != null_type && !params[4].get_str().empty())
1765 wtx.mapValue["comment"] = params[4].get_str();
1766 if (params.size() > 5 && params[5].type() != null_type && !params[5].get_str().empty())
1767 wtx.mapValue["to"] = params[5].get_str();
1768
1769 if (pwalletMain->IsLocked())
1770 throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
1771
1772 // Check funds
1773 int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
1774 if (nAmount > nBalance)
1775 throw JSONRPCError(-6, "Account has insufficient funds");
1776
1777 // Send
1778 string strError = pwalletMain->SendMoneyToBitcoinAddress(address, nAmount, wtx);
1779 if (strError != "")
1780 throw JSONRPCError(-4, strError);
1781
1782 return wtx.GetHash().GetHex();
1783 }
1784
1785
1786 Value sendmany(const Array& params, bool fHelp)
1787 {
1788 if (pwalletMain->IsCrypted() && (fHelp || params.size() < 2 || params.size() > 4))
1789 throw runtime_error(
1790 "sendmany <fromaccount> {address:amount,...} [minconf=1] [comment]\n"
1791 "amounts are double-precision floating point numbers\n"
1792 "requires wallet passphrase to be set with walletpassphrase first");
1793 if (!pwalletMain->IsCrypted() && (fHelp || params.size() < 2 || params.size() > 4))
1794 throw runtime_error(
1795 "sendmany <fromaccount> {address:amount,...} [minconf=1] [comment]\n"
1796 "amounts are double-precision floating point numbers");
1797
1798 string strAccount = AccountFromValue(params[0]);
1799 Object sendTo = params[1].get_obj();
1800 int nMinDepth = 1;
1801 if (params.size() > 2)
1802 nMinDepth = params[2].get_int();
1803
1804 CWalletTx wtx;
1805 wtx.strFromAccount = strAccount;
1806 if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty())
1807 wtx.mapValue["comment"] = params[3].get_str();
1808
1809 set<CBitcoinAddress> setAddress;
1810 vector<pair<CScript, int64> > vecSend;
1811
1812 int64 totalAmount = 0;
1813 BOOST_FOREACH(const Pair& s, sendTo)
1814 {
1815 CBitcoinAddress address(s.name_);
1816 if (!address.IsValid())
1817 throw JSONRPCError(-5, string("Invalid bitcoin address:")+s.name_);
1818
1819 if (setAddress.count(address))
1820 throw JSONRPCError(-8, string("Invalid parameter, duplicated address: ")+s.name_);
1821 setAddress.insert(address);
1822
1823 CScript scriptPubKey;
1824 scriptPubKey.SetBitcoinAddress(address);
1825 int64 nAmount = AmountFromValue(s.value_);
1826 totalAmount += nAmount;
1827
1828 vecSend.push_back(make_pair(scriptPubKey, nAmount));
1829 }
1830
1831 if (pwalletMain->IsLocked())
1832 throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
1833
1834 // Check funds
1835 int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
1836 if (totalAmount > nBalance)
1837 throw JSONRPCError(-6, "Account has insufficient funds");
1838
1839 // Send
1840 CReserveKey keyChange(pwalletMain);
1841 int64 nFeeRequired = 0;
1842 bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired);
1843 if (!fCreated)
1844 {
1845 if (totalAmount + nFeeRequired > pwalletMain->GetBalance())
1846 throw JSONRPCError(-6, "Insufficient funds");
1847 throw JSONRPCError(-4, "Transaction creation failed");
1848 }
1849 if (!pwalletMain->CommitTransaction(wtx, keyChange))
1850 throw JSONRPCError(-4, "Transaction commit failed");
1851
1852 return wtx.GetHash().GetHex();
1853 }
1854
1855
1856 struct tallyitem
1857 {
1858 int64 nAmount;
1859 int nConf;
1860 tallyitem()
1861 {
1862 nAmount = 0;
1863 nConf = INT_MAX;
1864 }
1865 };
1866
1867 Value ListReceived(const Array& params, bool fByAccounts)
1868 {
1869 // Minimum confirmations
1870 int nMinDepth = 1;
1871 if (params.size() > 0)
1872 nMinDepth = params[0].get_int();
1873
1874 // Whether to include empty accounts
1875 bool fIncludeEmpty = false;
1876 if (params.size() > 1)
1877 fIncludeEmpty = params[1].get_bool();
1878
1879 // Tally
1880 map<CBitcoinAddress, tallyitem> mapTally;
1881 for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
1882 {
1883 const CWalletTx& wtx = (*it).second;
1884 if (wtx.IsCoinBase() || !wtx.IsFinal())
1885 continue;
1886
1887 int nDepth = wtx.GetDepthInMainChain();
1888 if (nDepth < nMinDepth)
1889 continue;
1890
1891 BOOST_FOREACH(const CTxOut& txout, wtx.vout)
1892 {
1893 CBitcoinAddress address;
1894 if (!ExtractAddress(txout.scriptPubKey, pwalletMain, address) || !address.IsValid())
1895 continue;
1896
1897 tallyitem& item = mapTally[address];
1898 item.nAmount += txout.nValue;
1899 item.nConf = min(item.nConf, nDepth);
1900 }
1901 }
1902
1903 // Reply
1904 Array ret;
1905 map<string, tallyitem> mapAccountTally;
1906 BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook)
1907 {
1908 const CBitcoinAddress& address = item.first;
1909 const string& strAccount = item.second;
1910 map<CBitcoinAddress, tallyitem>::iterator it = mapTally.find(address);
1911 if (it == mapTally.end() && !fIncludeEmpty)
1912 continue;
1913
1914 int64 nAmount = 0;
1915 int nConf = INT_MAX;
1916 if (it != mapTally.end())
1917 {
1918 nAmount = (*it).second.nAmount;
1919 nConf = (*it).second.nConf;
1920 }
1921
1922 if (fByAccounts)
1923 {
1924 tallyitem& item = mapAccountTally[strAccount];
1925 item.nAmount += nAmount;
1926 item.nConf = min(item.nConf, nConf);
1927 }
1928 else
1929 {
1930 Object obj;
1931 obj.push_back(Pair("address", address.ToString()));
1932 obj.push_back(Pair("account", strAccount));
1933 obj.push_back(Pair("amount", ValueFromAmount(nAmount)));
1934 obj.push_back(Pair("confirmations", (nConf == INT_MAX ? 0 : nConf)));
1935 ret.push_back(obj);
1936 }
1937 }
1938
1939 if (fByAccounts)
1940 {
1941 for (map<string, tallyitem>::iterator it = mapAccountTally.begin(); it != mapAccountTally.end(); ++it)
1942 {
1943 int64 nAmount = (*it).second.nAmount;
1944 int nConf = (*it).second.nConf;
1945 Object obj;
1946 obj.push_back(Pair("account", (*it).first));
1947 obj.push_back(Pair("amount", ValueFromAmount(nAmount)));
1948 obj.push_back(Pair("confirmations", (nConf == INT_MAX ? 0 : nConf)));
1949 ret.push_back(obj);
1950 }
1951 }
1952
1953 return ret;
1954 }
1955
1956 Value listreceivedbyaddress(const Array& params, bool fHelp)
1957 {
1958 if (fHelp || params.size() > 2)
1959 throw runtime_error(
1960 "listreceivedbyaddress [minconf=1] [includeempty=false]\n"
1961 "[minconf] is the minimum number of confirmations before payments are included.\n"
1962 "[includeempty] whether to include addresses that haven't received any payments.\n"
1963 "Returns an array of objects containing:\n"
1964 " \"address\" : receiving address\n"
1965 " \"account\" : the account of the receiving address\n"
1966 " \"amount\" : total amount received by the address\n"
1967 " \"confirmations\" : number of confirmations of the most recent transaction included");
1968
1969 return ListReceived(params, false);
1970 }
1971
1972 Value listreceivedbyaccount(const Array& params, bool fHelp)
1973 {
1974 if (fHelp || params.size() > 2)
1975 throw runtime_error(
1976 "listreceivedbyaccount [minconf=1] [includeempty=false]\n"
1977 "[minconf] is the minimum number of confirmations before payments are included.\n"
1978 "[includeempty] whether to include accounts that haven't received any payments.\n"
1979 "Returns an array of objects containing:\n"
1980 " \"account\" : the account of the receiving addresses\n"
1981 " \"amount\" : total amount received by addresses with this account\n"
1982 " \"confirmations\" : number of confirmations of the most recent transaction included");
1983
1984 return ListReceived(params, true);
1985 }
1986
1987 void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, Array& ret)
1988 {
1989 int64 nGeneratedImmature, nGeneratedMature, nFee;
1990 string strSentAccount;
1991 list<pair<CBitcoinAddress, int64> > listReceived;
1992 list<pair<CBitcoinAddress, int64> > listSent;
1993 wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount);
1994
1995 bool fAllAccounts = (strAccount == string("*"));
1996
1997 // Generated blocks assigned to account ""
1998 if ((nGeneratedMature+nGeneratedImmature) != 0 && (fAllAccounts || strAccount == ""))
1999 {
2000 Object entry;
2001 entry.push_back(Pair("account", string("")));
2002 if (nGeneratedImmature)
2003 {
2004 entry.push_back(Pair("category", wtx.GetDepthInMainChain() ? "immature" : "orphan"));
2005 entry.push_back(Pair("amount", ValueFromAmount(nGeneratedImmature)));
2006 }
2007 else
2008 {
2009 entry.push_back(Pair("category", "generate"));
2010 entry.push_back(Pair("amount", ValueFromAmount(nGeneratedMature)));
2011 }
2012 if (fLong)
2013 WalletTxToJSON(wtx, entry);
2014 ret.push_back(entry);
2015 }
2016
2017 // Sent
2018 if ((!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount))
2019 {
2020 BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& s, listSent)
2021 {
2022 Object entry;
2023 entry.push_back(Pair("account", strSentAccount));
2024 entry.push_back(Pair("address", s.first.ToString()));
2025 entry.push_back(Pair("category", "send"));
2026 entry.push_back(Pair("amount", ValueFromAmount(-s.second)));
2027 entry.push_back(Pair("fee", ValueFromAmount(-nFee)));
2028 if (fLong)
2029 WalletTxToJSON(wtx, entry);
2030 ret.push_back(entry);
2031 }
2032 }
2033
2034 // Received
2035 if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth)
2036 BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& r, listReceived)
2037 {
2038 string account;
2039 if (pwalletMain->mapAddressBook.count(r.first))
2040 account = pwalletMain->mapAddressBook[r.first];
2041 if (fAllAccounts || (account == strAccount))
2042 {
2043 Object entry;
2044 entry.push_back(Pair("account", account));
2045 entry.push_back(Pair("address", r.first.ToString()));
2046 entry.push_back(Pair("category", "receive"));
2047 entry.push_back(Pair("amount", ValueFromAmount(r.second)));
2048 if (fLong)
2049 WalletTxToJSON(wtx, entry);
2050 ret.push_back(entry);
2051 }
2052 }
2053 }
2054
2055 void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Array& ret)
2056 {
2057 bool fAllAccounts = (strAccount == string("*"));
2058
2059 if (fAllAccounts || acentry.strAccount == strAccount)
2060 {
2061 Object entry;
2062 entry.push_back(Pair("account", acentry.strAccount));
2063 entry.push_back(Pair("category", "move"));
2064 entry.push_back(Pair("time", (boost::int64_t)acentry.nTime));
2065 entry.push_back(Pair("amount", ValueFromAmount(acentry.nCreditDebit)));
2066 entry.push_back(Pair("otheraccount", acentry.strOtherAccount));
2067 entry.push_back(Pair("comment", acentry.strComment));
2068 ret.push_back(entry);
2069 }
2070 }
2071
2072 Value listtransactions(const Array& params, bool fHelp)
2073 {
2074 if (fHelp || params.size() > 3)
2075 throw runtime_error(
2076 "listtransactions [account] [count=10] [from=0]\n"
2077 "Returns up to [count] most recent transactions skipping the first [from] transactions for account [account].");
2078
2079 string strAccount = "*";
2080 if (params.size() > 0)
2081 strAccount = params[0].get_str();
2082 int nCount = 10;
2083 if (params.size() > 1)
2084 nCount = params[1].get_int();
2085 int nFrom = 0;
2086 if (params.size() > 2)
2087 nFrom = params[2].get_int();
2088
2089 Array ret;
2090 CWalletDB walletdb(pwalletMain->strWalletFile);
2091
2092 // Firs: get all CWalletTx and CAccountingEntry into a sorted-by-time multimap:
2093 typedef pair<CWalletTx*, CAccountingEntry*> TxPair;
2094 typedef multimap<int64, TxPair > TxItems;
2095 TxItems txByTime;
2096
2097 for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
2098 {
2099 CWalletTx* wtx = &((*it).second);
2100 txByTime.insert(make_pair(wtx->GetTxTime(), TxPair(wtx, (CAccountingEntry*)0)));
2101 }
2102 list<CAccountingEntry> acentries;
2103 walletdb.ListAccountCreditDebit(strAccount, acentries);
2104 BOOST_FOREACH(CAccountingEntry& entry, acentries)
2105 {
2106 txByTime.insert(make_pair(entry.nTime, TxPair((CWalletTx*)0, &entry)));
2107 }
2108
2109 // Now: iterate backwards until we have nCount items to return:
2110 TxItems::reverse_iterator it = txByTime.rbegin();
2111 if (txByTime.size() > nFrom) std::advance(it, nFrom);
2112 for (; it != txByTime.rend(); ++it)
2113 {
2114 CWalletTx *const pwtx = (*it).second.first;
2115 if (pwtx != 0)
2116 ListTransactions(*pwtx, strAccount, 0, true, ret);
2117 CAccountingEntry *const pacentry = (*it).second.second;
2118 if (pacentry != 0)
2119 AcentryToJSON(*pacentry, strAccount, ret);
2120
2121 if (ret.size() >= nCount) break;
2122 }
2123 // ret is now newest to oldest
2124
2125 // Make sure we return only last nCount items (sends-to-self might give us an extra):
2126 if (ret.size() > nCount)
2127 {
2128 Array::iterator last = ret.begin();
2129 std::advance(last, nCount);
2130 ret.erase(last, ret.end());
2131 }
2132 std::reverse(ret.begin(), ret.end()); // oldest to newest
2133
2134 return ret;
2135 }
2136
2137 Value listaccounts(const Array& params, bool fHelp)
2138 {
2139 if (fHelp || params.size() > 1)
2140 throw runtime_error(
2141 "listaccounts [minconf=1]\n"
2142 "Returns Object that has account names as keys, account balances as values.");
2143
2144 int nMinDepth = 1;
2145 if (params.size() > 0)
2146 nMinDepth = params[0].get_int();
2147
2148 map<string, int64> mapAccountBalances;
2149 BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& entry, pwalletMain->mapAddressBook) {
2150 if (pwalletMain->HaveKey(entry.first)) // This address belongs to me
2151 mapAccountBalances[entry.second] = 0;
2152 }
2153
2154 for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
2155 {
2156 const CWalletTx& wtx = (*it).second;
2157 int64 nGeneratedImmature, nGeneratedMature, nFee;
2158 string strSentAccount;
2159 list<pair<CBitcoinAddress, int64> > listReceived;
2160 list<pair<CBitcoinAddress, int64> > listSent;
2161 wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount);
2162 mapAccountBalances[strSentAccount] -= nFee;
2163 BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& s, listSent)
2164 mapAccountBalances[strSentAccount] -= s.second;
2165 if (wtx.GetDepthInMainChain() >= nMinDepth)
2166 {
2167 mapAccountBalances[""] += nGeneratedMature;
2168 BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& r, listReceived)
2169 if (pwalletMain->mapAddressBook.count(r.first))
2170 mapAccountBalances[pwalletMain->mapAddressBook[r.first]] += r.second;
2171 else
2172 mapAccountBalances[""] += r.second;
2173 }
2174 }
2175
2176 list<CAccountingEntry> acentries;
2177 CWalletDB(pwalletMain->strWalletFile).ListAccountCreditDebit("*", acentries);
2178 BOOST_FOREACH(const CAccountingEntry& entry, acentries)
2179 mapAccountBalances[entry.strAccount] += entry.nCreditDebit;
2180
2181 Object ret;
2182 BOOST_FOREACH(const PAIRTYPE(string, int64)& accountBalance, mapAccountBalances) {
2183 ret.push_back(Pair(accountBalance.first, ValueFromAmount(accountBalance.second)));
2184 }
2185 return ret;
2186 }
2187
2188 Value listsinceblock(const Array& params, bool fHelp)
2189 {
2190 if (fHelp)
2191 throw runtime_error(
2192 "listsinceblock [blockid] [target-confirmations]\n"
2193 "Get all transactions in blocks since block [blockid], or all transactions if omitted");
2194
2195 CBlockIndex *pindex = NULL;
2196 int target_confirms = 1;
2197
2198 if (params.size() > 0)
2199 {
2200 uint256 blockId = 0;
2201
2202 blockId.SetHex(params[0].get_str());
2203 pindex = CBlockLocator(blockId).GetBlockIndex();
2204 }
2205
2206 if (params.size() > 1)
2207 {
2208 target_confirms = params[1].get_int();
2209
2210 if (target_confirms < 1)
2211 throw JSONRPCError(-8, "Invalid parameter");
2212 }
2213
2214 int depth = pindex ? (1 + nBestHeight - pindex->nHeight) : -1;
2215
2216 Array transactions;
2217
2218 for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); it++)
2219 {
2220 CWalletTx tx = (*it).second;
2221
2222 if (depth == -1 || tx.GetDepthInMainChain() < depth)
2223 ListTransactions(tx, "*", 0, true, transactions);
2224 }
2225
2226 uint256 lastblock;
2227
2228 if (target_confirms == 1)
2229 {
2230 printf("oops!\n");
2231 lastblock = hashBestChain;
2232 }
2233 else
2234 {
2235 int target_height = pindexBest->nHeight + 1 - target_confirms;
2236
2237 CBlockIndex *block;
2238 for (block = pindexBest;
2239 block && block->nHeight > target_height;
2240 block = block->pprev) { }
2241
2242 lastblock = block ? block->GetBlockHash() : 0;
2243 }
2244
2245 Object ret;
2246 ret.push_back(Pair("transactions", transactions));
2247 ret.push_back(Pair("lastblock", lastblock.GetHex()));
2248
2249 return ret;
2250 }
2251
2252 Value gettransaction(const Array& params, bool fHelp)
2253 {
2254 if (fHelp || params.size() != 1)
2255 throw runtime_error(
2256 "gettransaction <txid>\n"
2257 "Get detailed information about <txid>");
2258
2259 uint256 hash;
2260 hash.SetHex(params[0].get_str());
2261
2262 Object entry;
2263
2264 if (!pwalletMain->mapWallet.count(hash))
2265 throw JSONRPCError(-5, "Invalid or non-wallet transaction id");
2266 const CWalletTx& wtx = pwalletMain->mapWallet[hash];
2267
2268 int64 nCredit = wtx.GetCredit();
2269 int64 nDebit = wtx.GetDebit();
2270 int64 nNet = nCredit - nDebit;
2271 int64 nFee = (wtx.IsFromMe() ? wtx.GetValueOut() - nDebit : 0);
2272
2273 entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee)));
2274 if (wtx.IsFromMe())
2275 entry.push_back(Pair("fee", ValueFromAmount(nFee)));
2276
2277 WalletTxToJSON(pwalletMain->mapWallet[hash], entry);
2278
2279 Array details;
2280 ListTransactions(pwalletMain->mapWallet[hash], "*", 0, false, details);
2281 entry.push_back(Pair("details", details));
2282
2283 return entry;
2284 }
2285
2286
2287 Value backupwallet(const Array& params, bool fHelp)
2288 {
2289 if (fHelp || params.size() != 1)
2290 throw runtime_error(
2291 "backupwallet <destination>\n"
2292 "Safely copies wallet.dat to destination, which can be a directory or a path with filename.");
2293
2294 string strDest = params[0].get_str();
2295 BackupWallet(*pwalletMain, strDest);
2296
2297 return Value::null;
2298 }
2299
2300
2301 Value keypoolrefill(const Array& params, bool fHelp)
2302 {
2303 if (pwalletMain->IsCrypted() && (fHelp || params.size() > 0))
2304 throw runtime_error(
2305 "keypoolrefill\n"
2306 "Fills the keypool, requires wallet passphrase to be set.");
2307 if (!pwalletMain->IsCrypted() && (fHelp || params.size() > 0))
2308 throw runtime_error(
2309 "keypoolrefill\n"
2310 "Fills the keypool.");
2311
2312 if (pwalletMain->IsLocked())
2313 throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
2314
2315 pwalletMain->TopUpKeyPool();
2316
2317 if (pwalletMain->GetKeyPoolSize() < GetArg("-keypool", 100))
2318 throw JSONRPCError(-4, "Error refreshing keypool.");
2319
2320 return Value::null;
2321 }
2322
2323
2324 void ThreadTopUpKeyPool(void* parg)
2325 {
2326 pwalletMain->TopUpKeyPool();
2327 }
2328
2329 void ThreadCleanWalletPassphrase(void* parg)
2330 {
2331 int64 nMyWakeTime = GetTimeMillis() + *((int64*)parg) * 1000;
2332
2333 ENTER_CRITICAL_SECTION(cs_nWalletUnlockTime);
2334
2335 if (nWalletUnlockTime == 0)
2336 {
2337 nWalletUnlockTime = nMyWakeTime;
2338
2339 do
2340 {
2341 if (nWalletUnlockTime==0)
2342 break;
2343 int64 nToSleep = nWalletUnlockTime - GetTimeMillis();
2344 if (nToSleep <= 0)
2345 break;
2346
2347 LEAVE_CRITICAL_SECTION(cs_nWalletUnlockTime);
2348 Sleep(nToSleep);
2349 ENTER_CRITICAL_SECTION(cs_nWalletUnlockTime);
2350
2351 } while(1);
2352
2353 if (nWalletUnlockTime)
2354 {
2355 nWalletUnlockTime = 0;
2356 pwalletMain->Lock();
2357 }
2358 }
2359 else
2360 {
2361 if (nWalletUnlockTime < nMyWakeTime)
2362 nWalletUnlockTime = nMyWakeTime;
2363 }
2364
2365 LEAVE_CRITICAL_SECTION(cs_nWalletUnlockTime);
2366
2367 delete (int64*)parg;
2368 }
2369
2370 Value walletpassphrase(const Array& params, bool fHelp)
2371 {
2372 if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2))
2373 throw runtime_error(
2374 "walletpassphrase <passphrase> <timeout>\n"
2375 "Stores the wallet decryption key in memory for <timeout> seconds.");
2376 if (fHelp)
2377 return true;
2378 if (!pwalletMain->IsCrypted())
2379 throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletpassphrase was called.");
2380
2381 if (!pwalletMain->IsLocked())
2382 throw JSONRPCError(-17, "Error: Wallet is already unlocked.");
2383
2384 // Note that the walletpassphrase is stored in params[0] which is not mlock()ed
2385 SecureString strWalletPass;
2386 strWalletPass.reserve(100);
2387 // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
2388 // Alternately, find a way to make params[0] mlock()'d to begin with.
2389 strWalletPass = params[0].get_str().c_str();
2390
2391 if (strWalletPass.length() > 0)
2392 {
2393 if (!pwalletMain->Unlock(strWalletPass))
2394 throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect.");
2395 }
2396 else
2397 throw runtime_error(
2398 "walletpassphrase <passphrase> <timeout>\n"
2399 "Stores the wallet decryption key in memory for <timeout> seconds.");
2400
2401 CreateThread(ThreadTopUpKeyPool, NULL);
2402 int64* pnSleepTime = new int64(params[1].get_int64());
2403 CreateThread(ThreadCleanWalletPassphrase, pnSleepTime);
2404
2405 return Value::null;
2406 }
2407
2408
2409 Value walletpassphrasechange(const Array& params, bool fHelp)
2410 {
2411 if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2))
2412 throw runtime_error(
2413 "walletpassphrasechange <oldpassphrase> <newpassphrase>\n"
2414 "Changes the wallet passphrase from <oldpassphrase> to <newpassphrase>.");
2415 if (fHelp)
2416 return true;
2417 if (!pwalletMain->IsCrypted())
2418 throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletpassphrasechange was called.");
2419
2420 // TODO: get rid of these .c_str() calls by implementing SecureString::operator=(std::string)
2421 // Alternately, find a way to make params[0] mlock()'d to begin with.
2422 SecureString strOldWalletPass;
2423 strOldWalletPass.reserve(100);
2424 strOldWalletPass = params[0].get_str().c_str();
2425
2426 SecureString strNewWalletPass;
2427 strNewWalletPass.reserve(100);
2428 strNewWalletPass = params[1].get_str().c_str();
2429
2430 if (strOldWalletPass.length() < 1 || strNewWalletPass.length() < 1)
2431 throw runtime_error(
2432 "walletpassphrasechange <oldpassphrase> <newpassphrase>\n"
2433 "Changes the wallet passphrase from <oldpassphrase> to <newpassphrase>.");
2434
2435 if (!pwalletMain->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass))
2436 throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect.");
2437
2438 return Value::null;
2439 }
2440
2441
2442 Value walletlock(const Array& params, bool fHelp)
2443 {
2444 if (pwalletMain->IsCrypted() && (fHelp || params.size() != 0))
2445 throw runtime_error(
2446 "walletlock\n"
2447 "Removes the wallet encryption key from memory, locking the wallet.\n"
2448 "After calling this method, you will need to call walletpassphrase again\n"
2449 "before being able to call any methods which require the wallet to be unlocked.");
2450 if (fHelp)
2451 return true;
2452 if (!pwalletMain->IsCrypted())
2453 throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletlock was called.");
2454
2455 CRITICAL_BLOCK(cs_nWalletUnlockTime)
2456 {
2457 pwalletMain->Lock();
2458 nWalletUnlockTime = 0;
2459 }
2460
2461 return Value::null;
2462 }
2463
2464
2465 Value encryptwallet(const Array& params, bool fHelp)
2466 {
2467 if (!pwalletMain->IsCrypted() && (fHelp || params.size() != 1))
2468 throw runtime_error(
2469 "encryptwallet <passphrase>\n"
2470 "Encrypts the wallet with <passphrase>.");
2471 if (fHelp)
2472 return true;
2473 if (pwalletMain->IsCrypted())
2474 throw JSONRPCError(-15, "Error: running with an encrypted wallet, but encryptwallet was called.");
2475
2476 #ifdef QT_GUI
2477 // shutting down via RPC while the GUI is running does not work (yet):
2478 throw runtime_error("Not Yet Implemented: use GUI to encrypt wallet, not RPC command");
2479 #endif
2480
2481 // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
2482 // Alternately, find a way to make params[0] mlock()'d to begin with.
2483 SecureString strWalletPass;
2484 strWalletPass.reserve(100);
2485 strWalletPass = params[0].get_str().c_str();
2486
2487 if (strWalletPass.length() < 1)
2488 throw runtime_error(
2489 "encryptwallet <passphrase>\n"
2490 "Encrypts the wallet with <passphrase>.");
2491
2492 if (!pwalletMain->EncryptWallet(strWalletPass))
2493 throw JSONRPCError(-16, "Error: Failed to encrypt the wallet.");
2494
2495 // BDB seems to have a bad habit of writing old data into
2496 // slack space in .dat files; that is bad if the old data is
2497 // unencrypted private keys. So:
2498 CreateThread(Shutdown, NULL);
2499 return "wallet encrypted; bitcoin server stopping, restart to run with encrypted wallet";
2500 }
2501
2502
2503 Value validateaddress(const Array& params, bool fHelp)
2504 {
2505 if (fHelp || params.size() != 1)
2506 throw runtime_error(
2507 "validateaddress <bitcoinaddress>\n"
2508 "Return information about <bitcoinaddress>.");
2509
2510 CBitcoinAddress address(params[0].get_str());
2511 bool isValid = address.IsValid();
2512
2513 Object ret;
2514 ret.push_back(Pair("isvalid", isValid));
2515 if (isValid)
2516 {
2517 // Call Hash160ToAddress() so we always return current ADDRESSVERSION
2518 // version of the address:
2519 string currentAddress = address.ToString();
2520 ret.push_back(Pair("address", currentAddress));
2521 ret.push_back(Pair("ismine", (pwalletMain->HaveKey(address) > 0)));
2522 if (pwalletMain->mapAddressBook.count(address))
2523 ret.push_back(Pair("account", pwalletMain->mapAddressBook[address]));
2524 }
2525 return ret;
2526 }
2527
2528
2529 Value getwork(const Array& params, bool fHelp)
2530 {
2531 if (fHelp || params.size() > 1)
2532 throw runtime_error(
2533 "getwork [data]\n"
2534 "If [data] is not specified, returns formatted hash data to work on:\n"
2535 " \"midstate\" : precomputed hash state after hashing the first half of the data (DEPRECATED)\n" // deprecated
2536 " \"data\" : block data\n"
2537 " \"hash1\" : formatted hash buffer for second hash (DEPRECATED)\n" // deprecated
2538 " \"target\" : little endian hash target\n"
2539 "If [data] is specified, tries to solve the block and returns true if it was successful.");
2540
2541 if (vNodes.empty())
2542 throw JSONRPCError(-9, "Bitcoin is not connected!");
2543
2544 if (IsInitialBlockDownload())
2545 throw JSONRPCError(-10, "Bitcoin is downloading blocks...");
2546
2547 typedef map<uint256, pair<CBlock*, CScript> > mapNewBlock_t;
2548 static mapNewBlock_t mapNewBlock;
2549 static vector<CBlock*> vNewBlock;
2550 static CReserveKey reservekey(pwalletMain);
2551
2552 if (params.size() == 0)
2553 {
2554 // Update block
2555 static unsigned int nTransactionsUpdatedLast;
2556 static CBlockIndex* pindexPrev;
2557 static int64 nStart;
2558 static CBlock* pblock;
2559 if (pindexPrev != pindexBest ||
2560 (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60))
2561 {
2562 if (pindexPrev != pindexBest)
2563 {
2564 // Deallocate old blocks since they're obsolete now
2565 mapNewBlock.clear();
2566 BOOST_FOREACH(CBlock* pblock, vNewBlock)
2567 delete pblock;
2568 vNewBlock.clear();
2569 }
2570 nTransactionsUpdatedLast = nTransactionsUpdated;
2571 pindexPrev = pindexBest;
2572 nStart = GetTime();
2573
2574 // Create new block
2575 pblock = CreateNewBlock(reservekey);
2576 if (!pblock)
2577 throw JSONRPCError(-7, "Out of memory");
2578 vNewBlock.push_back(pblock);
2579 }
2580
2581 // Update nTime
2582 pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
2583 pblock->nNonce = 0;
2584
2585 // Update nExtraNonce
2586 static unsigned int nExtraNonce = 0;
2587 IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);
2588
2589 // Save
2590 mapNewBlock[pblock->hashMerkleRoot] = make_pair(pblock, pblock->vtx[0].vin[0].scriptSig);
2591
2592 // Prebuild hash buffers
2593 char pmidstate[32];
2594 char pdata[128];
2595 char phash1[64];
2596 FormatHashBuffers(pblock, pmidstate, pdata, phash1);
2597
2598 uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
2599
2600 Object result;
2601 result.push_back(Pair("midstate", HexStr(BEGIN(pmidstate), END(pmidstate)))); // deprecated
2602 result.push_back(Pair("data", HexStr(BEGIN(pdata), END(pdata))));
2603 result.push_back(Pair("hash1", HexStr(BEGIN(phash1), END(phash1)))); // deprecated
2604 result.push_back(Pair("target", HexStr(BEGIN(hashTarget), END(hashTarget))));
2605 return result;
2606 }
2607 else
2608 {
2609 // Parse parameters
2610 vector<unsigned char> vchData = ParseHex(params[0].get_str());
2611 if (vchData.size() != 128)
2612 throw JSONRPCError(-8, "Invalid parameter");
2613 CBlock* pdata = (CBlock*)&vchData[0];
2614
2615 // Byte reverse
2616 for (int i = 0; i < 128/4; i++)
2617 ((unsigned int*)pdata)[i] = ByteReverse(((unsigned int*)pdata)[i]);
2618
2619 // Get saved block
2620 if (!mapNewBlock.count(pdata->hashMerkleRoot))
2621 return false;
2622 CBlock* pblock = mapNewBlock[pdata->hashMerkleRoot].first;
2623
2624 pblock->nTime = pdata->nTime;
2625 pblock->nNonce = pdata->nNonce;
2626 pblock->vtx[0].vin[0].scriptSig = mapNewBlock[pdata->hashMerkleRoot].second;
2627 pblock->hashMerkleRoot = pblock->BuildMerkleTree();
2628
2629 return CheckWork(pblock, *pwalletMain, reservekey);
2630 }
2631 }
2632
2633
2634 Value getmemorypool(const Array& params, bool fHelp)
2635 {
2636 if (fHelp || params.size() > 1)
2637 throw runtime_error(
2638 "getmemorypool [data]\n"
2639 "If [data] is not specified, returns data needed to construct a block to work on:\n"
2640 " \"version\" : block version\n"
2641 " \"previousblockhash\" : hash of current highest block\n"
2642 " \"transactions\" : contents of non-coinbase transactions that should be included in the next block\n"
2643 " \"coinbasevalue\" : maximum allowable input to coinbase transaction, including the generation award and transaction fees\n"
2644 " \"time\" : timestamp appropriate for next block\n"
2645 " \"bits\" : compressed target of next block\n"
2646 "If [data] is specified, tries to solve the block and returns true if it was successful.");
2647
2648 if (params.size() == 0)
2649 {
2650 if (vNodes.empty())
2651 throw JSONRPCError(-9, "Bitcoin is not connected!");
2652
2653 if (IsInitialBlockDownload())
2654 throw JSONRPCError(-10, "Bitcoin is downloading blocks...");
2655
2656 static CReserveKey reservekey(pwalletMain);
2657
2658 // Update block
2659 static unsigned int nTransactionsUpdatedLast;
2660 static CBlockIndex* pindexPrev;
2661 static int64 nStart;
2662 static CBlock* pblock;
2663 if (pindexPrev != pindexBest ||
2664 (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 5))
2665 {
2666 nTransactionsUpdatedLast = nTransactionsUpdated;
2667 pindexPrev = pindexBest;
2668 nStart = GetTime();
2669
2670 // Create new block
2671 if(pblock)
2672 delete pblock;
2673 pblock = CreateNewBlock(reservekey);
2674 if (!pblock)
2675 throw JSONRPCError(-7, "Out of memory");
2676 }
2677
2678 // Update nTime
2679 pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
2680 pblock->nNonce = 0;
2681
2682 Array transactions;
2683 BOOST_FOREACH(CTransaction tx, pblock->vtx) {
2684 if(tx.IsCoinBase())
2685 continue;
2686
2687 CDataStream ssTx;
2688 ssTx << tx;
2689
2690 transactions.push_back(HexStr(ssTx.begin(), ssTx.end()));
2691 }
2692
2693 Object result;
2694 result.push_back(Pair("version", pblock->nVersion));
2695 result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex()));
2696 result.push_back(Pair("transactions", transactions));
2697 result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue));
2698 result.push_back(Pair("time", (int64_t)pblock->nTime));
2699
2700 union {
2701 int32_t nBits;
2702 char cBits[4];
2703 } uBits;
2704 uBits.nBits = htonl((int32_t)pblock->nBits);
2705 result.push_back(Pair("bits", HexStr(BEGIN(uBits.cBits), END(uBits.cBits))));
2706
2707 return result;
2708 }
2709 else
2710 {
2711 // Parse parameters
2712 CDataStream ssBlock(ParseHex(params[0].get_str()));
2713 CBlock pblock;
2714 ssBlock >> pblock;
2715
2716 return ProcessBlock(NULL, &pblock);
2717 }
2718 }
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730 //
2731 // Call Table
2732 //
2733
2734 pair<string, rpcfn_type> pCallTable[] =
2735 {
2736 make_pair("help", &help),
2737 make_pair("stop", &stop),
2738 make_pair("getblockcount", &getblockcount),
2739 make_pair("getblocknumber", &getblocknumber),
2740 make_pair("getconnectioncount", &getconnectioncount),
2741 make_pair("getdifficulty", &getdifficulty),
2742 make_pair("getgenerate", &getgenerate),
2743 make_pair("setgenerate", &setgenerate),
2744 make_pair("gethashespersec", &gethashespersec),
2745 make_pair("getinfo", &getinfo),
2746 make_pair("getnewaddress", &getnewaddress),
2747 make_pair("getaccountaddress", &getaccountaddress),
2748 make_pair("setaccount", &setaccount),
2749 make_pair("getaccount", &getaccount),
2750 make_pair("getaddressesbyaccount", &getaddressesbyaccount),
2751 make_pair("sendtoaddress", &sendtoaddress),
2752 make_pair("getreceivedbyaddress", &getreceivedbyaddress),
2753 make_pair("getreceivedbyaccount", &getreceivedbyaccount),
2754 make_pair("listreceivedbyaddress", &listreceivedbyaddress),
2755 make_pair("listreceivedbyaccount", &listreceivedbyaccount),
2756 make_pair("backupwallet", &backupwallet),
2757 make_pair("keypoolrefill", &keypoolrefill),
2758 make_pair("walletpassphrase", &walletpassphrase),
2759 make_pair("walletpassphrasechange", &walletpassphrasechange),
2760 make_pair("walletlock", &walletlock),
2761 make_pair("encryptwallet", &encryptwallet),
2762 make_pair("validateaddress", &validateaddress),
2763 make_pair("getbalance", &getbalance),
2764 make_pair("move", &movecmd),
2765 make_pair("sendfrom", &sendfrom),
2766 make_pair("sendmany", &sendmany),
2767 make_pair("gettransaction", &gettransaction),
2768 make_pair("listtransactions", &listtransactions),
2769 make_pair("signmessage", &signmessage),
2770 make_pair("verifymessage", &verifymessage),
2771 make_pair("getwork", &getwork),
2772 make_pair("listaccounts", &listaccounts),
2773 make_pair("settxfee", &settxfee),
2774 make_pair("getmemorypool", &getmemorypool),
2775 make_pair("listsinceblock", &listsinceblock),
2776 };
2777 map<string, rpcfn_type> mapCallTable(pCallTable, pCallTable + sizeof(pCallTable)/sizeof(pCallTable[0]));
2778
2779 string pAllowInSafeMode[] =
2780 {
2781 "help",
2782 "stop",
2783 "getblockcount",
2784 "getblocknumber", // deprecated
2785 "getconnectioncount",
2786 "getdifficulty",
2787 "getgenerate",
2788 "setgenerate",
2789 "gethashespersec",
2790 "getinfo",
2791 "getnewaddress",
2792 "getaccountaddress",
2793 "getaccount",
2794 "getaddressesbyaccount",
2795 "backupwallet",
2796 "keypoolrefill",
2797 "walletpassphrase",
2798 "walletlock",
2799 "validateaddress",
2800 "getwork",
2801 "getmemorypool",
2802 };
2803 set<string> setAllowInSafeMode(pAllowInSafeMode, pAllowInSafeMode + sizeof(pAllowInSafeMode)/sizeof(pAllowInSafeMode[0]));
2804
2805
2806
2807
2808 //
2809 // HTTP protocol
2810 //
2811 // This ain't Apache. We're just using HTTP header for the length field
2812 // and to be compatible with other JSON-RPC implementations.
2813 //
2814
2815 string HTTPPost(const string& strMsg, const map<string,string>& mapRequestHeaders)
2816 {
2817 ostringstream s;
2818 s << "POST / HTTP/1.1\r\n"
2819 << "User-Agent: bitcoin-json-rpc/" << FormatFullVersion() << "\r\n"
2820 << "Host: 127.0.0.1\r\n"
2821 << "Content-Type: application/json\r\n"
2822 << "Content-Length: " << strMsg.size() << "\r\n"
2823 << "Connection: close\r\n"
2824 << "Accept: application/json\r\n";
2825 BOOST_FOREACH(const PAIRTYPE(string, string)& item, mapRequestHeaders)
2826 s << item.first << ": " << item.second << "\r\n";
2827 s << "\r\n" << strMsg;
2828
2829 return s.str();
2830 }
2831
2832 string rfc1123Time()
2833 {
2834 char buffer[64];
2835 time_t now;
2836 time(&now);
2837 struct tm* now_gmt = gmtime(&now);
2838 string locale(setlocale(LC_TIME, NULL));
2839 setlocale(LC_TIME, "C"); // we want posix (aka "C") weekday/month strings
2840 strftime(buffer, sizeof(buffer), "%a, %d %b %Y %H:%M:%S +0000", now_gmt);
2841 setlocale(LC_TIME, locale.c_str());
2842 return string(buffer);
2843 }
2844
2845 static string HTTPReply(int nStatus, const string& strMsg)
2846 {
2847 if (nStatus == 401)
2848 return strprintf("HTTP/1.0 401 Authorization Required\r\n"
2849 "Date: %s\r\n"
2850 "Server: bitcoin-json-rpc/%s\r\n"
2851 "WWW-Authenticate: Basic realm=\"jsonrpc\"\r\n"
2852 "Content-Type: text/html\r\n"
2853 "Content-Length: 296\r\n"
2854 "\r\n"
2855 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\r\n"
2856 "\"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd\">\r\n"
2857 "<HTML>\r\n"
2858 "<HEAD>\r\n"
2859 "<TITLE>Error</TITLE>\r\n"
2860 "<META HTTP-EQUIV='Content-Type' CONTENT='text/html; charset=ISO-8859-1'>\r\n"
2861 "</HEAD>\r\n"
2862 "<BODY><H1>401 Unauthorized.</H1></BODY>\r\n"
2863 "</HTML>\r\n", rfc1123Time().c_str(), FormatFullVersion().c_str());
2864 const char *cStatus;
2865 if (nStatus == 200) cStatus = "OK";
2866 else if (nStatus == 400) cStatus = "Bad Request";
2867 else if (nStatus == 403) cStatus = "Forbidden";
2868 else if (nStatus == 404) cStatus = "Not Found";
2869 else if (nStatus == 500) cStatus = "Internal Server Error";
2870 else cStatus = "";
2871 return strprintf(
2872 "HTTP/1.1 %d %s\r\n"
2873 "Date: %s\r\n"
2874 "Connection: close\r\n"
2875 "Content-Length: %d\r\n"
2876 "Content-Type: application/json\r\n"
2877 "Server: bitcoin-json-rpc/%s\r\n"
2878 "\r\n"
2879 "%s",
2880 nStatus,
2881 cStatus,
2882 rfc1123Time().c_str(),
2883 strMsg.size(),
2884 FormatFullVersion().c_str(),
2885 strMsg.c_str());
2886 }
2887
2888 int ReadHTTPStatus(std::basic_istream<char>& stream)
2889 {
2890 string str;
2891 getline(stream, str);
2892 vector<string> vWords;
2893 boost::split(vWords, str, boost::is_any_of(" "));
2894 if (vWords.size() < 2)
2895 return 500;
2896 return atoi(vWords[1].c_str());
2897 }
2898
2899 int ReadHTTPHeader(std::basic_istream<char>& stream, map<string, string>& mapHeadersRet)
2900 {
2901 int nLen = 0;
2902 loop
2903 {
2904 string str;
2905 std::getline(stream, str);
2906 if (str.empty() || str == "\r")
2907 break;
2908 string::size_type nColon = str.find(":");
2909 if (nColon != string::npos)
2910 {
2911 string strHeader = str.substr(0, nColon);
2912 boost::trim(strHeader);
2913 boost::to_lower(strHeader);
2914 string strValue = str.substr(nColon+1);
2915 boost::trim(strValue);
2916 mapHeadersRet[strHeader] = strValue;
2917 if (strHeader == "content-length")
2918 nLen = atoi(strValue.c_str());
2919 }
2920 }
2921 return nLen;
2922 }
2923
2924 int ReadHTTP(std::basic_istream<char>& stream, map<string, string>& mapHeadersRet, string& strMessageRet)
2925 {
2926 mapHeadersRet.clear();
2927 strMessageRet = "";
2928
2929 // Read status
2930 int nStatus = ReadHTTPStatus(stream);
2931
2932 // Read header
2933 int nLen = ReadHTTPHeader(stream, mapHeadersRet);
2934 if (nLen < 0 || nLen > MAX_SIZE)
2935 return 500;
2936
2937 // Read message
2938 if (nLen > 0)
2939 {
2940 vector<char> vch(nLen);
2941 stream.read(&vch[0], nLen);
2942 strMessageRet = string(vch.begin(), vch.end());
2943 }
2944
2945 return nStatus;
2946 }
2947
2948 bool HTTPAuthorized(map<string, string>& mapHeaders)
2949 {
2950 string strAuth = mapHeaders["authorization"];
2951 if (strAuth.substr(0,6) != "Basic ")
2952 return false;
2953 string strUserPass64 = strAuth.substr(6); boost::trim(strUserPass64);
2954 string strUserPass = DecodeBase64(strUserPass64);
2955 return strUserPass == strRPCUserColonPass;
2956 }
2957
2958 //
2959 // JSON-RPC protocol. Bitcoin speaks version 1.0 for maximum compatibility,
2960 // but uses JSON-RPC 1.1/2.0 standards for parts of the 1.0 standard that were
2961 // unspecified (HTTP errors and contents of 'error').
2962 //
2963 // 1.0 spec: http://json-rpc.org/wiki/specification
2964 // 1.2 spec: http://groups.google.com/group/json-rpc/web/json-rpc-over-http
2965 // http://www.codeproject.com/KB/recipes/JSON_Spirit.aspx
2966 //
2967
2968 string JSONRPCRequest(const string& strMethod, const Array& params, const Value& id)
2969 {
2970 Object request;
2971 request.push_back(Pair("method", strMethod));
2972 request.push_back(Pair("params", params));
2973 request.push_back(Pair("id", id));
2974 return write_string(Value(request), false) + "\n";
2975 }
2976
2977 string JSONRPCReply(const Value& result, const Value& error, const Value& id)
2978 {
2979 Object reply;
2980 if (error.type() != null_type)
2981 reply.push_back(Pair("result", Value::null));
2982 else
2983 reply.push_back(Pair("result", result));
2984 reply.push_back(Pair("error", error));
2985 reply.push_back(Pair("id", id));
2986 return write_string(Value(reply), false) + "\n";
2987 }
2988
2989 void ErrorReply(std::ostream& stream, const Object& objError, const Value& id)
2990 {
2991 // Send error reply from json-rpc error object
2992 int nStatus = 500;
2993 int code = find_value(objError, "code").get_int();
2994 if (code == -32600) nStatus = 400;
2995 else if (code == -32601) nStatus = 404;
2996 string strReply = JSONRPCReply(Value::null, objError, id);
2997 stream << HTTPReply(nStatus, strReply) << std::flush;
2998 }
2999
3000 bool ClientAllowed(const string& strAddress)
3001 {
3002 if (strAddress == asio::ip::address_v4::loopback().to_string())
3003 return true;
3004 const vector<string>& vAllow = mapMultiArgs["-rpcallowip"];
3005 BOOST_FOREACH(string strAllow, vAllow)
3006 if (WildcardMatch(strAddress, strAllow))
3007 return true;
3008 return false;
3009 }
3010
3011 #ifdef USE_SSL
3012 //
3013 // IOStream device that speaks SSL but can also speak non-SSL
3014 //
3015 class SSLIOStreamDevice : public iostreams::device<iostreams::bidirectional> {
3016 public:
3017 SSLIOStreamDevice(SSLStream &streamIn, bool fUseSSLIn) : stream(streamIn)
3018 {
3019 fUseSSL = fUseSSLIn;
3020 fNeedHandshake = fUseSSLIn;
3021 }
3022
3023 void handshake(ssl::stream_base::handshake_type role)
3024 {
3025 if (!fNeedHandshake) return;
3026 fNeedHandshake = false;
3027 stream.handshake(role);
3028 }
3029 std::streamsize read(char* s, std::streamsize n)
3030 {
3031 handshake(ssl::stream_base::server); // HTTPS servers read first
3032 if (fUseSSL) return stream.read_some(asio::buffer(s, n));
3033 return stream.next_layer().read_some(asio::buffer(s, n));
3034 }
3035 std::streamsize write(const char* s, std::streamsize n)
3036 {
3037 handshake(ssl::stream_base::client); // HTTPS clients write first
3038 if (fUseSSL) return asio::write(stream, asio::buffer(s, n));
3039 return asio::write(stream.next_layer(), asio::buffer(s, n));
3040 }
3041 bool connect(const std::string& server, const std::string& port)
3042 {
3043 ip::tcp::resolver resolver(stream.get_io_service());
3044 ip::tcp::resolver::query query(server.c_str(), port.c_str());
3045 ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
3046 ip::tcp::resolver::iterator end;
3047 boost::system::error_code error = asio::error::host_not_found;
3048 while (error && endpoint_iterator != end)
3049 {
3050 stream.lowest_layer().close();
3051 stream.lowest_layer().connect(*endpoint_iterator++, error);
3052 }
3053 if (error)
3054 return false;
3055 return true;
3056 }
3057
3058 private:
3059 bool fNeedHandshake;
3060 bool fUseSSL;
3061 SSLStream& stream;
3062 };
3063 #endif
3064
3065 void ThreadRPCServer(void* parg)
3066 {
3067 IMPLEMENT_RANDOMIZE_STACK(ThreadRPCServer(parg));
3068 try
3069 {
3070 vnThreadsRunning[4]++;
3071 ThreadRPCServer2(parg);
3072 vnThreadsRunning[4]--;
3073 }
3074 catch (std::exception& e) {
3075 vnThreadsRunning[4]--;
3076 PrintException(&e, "ThreadRPCServer()");
3077 } catch (...) {
3078 vnThreadsRunning[4]--;
3079 PrintException(NULL, "ThreadRPCServer()");
3080 }
3081 printf("ThreadRPCServer exiting\n");
3082 }
3083
3084 void ThreadRPCServer2(void* parg)
3085 {
3086 printf("ThreadRPCServer started\n");
3087
3088 strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"];
3089 if (strRPCUserColonPass == ":")
3090 {
3091 unsigned char rand_pwd[32];
3092 RAND_bytes(rand_pwd, 32);
3093 string strWhatAmI = "To use bitcoind";
3094 if (mapArgs.count("-server"))
3095 strWhatAmI = strprintf(_("To use the %s option"), "\"-server\"");
3096 else if (mapArgs.count("-daemon"))
3097 strWhatAmI = strprintf(_("To use the %s option"), "\"-daemon\"");
3098 PrintConsole(
3099 _("Error: %s, you must set a rpcpassword in the configuration file:\n %s\n"
3100 "It is recommended you use the following random password:\n"
3101 "rpcuser=bitcoinrpc\n"
3102 "rpcpassword=%s\n"
3103 "(you do not need to remember this password)\n"
3104 "If the file does not exist, create it with owner-readable-only file permissions.\n"),
3105 strWhatAmI.c_str(),
3106 GetConfigFile().c_str(),
3107 EncodeBase58(&rand_pwd[0],&rand_pwd[0]+32).c_str());
3108 #ifndef QT_GUI
3109 CreateThread(Shutdown, NULL);
3110 #endif
3111 return;
3112 }
3113
3114 bool fUseSSL = GetBoolArg("-rpcssl");
3115 asio::ip::address bindAddress = mapArgs.count("-rpcallowip") ? asio::ip::address_v4::any() : asio::ip::address_v4::loopback();
3116
3117 asio::io_service io_service;
3118 ip::tcp::endpoint endpoint(bindAddress, GetArg("-rpcport", 8332));
3119 ip::tcp::acceptor acceptor(io_service, endpoint);
3120
3121 acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
3122
3123 #ifdef USE_SSL
3124 ssl::context context(io_service, ssl::context::sslv23);
3125 if (fUseSSL)
3126 {
3127 context.set_options(ssl::context::no_sslv2);
3128 filesystem::path certfile = GetArg("-rpcsslcertificatechainfile", "server.cert");
3129 if (!certfile.is_complete()) certfile = filesystem::path(GetDataDir()) / certfile;
3130 if (filesystem::exists(certfile)) context.use_certificate_chain_file(certfile.string().c_str());
3131 else printf("ThreadRPCServer ERROR: missing server certificate file %s\n", certfile.string().c_str());
3132 filesystem::path pkfile = GetArg("-rpcsslprivatekeyfile", "server.pem");
3133 if (!pkfile.is_complete()) pkfile = filesystem::path(GetDataDir()) / pkfile;
3134 if (filesystem::exists(pkfile)) context.use_private_key_file(pkfile.string().c_str(), ssl::context::pem);
3135 else printf("ThreadRPCServer ERROR: missing server private key file %s\n", pkfile.string().c_str());
3136
3137 string ciphers = GetArg("-rpcsslciphers",
3138 "TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH");
3139 SSL_CTX_set_cipher_list(context.impl(), ciphers.c_str());
3140 }
3141 #else
3142 if (fUseSSL)
3143 throw runtime_error("-rpcssl=1, but bitcoin compiled without full openssl libraries.");
3144 #endif
3145
3146 loop
3147 {
3148 // Accept connection
3149 #ifdef USE_SSL
3150 SSLStream sslStream(io_service, context);
3151 SSLIOStreamDevice d(sslStream, fUseSSL);
3152 iostreams::stream<SSLIOStreamDevice> stream(d);
3153 #else
3154 ip::tcp::iostream stream;
3155 #endif
3156
3157 ip::tcp::endpoint peer;
3158 vnThreadsRunning[4]--;
3159 #ifdef USE_SSL
3160 acceptor.accept(sslStream.lowest_layer(), peer);
3161 #else
3162 acceptor.accept(*stream.rdbuf(), peer);
3163 #endif
3164 vnThreadsRunning[4]++;
3165 if (fShutdown)
3166 return;
3167
3168 // Restrict callers by IP
3169 if (!ClientAllowed(peer.address().to_string()))
3170 {
3171 // Only send a 403 if we're not using SSL to prevent a DoS during the SSL handshake.
3172 if (!fUseSSL)
3173 stream << HTTPReply(403, "") << std::flush;
3174 continue;
3175 }
3176
3177 map<string, string> mapHeaders;
3178 string strRequest;
3179
3180 boost::thread api_caller(ReadHTTP, boost::ref(stream), boost::ref(mapHeaders), boost::ref(strRequest));
3181 if (!api_caller.timed_join(boost::posix_time::seconds(GetArg("-rpctimeout", 30))))
3182 { // Timed out:
3183 acceptor.cancel();
3184 printf("ThreadRPCServer ReadHTTP timeout\n");
3185 continue;
3186 }
3187
3188 // Check authorization
3189 if (mapHeaders.count("authorization") == 0)
3190 {
3191 stream << HTTPReply(401, "") << std::flush;
3192 continue;
3193 }
3194 if (!HTTPAuthorized(mapHeaders))
3195 {
3196 printf("ThreadRPCServer incorrect password attempt from %s\n",peer.address().to_string().c_str());
3197 /* Deter brute-forcing short passwords.
3198 If this results in a DOS the user really
3199 shouldn't have their RPC port exposed.*/
3200 if (mapArgs["-rpcpassword"].size() < 20)
3201 Sleep(250);
3202
3203 stream << HTTPReply(401, "") << std::flush;
3204 continue;
3205 }
3206
3207 Value id = Value::null;
3208 try
3209 {
3210 // Parse request
3211 Value valRequest;
3212 if (!read_string(strRequest, valRequest) || valRequest.type() != obj_type)
3213 throw JSONRPCError(-32700, "Parse error");
3214 const Object& request = valRequest.get_obj();
3215
3216 // Parse id now so errors from here on will have the id
3217 id = find_value(request, "id");
3218
3219 // Parse method
3220 Value valMethod = find_value(request, "method");
3221 if (valMethod.type() == null_type)
3222 throw JSONRPCError(-32600, "Missing method");
3223 if (valMethod.type() != str_type)
3224 throw JSONRPCError(-32600, "Method must be a string");
3225 string strMethod = valMethod.get_str();
3226 if (strMethod != "getwork" && strMethod != "getmemorypool")
3227 printf("ThreadRPCServer method=%s\n", strMethod.c_str());
3228
3229 // Parse params
3230 Value valParams = find_value(request, "params");
3231 Array params;
3232 if (valParams.type() == array_type)
3233 params = valParams.get_array();
3234 else if (valParams.type() == null_type)
3235 params = Array();
3236 else
3237 throw JSONRPCError(-32600, "Params must be an array");
3238
3239 // Find method
3240 map<string, rpcfn_type>::iterator mi = mapCallTable.find(strMethod);
3241 if (mi == mapCallTable.end())
3242 throw JSONRPCError(-32601, "Method not found");
3243
3244 // Observe safe mode
3245 string strWarning = GetWarnings("rpc");
3246 if (strWarning != "" && !GetBoolArg("-disablesafemode") && !setAllowInSafeMode.count(strMethod))
3247 throw JSONRPCError(-2, string("Safe mode: ") + strWarning);
3248
3249 try
3250 {
3251 // Execute
3252 Value result;
3253 CRITICAL_BLOCK(cs_main)
3254 CRITICAL_BLOCK(pwalletMain->cs_wallet)
3255 result = (*(*mi).second)(params, false);
3256
3257 // Send reply
3258 string strReply = JSONRPCReply(result, Value::null, id);
3259 stream << HTTPReply(200, strReply) << std::flush;
3260 }
3261 catch (std::exception& e)
3262 {
3263 ErrorReply(stream, JSONRPCError(-1, e.what()), id);
3264 }
3265 }
3266 catch (Object& objError)
3267 {
3268 ErrorReply(stream, objError, id);
3269 }
3270 catch (std::exception& e)
3271 {
3272 ErrorReply(stream, JSONRPCError(-32700, e.what()), id);
3273 }
3274 }
3275 }
3276
3277
3278
3279
3280 Object CallRPC(const string& strMethod, const Array& params)
3281 {
3282 if (mapArgs["-rpcuser"] == "" && mapArgs["-rpcpassword"] == "")
3283 throw runtime_error(strprintf(
3284 _("You must set rpcpassword=<password> in the configuration file:\n%s\n"
3285 "If the file does not exist, create it with owner-readable-only file permissions."),
3286 GetConfigFile().c_str()));
3287
3288 // Connect to localhost
3289 bool fUseSSL = GetBoolArg("-rpcssl");
3290 #ifdef USE_SSL
3291 asio::io_service io_service;
3292 ssl::context context(io_service, ssl::context::sslv23);
3293 context.set_options(ssl::context::no_sslv2);
3294 SSLStream sslStream(io_service, context);
3295 SSLIOStreamDevice d(sslStream, fUseSSL);
3296 iostreams::stream<SSLIOStreamDevice> stream(d);
3297 if (!d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", "8332")))
3298 throw runtime_error("couldn't connect to server");
3299 #else
3300 if (fUseSSL)
3301 throw runtime_error("-rpcssl=1, but bitcoin compiled without full openssl libraries.");
3302
3303 ip::tcp::iostream stream(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", "8332"));
3304 if (stream.fail())
3305 throw runtime_error("couldn't connect to server");
3306 #endif
3307
3308
3309 // HTTP basic authentication
3310 string strUserPass64 = EncodeBase64(mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]);
3311 map<string, string> mapRequestHeaders;
3312 mapRequestHeaders["Authorization"] = string("Basic ") + strUserPass64;
3313
3314 // Send request
3315 string strRequest = JSONRPCRequest(strMethod, params, 1);
3316 string strPost = HTTPPost(strRequest, mapRequestHeaders);
3317 stream << strPost << std::flush;
3318
3319 // Receive reply
3320 map<string, string> mapHeaders;
3321 string strReply;
3322 int nStatus = ReadHTTP(stream, mapHeaders, strReply);
3323 if (nStatus == 401)
3324 throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)");
3325 else if (nStatus >= 400 && nStatus != 400 && nStatus != 404 && nStatus != 500)
3326 throw runtime_error(strprintf("server returned HTTP error %d", nStatus));
3327 else if (strReply.empty())
3328 throw runtime_error("no response from server");
3329
3330 // Parse reply
3331 Value valReply;
3332 if (!read_string(strReply, valReply))
3333 throw runtime_error("couldn't parse reply from server");
3334 const Object& reply = valReply.get_obj();
3335 if (reply.empty())
3336 throw runtime_error("expected reply to have result, error and id properties");
3337
3338 return reply;
3339 }
3340
3341
3342
3343
3344 template<typename T>
3345 void ConvertTo(Value& value)
3346 {
3347 if (value.type() == str_type)
3348 {
3349 // reinterpret string as unquoted json value
3350 Value value2;
3351 if (!read_string(value.get_str(), value2))
3352 throw runtime_error("type mismatch");
3353 value = value2.get_value<T>();
3354 }
3355 else
3356 {
3357 value = value.get_value<T>();
3358 }
3359 }
3360
3361 int CommandLineRPC(int argc, char *argv[])
3362 {
3363 string strPrint;
3364 int nRet = 0;
3365 try
3366 {
3367 // Skip switches
3368 while (argc > 1 && IsSwitchChar(argv[1][0]))
3369 {
3370 argc--;
3371 argv++;
3372 }
3373
3374 // Method
3375 if (argc < 2)
3376 throw runtime_error("too few parameters");
3377 string strMethod = argv[1];
3378
3379 // Parameters default to strings
3380 Array params;
3381 for (int i = 2; i < argc; i++)
3382 params.push_back(argv[i]);
3383 int n = params.size();
3384
3385 //
3386 // Special case non-string parameter types
3387 //
3388 if (strMethod == "setgenerate" && n > 0) ConvertTo<bool>(params[0]);
3389 if (strMethod == "setgenerate" && n > 1) ConvertTo<boost::int64_t>(params[1]);
3390 if (strMethod == "sendtoaddress" && n > 1) ConvertTo<double>(params[1]);
3391 if (strMethod == "settxfee" && n > 0) ConvertTo<double>(params[0]);
3392 if (strMethod == "getreceivedbyaddress" && n > 1) ConvertTo<boost::int64_t>(params[1]);
3393 if (strMethod == "getreceivedbyaccount" && n > 1) ConvertTo<boost::int64_t>(params[1]);
3394 if (strMethod == "listreceivedbyaddress" && n > 0) ConvertTo<boost::int64_t>(params[0]);
3395 if (strMethod == "listreceivedbyaddress" && n > 1) ConvertTo<bool>(params[1]);
3396 if (strMethod == "listreceivedbyaccount" && n > 0) ConvertTo<boost::int64_t>(params[0]);
3397 if (strMethod == "listreceivedbyaccount" && n > 1) ConvertTo<bool>(params[1]);
3398 if (strMethod == "getbalance" && n > 1) ConvertTo<boost::int64_t>(params[1]);
3399 if (strMethod == "move" && n > 2) ConvertTo<double>(params[2]);
3400 if (strMethod == "move" && n > 3) ConvertTo<boost::int64_t>(params[3]);
3401 if (strMethod == "sendfrom" && n > 2) ConvertTo<double>(params[2]);
3402 if (strMethod == "sendfrom" && n > 3) ConvertTo<boost::int64_t>(params[3]);
3403 if (strMethod == "listtransactions" && n > 1) ConvertTo<boost::int64_t>(params[1]);
3404 if (strMethod == "listtransactions" && n > 2) ConvertTo<boost::int64_t>(params[2]);
3405 if (strMethod == "listaccounts" && n > 0) ConvertTo<boost::int64_t>(params[0]);
3406 if (strMethod == "walletpassphrase" && n > 1) ConvertTo<boost::int64_t>(params[1]);
3407 if (strMethod == "listsinceblock" && n > 1) ConvertTo<boost::int64_t>(params[1]);
3408 if (strMethod == "sendmany" && n > 1)
3409 {
3410 string s = params[1].get_str();
3411 Value v;
3412 if (!read_string(s, v) || v.type() != obj_type)
3413 throw runtime_error("type mismatch");
3414 params[1] = v.get_obj();
3415 }
3416 if (strMethod == "sendmany" && n > 2) ConvertTo<boost::int64_t>(params[2]);
3417
3418 // Execute
3419 Object reply = CallRPC(strMethod, params);
3420
3421 // Parse reply
3422 const Value& result = find_value(reply, "result");
3423 const Value& error = find_value(reply, "error");
3424
3425 if (error.type() != null_type)
3426 {
3427 // Error
3428 strPrint = "error: " + write_string(error, false);
3429 int code = find_value(error.get_obj(), "code").get_int();
3430 nRet = abs(code);
3431 }
3432 else
3433 {
3434 // Result
3435 if (result.type() == null_type)
3436 strPrint = "";
3437 else if (result.type() == str_type)
3438 strPrint = result.get_str();
3439 else
3440 strPrint = write_string(result, true);
3441 }
3442 }
3443 catch (std::exception& e)
3444 {
3445 strPrint = string("error: ") + e.what();
3446 nRet = 87;
3447 }
3448 catch (...)
3449 {
3450 PrintException(NULL, "CommandLineRPC()");
3451 }
3452
3453 if (strPrint != "")
3454 {
3455 fprintf((nRet == 0 ? stdout : stderr), "%s\n", strPrint.c_str());
3456 }
3457 return nRet;
3458 }
3459
3460
3461
3462
3463 #ifdef TEST
3464 int main(int argc, char *argv[])
3465 {
3466 #ifdef _MSC_VER
3467 // Turn off microsoft heap dump noise
3468 _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
3469 _CrtSetReportFile(_CRT_WARN, CreateFile("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0));
3470 #endif
3471 setbuf(stdin, NULL);
3472 setbuf(stdout, NULL);
3473 setbuf(stderr, NULL);
3474
3475 try
3476 {
3477 if (argc >= 2 && string(argv[1]) == "-server")
3478 {
3479 printf("server ready\n");
3480 ThreadRPCServer(NULL);
3481 }
3482 else
3483 {
3484 return CommandLineRPC(argc, argv);
3485 }
3486 }
3487 catch (std::exception& e) {
3488 PrintException(&e, "main()");
3489 } catch (...) {
3490 PrintException(NULL, "main()");
3491 }
3492 return 0;
3493 }
3494 #endif
-
+ FB1E5C5D952BC34CD050609B16EB3B4A659AAFAEE1BF070969B4EEDF88ADAEC3B095977DAAF537E0515A32C0E99F2FB893BF38C59C906333BA21B52B51569D93
bitcoin/src/bitcoinrpc.h
(0 . 0)(1 . 7)
3499 // Copyright (c) 2010 Satoshi Nakamoto
3500 // Copyright (c) 2011 The Bitcoin developers
3501 // Distributed under the MIT/X11 software license, see the accompanying
3502 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
3503
3504 void ThreadRPCServer(void* parg);
3505 int CommandLineRPC(int argc, char *argv[]);
-
+ 423FE692637903B32D0DAEA46D9752322A7615CE3CD3CC3CE1F6FB2BF80B8F3C5285DB91F0BE83C5AB97C951BE6A8E46BB2B1A8FA7BDCE9780FCB6E5C54E2648
bitcoin/src/checkpoints.cpp
(0 . 0)(1 . 65)
3510 // Copyright (c) 2009-2012 The Bitcoin developers
3511 // Distributed under the MIT/X11 software license, see the accompanying
3512 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
3513
3514 #include <boost/assign/list_of.hpp> // for 'map_list_of()'
3515 #include <boost/foreach.hpp>
3516
3517 #include "headers.h"
3518 #include "checkpoints.h"
3519
3520 namespace Checkpoints
3521 {
3522 typedef std::map<int, uint256> MapCheckpoints;
3523
3524 //
3525 // What makes a good checkpoint block?
3526 // + Is surrounded by blocks with reasonable timestamps
3527 // (no blocks before with a timestamp after, none after with
3528 // timestamp before)
3529 // + Contains no strange transactions
3530 //
3531 static MapCheckpoints mapCheckpoints =
3532 boost::assign::map_list_of
3533 ( 11111, uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d"))
3534 ( 33333, uint256("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6"))
3535 ( 68555, uint256("0x00000000001e1b4903550a0b96e9a9405c8a95f387162e4944e8d9fbe501cd6a"))
3536 ( 70567, uint256("0x00000000006a49b14bcf27462068f1264c961f11fa2e0eddd2be0791e1d4124a"))
3537 ( 74000, uint256("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20"))
3538 (105000, uint256("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97"))
3539 (118000, uint256("0x000000000000774a7f8a7a12dc906ddb9e17e75d684f15e00f8767f9e8f36553"))
3540 (134444, uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe"))
3541 (140700, uint256("0x000000000000033b512028abb90e1626d8b346fd0ed598ac0a3c371138dce2bd"))
3542 (168000, uint256("0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763"))
3543 ;
3544
3545 bool CheckBlock(int nHeight, const uint256& hash)
3546 {
3547 if (fTestNet) return true; // Testnet has no checkpoints
3548
3549 MapCheckpoints::const_iterator i = mapCheckpoints.find(nHeight);
3550 if (i == mapCheckpoints.end()) return true;
3551 return hash == i->second;
3552 }
3553
3554 int GetTotalBlocksEstimate()
3555 {
3556 if (fTestNet) return 0;
3557
3558 return mapCheckpoints.rbegin()->first;
3559 }
3560
3561 CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
3562 {
3563 if (fTestNet) return NULL;
3564
3565 BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, mapCheckpoints)
3566 {
3567 const uint256& hash = i.second;
3568 std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
3569 if (t != mapBlockIndex.end())
3570 return t->second;
3571 }
3572 return NULL;
3573 }
3574 }
-
+ 2755D835E829219980034D39868269D3BC056B8E114AAA523409E87A8CFB988B7D8FAEA603833B16A35D7C48A9A03CADBCDDB7C014E87FFAE37AAFCF42EA0B79
bitcoin/src/checkpoints.h
(0 . 0)(1 . 29)
3579 // Copyright (c) 2011 The Bitcoin developers
3580 // Distributed under the MIT/X11 software license, see the accompanying
3581 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
3582 #ifndef BITCOIN_CHECKPOINT_H
3583 #define BITCOIN_CHECKPOINT_H
3584
3585 #include <map>
3586 #include "util.h"
3587
3588 class uint256;
3589 class CBlockIndex;
3590
3591 //
3592 // Block-chain checkpoints are compiled-in sanity checks.
3593 // They are updated every release or three.
3594 //
3595 namespace Checkpoints
3596 {
3597 // Returns true if block passes checkpoint checks
3598 bool CheckBlock(int nHeight, const uint256& hash);
3599
3600 // Return conservative estimate of total number of blocks, 0 if unknown
3601 int GetTotalBlocksEstimate();
3602
3603 // Returns last CBlockIndex* in mapBlockIndex that is a checkpoint
3604 CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex);
3605 }
3606
3607 #endif
-
+ 7C19985746214E45BF75C9044C5F13230195376E74B6C013659CFBE89390FD575E7BB1935F82F0D42F01B93F58EE980AF16BD99101E4241EABD585B6FEC09B0F
bitcoin/src/crypter.cpp
(0 . 0)(1 . 132)
3612 // Copyright (c) 2011 The Bitcoin Developers
3613 // Distributed under the MIT/X11 software license, see the accompanying
3614 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
3615
3616 #include <openssl/aes.h>
3617 #include <openssl/evp.h>
3618 #include <vector>
3619 #include <string>
3620 #include "headers.h"
3621 #ifdef WIN32
3622 #include <windows.h>
3623 #endif
3624
3625 #include "crypter.h"
3626 #include "main.h"
3627 #include "util.h"
3628
3629 bool CCrypter::SetKeyFromPassphrase(const SecureString& strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod)
3630 {
3631 if (nRounds < 1 || chSalt.size() != WALLET_CRYPTO_SALT_SIZE)
3632 return false;
3633
3634 // Try to keep the keydata out of swap (and be a bit over-careful to keep the IV that we don't even use out of swap)
3635 // Note that this does nothing about suspend-to-disk (which will put all our key data on disk)
3636 // Note as well that at no point in this program is any attempt made to prevent stealing of keys by reading the memory of the running process.
3637 mlock(&chKey[0], sizeof chKey);
3638 mlock(&chIV[0], sizeof chIV);
3639
3640 int i = 0;
3641 if (nDerivationMethod == 0)
3642 i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha512(), &chSalt[0],
3643 (unsigned char *)&strKeyData[0], strKeyData.size(), nRounds, chKey, chIV);
3644
3645 if (i != WALLET_CRYPTO_KEY_SIZE)
3646 {
3647 memset(&chKey, 0, sizeof chKey);
3648 memset(&chIV, 0, sizeof chIV);
3649 return false;
3650 }
3651
3652 fKeySet = true;
3653 return true;
3654 }
3655
3656 bool CCrypter::SetKey(const CKeyingMaterial& chNewKey, const std::vector<unsigned char>& chNewIV)
3657 {
3658 if (chNewKey.size() != WALLET_CRYPTO_KEY_SIZE || chNewIV.size() != WALLET_CRYPTO_KEY_SIZE)
3659 return false;
3660
3661 // Try to keep the keydata out of swap
3662 // Note that this does nothing about suspend-to-disk (which will put all our key data on disk)
3663 // Note as well that at no point in this program is any attempt made to prevent stealing of keys by reading the memory of the running process.
3664 mlock(&chKey[0], sizeof chKey);
3665 mlock(&chIV[0], sizeof chIV);
3666
3667 memcpy(&chKey[0], &chNewKey[0], sizeof chKey);
3668 memcpy(&chIV[0], &chNewIV[0], sizeof chIV);
3669
3670 fKeySet = true;
3671 return true;
3672 }
3673
3674 bool CCrypter::Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned char> &vchCiphertext)
3675 {
3676 if (!fKeySet)
3677 return false;
3678
3679 // max ciphertext len for a n bytes of plaintext is
3680 // n + AES_BLOCK_SIZE - 1 bytes
3681 int nLen = vchPlaintext.size();
3682 int nCLen = nLen + AES_BLOCK_SIZE, nFLen = 0;
3683 vchCiphertext = std::vector<unsigned char> (nCLen);
3684
3685 EVP_CIPHER_CTX ctx;
3686
3687 EVP_CIPHER_CTX_init(&ctx);
3688 EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV);
3689
3690 EVP_EncryptUpdate(&ctx, &vchCiphertext[0], &nCLen, &vchPlaintext[0], nLen);
3691 EVP_EncryptFinal_ex(&ctx, (&vchCiphertext[0])+nCLen, &nFLen);
3692
3693 EVP_CIPHER_CTX_cleanup(&ctx);
3694
3695 vchCiphertext.resize(nCLen + nFLen);
3696 return true;
3697 }
3698
3699 bool CCrypter::Decrypt(const std::vector<unsigned char>& vchCiphertext, CKeyingMaterial& vchPlaintext)
3700 {
3701 if (!fKeySet)
3702 return false;
3703
3704 // plaintext will always be equal to or lesser than length of ciphertext
3705 int nLen = vchCiphertext.size();
3706 int nPLen = nLen, nFLen = 0;
3707
3708 vchPlaintext = CKeyingMaterial(nPLen);
3709
3710 EVP_CIPHER_CTX ctx;
3711
3712 EVP_CIPHER_CTX_init(&ctx);
3713 EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV);
3714
3715 EVP_DecryptUpdate(&ctx, &vchPlaintext[0], &nPLen, &vchCiphertext[0], nLen);
3716 EVP_DecryptFinal_ex(&ctx, (&vchPlaintext[0])+nPLen, &nFLen);
3717
3718 EVP_CIPHER_CTX_cleanup(&ctx);
3719
3720 vchPlaintext.resize(nPLen + nFLen);
3721 return true;
3722 }
3723
3724
3725 bool EncryptSecret(CKeyingMaterial& vMasterKey, const CSecret &vchPlaintext, const uint256& nIV, std::vector<unsigned char> &vchCiphertext)
3726 {
3727 CCrypter cKeyCrypter;
3728 std::vector<unsigned char> chIV(WALLET_CRYPTO_KEY_SIZE);
3729 memcpy(&chIV[0], &nIV, WALLET_CRYPTO_KEY_SIZE);
3730 if(!cKeyCrypter.SetKey(vMasterKey, chIV))
3731 return false;
3732 return cKeyCrypter.Encrypt((CKeyingMaterial)vchPlaintext, vchCiphertext);
3733 }
3734
3735 bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCiphertext, const uint256& nIV, CSecret& vchPlaintext)
3736 {
3737 CCrypter cKeyCrypter;
3738 std::vector<unsigned char> chIV(WALLET_CRYPTO_KEY_SIZE);
3739 memcpy(&chIV[0], &nIV, WALLET_CRYPTO_KEY_SIZE);
3740 if(!cKeyCrypter.SetKey(vMasterKey, chIV))
3741 return false;
3742 return cKeyCrypter.Decrypt(vchCiphertext, *((CKeyingMaterial*)&vchPlaintext));
3743 }
-
+ 8797921C14CE0BE3E48A95AC27D4906CC208FF9E5F44868ACA5309B54112854AC13863B8D59DFF14CF7869F8DF6D4540F7C153945B6D6C917379065AEDBA7CDB
bitcoin/src/crypter.h
(0 . 0)(1 . 96)
3748 // Copyright (c) 2011 The Bitcoin Developers
3749 // Distributed under the MIT/X11 software license, see the accompanying
3750 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
3751 #ifndef __CRYPTER_H__
3752 #define __CRYPTER_H__
3753
3754 #include "key.h"
3755
3756 const unsigned int WALLET_CRYPTO_KEY_SIZE = 32;
3757 const unsigned int WALLET_CRYPTO_SALT_SIZE = 8;
3758
3759 /*
3760 Private key encryption is done based on a CMasterKey,
3761 which holds a salt and random encryption key.
3762
3763 CMasterKeys are encrypted using AES-256-CBC using a key
3764 derived using derivation method nDerivationMethod
3765 (0 == EVP_sha512()) and derivation iterations nDeriveIterations.
3766 vchOtherDerivationParameters is provided for alternative algorithms
3767 which may require more parameters (such as scrypt).
3768
3769 Wallet Private Keys are then encrypted using AES-256-CBC
3770 with the double-sha256 of the public key as the IV, and the
3771 master key's key as the encryption key (see keystore.[ch]).
3772 */
3773
3774 class CMasterKey
3775 {
3776 public:
3777 std::vector<unsigned char> vchCryptedKey;
3778 std::vector<unsigned char> vchSalt;
3779 // 0 = EVP_sha512()
3780 // 1 = scrypt()
3781 unsigned int nDerivationMethod;
3782 unsigned int nDeriveIterations;
3783 // Use this for more parameters to key derivation,
3784 // such as the various parameters to scrypt
3785 std::vector<unsigned char> vchOtherDerivationParameters;
3786
3787 IMPLEMENT_SERIALIZE
3788 (
3789 READWRITE(vchCryptedKey);
3790 READWRITE(vchSalt);
3791 READWRITE(nDerivationMethod);
3792 READWRITE(nDeriveIterations);
3793 READWRITE(vchOtherDerivationParameters);
3794 )
3795 CMasterKey()
3796 {
3797 // 25000 rounds is just under 0.1 seconds on a 1.86 GHz Pentium M
3798 // ie slightly lower than the lowest hardware we need bother supporting
3799 nDeriveIterations = 25000;
3800 nDerivationMethod = 0;
3801 vchOtherDerivationParameters = std::vector<unsigned char>(0);
3802 }
3803 };
3804
3805 typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial;
3806
3807 class CCrypter
3808 {
3809 private:
3810 unsigned char chKey[WALLET_CRYPTO_KEY_SIZE];
3811 unsigned char chIV[WALLET_CRYPTO_KEY_SIZE];
3812 bool fKeySet;
3813
3814 public:
3815 bool SetKeyFromPassphrase(const SecureString &strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod);
3816 bool Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned char> &vchCiphertext);
3817 bool Decrypt(const std::vector<unsigned char>& vchCiphertext, CKeyingMaterial& vchPlaintext);
3818 bool SetKey(const CKeyingMaterial& chNewKey, const std::vector<unsigned char>& chNewIV);
3819
3820 void CleanKey()
3821 {
3822 memset(&chKey, 0, sizeof chKey);
3823 memset(&chIV, 0, sizeof chIV);
3824 munlock(&chKey, sizeof chKey);
3825 munlock(&chIV, sizeof chIV);
3826 fKeySet = false;
3827 }
3828
3829 CCrypter()
3830 {
3831 fKeySet = false;
3832 }
3833
3834 ~CCrypter()
3835 {
3836 CleanKey();
3837 }
3838 };
3839
3840 bool EncryptSecret(CKeyingMaterial& vMasterKey, const CSecret &vchPlaintext, const uint256& nIV, std::vector<unsigned char> &vchCiphertext);
3841 bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char> &vchCiphertext, const uint256& nIV, CSecret &vchPlaintext);
3842
3843 #endif
-
+ B5486B3CB349B8AC9F3062359D595D28D076062390699FAC3F5AD50E89C3C82B1842524C153B09859A46F7F1776C40BE134F787B71761962D7170A7CDF8C3459
bitcoin/src/db.cpp
(0 . 0)(1 . 1069)
3848 // Copyright (c) 2009-2010 Satoshi Nakamoto
3849 // Copyright (c) 2009-2012 The Bitcoin developers
3850 // Distributed under the MIT/X11 software license, see the accompanying
3851 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
3852
3853 #include "headers.h"
3854 #include "db.h"
3855 #include "net.h"
3856 #include <boost/filesystem.hpp>
3857 #include <boost/filesystem/fstream.hpp>
3858
3859 using namespace std;
3860 using namespace boost;
3861
3862
3863 unsigned int nWalletDBUpdated;
3864 uint64 nAccountingEntryNumber = 0;
3865
3866
3867
3868 //
3869 // CDB
3870 //
3871
3872 static CCriticalSection cs_db;
3873 static bool fDbEnvInit = false;
3874 DbEnv dbenv(0);
3875 static map<string, int> mapFileUseCount;
3876 static map<string, Db*> mapDb;
3877
3878 static void EnvShutdown()
3879 {
3880 if (!fDbEnvInit)
3881 return;
3882
3883 fDbEnvInit = false;
3884 try
3885 {
3886 dbenv.close(0);
3887 }
3888 catch (const DbException& e)
3889 {
3890 printf("EnvShutdown exception: %s (%d)\n", e.what(), e.get_errno());
3891 }
3892 DbEnv(0).remove(GetDataDir().c_str(), 0);
3893 }
3894
3895 class CDBInit
3896 {
3897 public:
3898 CDBInit()
3899 {
3900 }
3901 ~CDBInit()
3902 {
3903 EnvShutdown();
3904 }
3905 }
3906 instance_of_cdbinit;
3907
3908
3909 CDB::CDB(const char* pszFile, const char* pszMode) : pdb(NULL)
3910 {
3911 int ret;
3912 if (pszFile == NULL)
3913 return;
3914
3915 fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w'));
3916 bool fCreate = strchr(pszMode, 'c');
3917 unsigned int nFlags = DB_THREAD;
3918 if (fCreate)
3919 nFlags |= DB_CREATE;
3920
3921 CRITICAL_BLOCK(cs_db)
3922 {
3923 if (!fDbEnvInit)
3924 {
3925 if (fShutdown)
3926 return;
3927 string strDataDir = GetDataDir();
3928 string strLogDir = strDataDir + "/database";
3929 filesystem::create_directory(strLogDir.c_str());
3930 string strErrorFile = strDataDir + "/db.log";
3931 printf("dbenv.open strLogDir=%s strErrorFile=%s\n", strLogDir.c_str(), strErrorFile.c_str());
3932
3933 dbenv.set_lg_dir(strLogDir.c_str());
3934 dbenv.set_lg_max(10000000);
3935 dbenv.set_lk_max_locks(10000);
3936 dbenv.set_lk_max_objects(10000);
3937 dbenv.set_errfile(fopen(strErrorFile.c_str(), "a")); /// debug
3938 dbenv.set_flags(DB_AUTO_COMMIT, 1);
3939 ret = dbenv.open(strDataDir.c_str(),
3940 DB_CREATE |
3941 DB_INIT_LOCK |
3942 DB_INIT_LOG |
3943 DB_INIT_MPOOL |
3944 DB_INIT_TXN |
3945 DB_THREAD |
3946 DB_RECOVER,
3947 S_IRUSR | S_IWUSR);
3948 if (ret > 0)
3949 throw runtime_error(strprintf("CDB() : error %d opening database environment", ret));
3950 fDbEnvInit = true;
3951 }
3952
3953 strFile = pszFile;
3954 ++mapFileUseCount[strFile];
3955 pdb = mapDb[strFile];
3956 if (pdb == NULL)
3957 {
3958 pdb = new Db(&dbenv, 0);
3959
3960 ret = pdb->open(NULL, // Txn pointer
3961 pszFile, // Filename
3962 "main", // Logical db name
3963 DB_BTREE, // Database type
3964 nFlags, // Flags
3965 0);
3966
3967 if (ret > 0)
3968 {
3969 delete pdb;
3970 pdb = NULL;
3971 CRITICAL_BLOCK(cs_db)
3972 --mapFileUseCount[strFile];
3973 strFile = "";
3974 throw runtime_error(strprintf("CDB() : can't open database file %s, error %d", pszFile, ret));
3975 }
3976
3977 if (fCreate && !Exists(string("version")))
3978 {
3979 bool fTmp = fReadOnly;
3980 fReadOnly = false;
3981 WriteVersion(VERSION);
3982 fReadOnly = fTmp;
3983 }
3984
3985 mapDb[strFile] = pdb;
3986 }
3987 }
3988 }
3989
3990 void CDB::Close()
3991 {
3992 if (!pdb)
3993 return;
3994 if (!vTxn.empty())
3995 vTxn.front()->abort();
3996 vTxn.clear();
3997 pdb = NULL;
3998
3999 // Flush database activity from memory pool to disk log
4000 unsigned int nMinutes = 0;
4001 if (fReadOnly)
4002 nMinutes = 1;
4003 if (strFile == "addr.dat")
4004 nMinutes = 2;
4005 if (strFile == "blkindex.dat" && IsInitialBlockDownload() && nBestHeight % 500 != 0)
4006 nMinutes = 1;
4007 dbenv.txn_checkpoint(0, nMinutes, 0);
4008
4009 CRITICAL_BLOCK(cs_db)
4010 --mapFileUseCount[strFile];
4011 }
4012
4013 void static CloseDb(const string& strFile)
4014 {
4015 CRITICAL_BLOCK(cs_db)
4016 {
4017 if (mapDb[strFile] != NULL)
4018 {
4019 // Close the database handle
4020 Db* pdb = mapDb[strFile];
4021 pdb->close(0);
4022 delete pdb;
4023 mapDb[strFile] = NULL;
4024 }
4025 }
4026 }
4027
4028 bool CDB::Rewrite(const string& strFile, const char* pszSkip)
4029 {
4030 while (!fShutdown)
4031 {
4032 CRITICAL_BLOCK(cs_db)
4033 {
4034 if (!mapFileUseCount.count(strFile) || mapFileUseCount[strFile] == 0)
4035 {
4036 // Flush log data to the dat file
4037 CloseDb(strFile);
4038 dbenv.txn_checkpoint(0, 0, 0);
4039 dbenv.lsn_reset(strFile.c_str(), 0);
4040 mapFileUseCount.erase(strFile);
4041
4042 bool fSuccess = true;
4043 printf("Rewriting %s...\n", strFile.c_str());
4044 string strFileRes = strFile + ".rewrite";
4045 { // surround usage of db with extra {}
4046 CDB db(strFile.c_str(), "r");
4047 Db* pdbCopy = new Db(&dbenv, 0);
4048
4049 int ret = pdbCopy->open(NULL, // Txn pointer
4050 strFileRes.c_str(), // Filename
4051 "main", // Logical db name
4052 DB_BTREE, // Database type
4053 DB_CREATE, // Flags
4054 0);
4055 if (ret > 0)
4056 {
4057 printf("Cannot create database file %s\n", strFileRes.c_str());
4058 fSuccess = false;
4059 }
4060
4061 Dbc* pcursor = db.GetCursor();
4062 if (pcursor)
4063 while (fSuccess)
4064 {
4065 CDataStream ssKey;
4066 CDataStream ssValue;
4067 int ret = db.ReadAtCursor(pcursor, ssKey, ssValue, DB_NEXT);
4068 if (ret == DB_NOTFOUND)
4069 {
4070 pcursor->close();
4071 break;
4072 }
4073 else if (ret != 0)
4074 {
4075 pcursor->close();
4076 fSuccess = false;
4077 break;
4078 }
4079 if (pszSkip &&
4080 strncmp(&ssKey[0], pszSkip, std::min(ssKey.size(), strlen(pszSkip))) == 0)
4081 continue;
4082 if (strncmp(&ssKey[0], "\x07version", 8) == 0)
4083 {
4084 // Update version:
4085 ssValue.clear();
4086 ssValue << VERSION;
4087 }
4088 Dbt datKey(&ssKey[0], ssKey.size());
4089 Dbt datValue(&ssValue[0], ssValue.size());
4090 int ret2 = pdbCopy->put(NULL, &datKey, &datValue, DB_NOOVERWRITE);
4091 if (ret2 > 0)
4092 fSuccess = false;
4093 }
4094 if (fSuccess)
4095 {
4096 db.Close();
4097 CloseDb(strFile);
4098 if (pdbCopy->close(0))
4099 fSuccess = false;
4100 delete pdbCopy;
4101 }
4102 }
4103 if (fSuccess)
4104 {
4105 Db dbA(&dbenv, 0);
4106 if (dbA.remove(strFile.c_str(), NULL, 0))
4107 fSuccess = false;
4108 Db dbB(&dbenv, 0);
4109 if (dbB.rename(strFileRes.c_str(), NULL, strFile.c_str(), 0))
4110 fSuccess = false;
4111 }
4112 if (!fSuccess)
4113 printf("Rewriting of %s FAILED!\n", strFileRes.c_str());
4114 return fSuccess;
4115 }
4116 }
4117 Sleep(100);
4118 }
4119 return false;
4120 }
4121
4122
4123 void DBFlush(bool fShutdown)
4124 {
4125 // Flush log data to the actual data file
4126 // on all files that are not in use
4127 printf("DBFlush(%s)%s\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " db not started");
4128 if (!fDbEnvInit)
4129 return;
4130 CRITICAL_BLOCK(cs_db)
4131 {
4132 map<string, int>::iterator mi = mapFileUseCount.begin();
4133 while (mi != mapFileUseCount.end())
4134 {
4135 string strFile = (*mi).first;
4136 int nRefCount = (*mi).second;
4137 printf("%s refcount=%d\n", strFile.c_str(), nRefCount);
4138 if (nRefCount == 0)
4139 {
4140 // Move log data to the dat file
4141 CloseDb(strFile);
4142 dbenv.txn_checkpoint(0, 0, 0);
4143 printf("%s flush\n", strFile.c_str());
4144 dbenv.lsn_reset(strFile.c_str(), 0);
4145 mapFileUseCount.erase(mi++);
4146 }
4147 else
4148 mi++;
4149 }
4150 if (fShutdown)
4151 {
4152 char** listp;
4153 if (mapFileUseCount.empty())
4154 {
4155 dbenv.log_archive(&listp, DB_ARCH_REMOVE);
4156 EnvShutdown();
4157 }
4158 }
4159 }
4160 }
4161
4162
4163
4164
4165
4166
4167 //
4168 // CTxDB
4169 //
4170
4171 bool CTxDB::ReadTxIndex(uint256 hash, CTxIndex& txindex)
4172 {
4173 assert(!fClient);
4174 txindex.SetNull();
4175 return Read(make_pair(string("tx"), hash), txindex);
4176 }
4177
4178 bool CTxDB::UpdateTxIndex(uint256 hash, const CTxIndex& txindex)
4179 {
4180 assert(!fClient);
4181 return Write(make_pair(string("tx"), hash), txindex);
4182 }
4183
4184 bool CTxDB::AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight)
4185 {
4186 assert(!fClient);
4187
4188 // Add to tx index
4189 uint256 hash = tx.GetHash();
4190 CTxIndex txindex(pos, tx.vout.size());
4191 return Write(make_pair(string("tx"), hash), txindex);
4192 }
4193
4194 bool CTxDB::EraseTxIndex(const CTransaction& tx)
4195 {
4196 assert(!fClient);
4197 uint256 hash = tx.GetHash();
4198
4199 return Erase(make_pair(string("tx"), hash));
4200 }
4201
4202 bool CTxDB::ContainsTx(uint256 hash)
4203 {
4204 assert(!fClient);
4205 return Exists(make_pair(string("tx"), hash));
4206 }
4207
4208 bool CTxDB::ReadOwnerTxes(uint160 hash160, int nMinHeight, vector<CTransaction>& vtx)
4209 {
4210 assert(!fClient);
4211 vtx.clear();
4212
4213 // Get cursor
4214 Dbc* pcursor = GetCursor();
4215 if (!pcursor)
4216 return false;
4217
4218 unsigned int fFlags = DB_SET_RANGE;
4219 loop
4220 {
4221 // Read next record
4222 CDataStream ssKey;
4223 if (fFlags == DB_SET_RANGE)
4224 ssKey << string("owner") << hash160 << CDiskTxPos(0, 0, 0);
4225 CDataStream ssValue;
4226 int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags);
4227 fFlags = DB_NEXT;
4228 if (ret == DB_NOTFOUND)
4229 break;
4230 else if (ret != 0)
4231 {
4232 pcursor->close();
4233 return false;
4234 }
4235
4236 // Unserialize
4237 string strType;
4238 uint160 hashItem;
4239 CDiskTxPos pos;
4240 ssKey >> strType >> hashItem >> pos;
4241 int nItemHeight;
4242 ssValue >> nItemHeight;
4243
4244 // Read transaction
4245 if (strType != "owner" || hashItem != hash160)
4246 break;
4247 if (nItemHeight >= nMinHeight)
4248 {
4249 vtx.resize(vtx.size()+1);
4250 if (!vtx.back().ReadFromDisk(pos))
4251 {
4252 pcursor->close();
4253 return false;
4254 }
4255 }
4256 }
4257
4258 pcursor->close();
4259 return true;
4260 }
4261
4262 bool CTxDB::ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex)
4263 {
4264 assert(!fClient);
4265 tx.SetNull();
4266 if (!ReadTxIndex(hash, txindex))
4267 return false;
4268 return (tx.ReadFromDisk(txindex.pos));
4269 }
4270
4271 bool CTxDB::ReadDiskTx(uint256 hash, CTransaction& tx)
4272 {
4273 CTxIndex txindex;
4274 return ReadDiskTx(hash, tx, txindex);
4275 }
4276
4277 bool CTxDB::ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex)
4278 {
4279 return ReadDiskTx(outpoint.hash, tx, txindex);
4280 }
4281
4282 bool CTxDB::ReadDiskTx(COutPoint outpoint, CTransaction& tx)
4283 {
4284 CTxIndex txindex;
4285 return ReadDiskTx(outpoint.hash, tx, txindex);
4286 }
4287
4288 bool CTxDB::WriteBlockIndex(const CDiskBlockIndex& blockindex)
4289 {
4290 return Write(make_pair(string("blockindex"), blockindex.GetBlockHash()), blockindex);
4291 }
4292
4293 bool CTxDB::EraseBlockIndex(uint256 hash)
4294 {
4295 return Erase(make_pair(string("blockindex"), hash));
4296 }
4297
4298 bool CTxDB::ReadHashBestChain(uint256& hashBestChain)
4299 {
4300 return Read(string("hashBestChain"), hashBestChain);
4301 }
4302
4303 bool CTxDB::WriteHashBestChain(uint256 hashBestChain)
4304 {
4305 return Write(string("hashBestChain"), hashBestChain);
4306 }
4307
4308 bool CTxDB::ReadBestInvalidWork(CBigNum& bnBestInvalidWork)
4309 {
4310 return Read(string("bnBestInvalidWork"), bnBestInvalidWork);
4311 }
4312
4313 bool CTxDB::WriteBestInvalidWork(CBigNum bnBestInvalidWork)
4314 {
4315 return Write(string("bnBestInvalidWork"), bnBestInvalidWork);
4316 }
4317
4318 CBlockIndex static * InsertBlockIndex(uint256 hash)
4319 {
4320 if (hash == 0)
4321 return NULL;
4322
4323 // Return existing
4324 map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
4325 if (mi != mapBlockIndex.end())
4326 return (*mi).second;
4327
4328 // Create new
4329 CBlockIndex* pindexNew = new CBlockIndex();
4330 if (!pindexNew)
4331 throw runtime_error("LoadBlockIndex() : new CBlockIndex failed");
4332 mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
4333 pindexNew->phashBlock = &((*mi).first);
4334
4335 return pindexNew;
4336 }
4337
4338 bool CTxDB::LoadBlockIndex()
4339 {
4340 // Get database cursor
4341 Dbc* pcursor = GetCursor();
4342 if (!pcursor)
4343 return false;
4344
4345 // Load mapBlockIndex
4346 unsigned int fFlags = DB_SET_RANGE;
4347 loop
4348 {
4349 // Read next record
4350 CDataStream ssKey;
4351 if (fFlags == DB_SET_RANGE)
4352 ssKey << make_pair(string("blockindex"), uint256(0));
4353 CDataStream ssValue;
4354 int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags);
4355 fFlags = DB_NEXT;
4356 if (ret == DB_NOTFOUND)
4357 break;
4358 else if (ret != 0)
4359 return false;
4360
4361 // Unserialize
4362 string strType;
4363 ssKey >> strType;
4364 if (strType == "blockindex")
4365 {
4366 CDiskBlockIndex diskindex;
4367 ssValue >> diskindex;
4368
4369 // Construct block index object
4370 CBlockIndex* pindexNew = InsertBlockIndex(diskindex.GetBlockHash());
4371 pindexNew->pprev = InsertBlockIndex(diskindex.hashPrev);
4372 pindexNew->pnext = InsertBlockIndex(diskindex.hashNext);
4373 pindexNew->nFile = diskindex.nFile;
4374 pindexNew->nBlockPos = diskindex.nBlockPos;
4375 pindexNew->nHeight = diskindex.nHeight;
4376 pindexNew->nVersion = diskindex.nVersion;
4377 pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot;
4378 pindexNew->nTime = diskindex.nTime;
4379 pindexNew->nBits = diskindex.nBits;
4380 pindexNew->nNonce = diskindex.nNonce;
4381
4382 // Watch for genesis block
4383 if (pindexGenesisBlock == NULL && diskindex.GetBlockHash() == hashGenesisBlock)
4384 pindexGenesisBlock = pindexNew;
4385
4386 if (!pindexNew->CheckIndex())
4387 return error("LoadBlockIndex() : CheckIndex failed at %d", pindexNew->nHeight);
4388 }
4389 else
4390 {
4391 break;
4392 }
4393 }
4394 pcursor->close();
4395
4396 // Calculate bnChainWork
4397 vector<pair<int, CBlockIndex*> > vSortedByHeight;
4398 vSortedByHeight.reserve(mapBlockIndex.size());
4399 BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
4400 {
4401 CBlockIndex* pindex = item.second;
4402 vSortedByHeight.push_back(make_pair(pindex->nHeight, pindex));
4403 }
4404 sort(vSortedByHeight.begin(), vSortedByHeight.end());
4405 BOOST_FOREACH(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight)
4406 {
4407 CBlockIndex* pindex = item.second;
4408 pindex->bnChainWork = (pindex->pprev ? pindex->pprev->bnChainWork : 0) + pindex->GetBlockWork();
4409 }
4410
4411 // Load hashBestChain pointer to end of best chain
4412 if (!ReadHashBestChain(hashBestChain))
4413 {
4414 if (pindexGenesisBlock == NULL)
4415 return true;
4416 return error("CTxDB::LoadBlockIndex() : hashBestChain not loaded");
4417 }
4418 if (!mapBlockIndex.count(hashBestChain))
4419 return error("CTxDB::LoadBlockIndex() : hashBestChain not found in the block index");
4420 pindexBest = mapBlockIndex[hashBestChain];
4421 nBestHeight = pindexBest->nHeight;
4422 bnBestChainWork = pindexBest->bnChainWork;
4423 printf("LoadBlockIndex(): hashBestChain=%s height=%d\n", hashBestChain.ToString().substr(0,20).c_str(), nBestHeight);
4424
4425 // Load bnBestInvalidWork, OK if it doesn't exist
4426 ReadBestInvalidWork(bnBestInvalidWork);
4427
4428 // Verify blocks in the best chain
4429 CBlockIndex* pindexFork = NULL;
4430 for (CBlockIndex* pindex = pindexBest; pindex && pindex->pprev; pindex = pindex->pprev)
4431 {
4432 if (pindex->nHeight < nBestHeight-2500 && !mapArgs.count("-checkblocks"))
4433 break;
4434 CBlock block;
4435 if (!block.ReadFromDisk(pindex))
4436 return error("LoadBlockIndex() : block.ReadFromDisk failed");
4437 if (!block.CheckBlock())
4438 {
4439 printf("LoadBlockIndex() : *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str());
4440 pindexFork = pindex->pprev;
4441 }
4442 }
4443 if (pindexFork)
4444 {
4445 // Reorg back to the fork
4446 printf("LoadBlockIndex() : *** moving best chain pointer back to block %d\n", pindexFork->nHeight);
4447 CBlock block;
4448 if (!block.ReadFromDisk(pindexFork))
4449 return error("LoadBlockIndex() : block.ReadFromDisk failed");
4450 CTxDB txdb;
4451 block.SetBestChain(txdb, pindexFork);
4452 }
4453
4454 return true;
4455 }
4456
4457
4458
4459
4460
4461 //
4462 // CAddrDB
4463 //
4464
4465 bool CAddrDB::WriteAddress(const CAddress& addr)
4466 {
4467 return Write(make_pair(string("addr"), addr.GetKey()), addr);
4468 }
4469
4470 bool CAddrDB::EraseAddress(const CAddress& addr)
4471 {
4472 return Erase(make_pair(string("addr"), addr.GetKey()));
4473 }
4474
4475 bool CAddrDB::LoadAddresses()
4476 {
4477 CRITICAL_BLOCK(cs_mapAddresses)
4478 {
4479 // Get cursor
4480 Dbc* pcursor = GetCursor();
4481 if (!pcursor)
4482 return false;
4483
4484 loop
4485 {
4486 // Read next record
4487 CDataStream ssKey;
4488 CDataStream ssValue;
4489 int ret = ReadAtCursor(pcursor, ssKey, ssValue);
4490 if (ret == DB_NOTFOUND)
4491 break;
4492 else if (ret != 0)
4493 return false;
4494
4495 // Unserialize
4496 string strType;
4497 ssKey >> strType;
4498 if (strType == "addr")
4499 {
4500 CAddress addr;
4501 ssValue >> addr;
4502 mapAddresses.insert(make_pair(addr.GetKey(), addr));
4503 }
4504 }
4505 pcursor->close();
4506
4507 printf("Loaded %d addresses\n", mapAddresses.size());
4508 }
4509
4510 return true;
4511 }
4512
4513 bool LoadAddresses()
4514 {
4515 return CAddrDB("cr+").LoadAddresses();
4516 }
4517
4518
4519
4520
4521 //
4522 // CWalletDB
4523 //
4524
4525 bool CWalletDB::WriteName(const string& strAddress, const string& strName)
4526 {
4527 nWalletDBUpdated++;
4528 return Write(make_pair(string("name"), strAddress), strName);
4529 }
4530
4531 bool CWalletDB::EraseName(const string& strAddress)
4532 {
4533 // This should only be used for sending addresses, never for receiving addresses,
4534 // receiving addresses must always have an address book entry if they're not change return.
4535 nWalletDBUpdated++;
4536 return Erase(make_pair(string("name"), strAddress));
4537 }
4538
4539 bool CWalletDB::ReadAccount(const string& strAccount, CAccount& account)
4540 {
4541 account.SetNull();
4542 return Read(make_pair(string("acc"), strAccount), account);
4543 }
4544
4545 bool CWalletDB::WriteAccount(const string& strAccount, const CAccount& account)
4546 {
4547 return Write(make_pair(string("acc"), strAccount), account);
4548 }
4549
4550 bool CWalletDB::WriteAccountingEntry(const CAccountingEntry& acentry)
4551 {
4552 return Write(boost::make_tuple(string("acentry"), acentry.strAccount, ++nAccountingEntryNumber), acentry);
4553 }
4554
4555 int64 CWalletDB::GetAccountCreditDebit(const string& strAccount)
4556 {
4557 list<CAccountingEntry> entries;
4558 ListAccountCreditDebit(strAccount, entries);
4559
4560 int64 nCreditDebit = 0;
4561 BOOST_FOREACH (const CAccountingEntry& entry, entries)
4562 nCreditDebit += entry.nCreditDebit;
4563
4564 return nCreditDebit;
4565 }
4566
4567 void CWalletDB::ListAccountCreditDebit(const string& strAccount, list<CAccountingEntry>& entries)
4568 {
4569 bool fAllAccounts = (strAccount == "*");
4570
4571 Dbc* pcursor = GetCursor();
4572 if (!pcursor)
4573 throw runtime_error("CWalletDB::ListAccountCreditDebit() : cannot create DB cursor");
4574 unsigned int fFlags = DB_SET_RANGE;
4575 loop
4576 {
4577 // Read next record
4578 CDataStream ssKey;
4579 if (fFlags == DB_SET_RANGE)
4580 ssKey << boost::make_tuple(string("acentry"), (fAllAccounts? string("") : strAccount), uint64(0));
4581 CDataStream ssValue;
4582 int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags);
4583 fFlags = DB_NEXT;
4584 if (ret == DB_NOTFOUND)
4585 break;
4586 else if (ret != 0)
4587 {
4588 pcursor->close();
4589 throw runtime_error("CWalletDB::ListAccountCreditDebit() : error scanning DB");
4590 }
4591
4592 // Unserialize
4593 string strType;
4594 ssKey >> strType;
4595 if (strType != "acentry")
4596 break;
4597 CAccountingEntry acentry;
4598 ssKey >> acentry.strAccount;
4599 if (!fAllAccounts && acentry.strAccount != strAccount)
4600 break;
4601
4602 ssValue >> acentry;
4603 entries.push_back(acentry);
4604 }
4605
4606 pcursor->close();
4607 }
4608
4609
4610 int CWalletDB::LoadWallet(CWallet* pwallet)
4611 {
4612 pwallet->vchDefaultKey.clear();
4613 int nFileVersion = 0;
4614 vector<uint256> vWalletUpgrade;
4615 bool fIsEncrypted = false;
4616
4617 // Modify defaults
4618 #ifndef WIN32
4619 // Tray icon sometimes disappears on 9.10 karmic koala 64-bit, leaving no way to access the program
4620 fMinimizeToTray = false;
4621 fMinimizeOnClose = false;
4622 #endif
4623
4624 //// todo: shouldn't we catch exceptions and try to recover and continue?
4625 CRITICAL_BLOCK(pwallet->cs_wallet)
4626 {
4627 // Get cursor
4628 Dbc* pcursor = GetCursor();
4629 if (!pcursor)
4630 return DB_CORRUPT;
4631
4632 loop
4633 {
4634 // Read next record
4635 CDataStream ssKey;
4636 CDataStream ssValue;
4637 int ret = ReadAtCursor(pcursor, ssKey, ssValue);
4638 if (ret == DB_NOTFOUND)
4639 break;
4640 else if (ret != 0)
4641 return DB_CORRUPT;
4642
4643 // Unserialize
4644 // Taking advantage of the fact that pair serialization
4645 // is just the two items serialized one after the other
4646 string strType;
4647 ssKey >> strType;
4648 if (strType == "name")
4649 {
4650 string strAddress;
4651 ssKey >> strAddress;
4652 ssValue >> pwallet->mapAddressBook[strAddress];
4653 }
4654 else if (strType == "tx")
4655 {
4656 uint256 hash;
4657 ssKey >> hash;
4658 CWalletTx& wtx = pwallet->mapWallet[hash];
4659 ssValue >> wtx;
4660 wtx.pwallet = pwallet;
4661
4662 if (wtx.GetHash() != hash)
4663 printf("Error in wallet.dat, hash mismatch\n");
4664
4665 // Undo serialize changes in 31600
4666 if (31404 <= wtx.fTimeReceivedIsTxTime && wtx.fTimeReceivedIsTxTime <= 31703)
4667 {
4668 if (!ssValue.empty())
4669 {
4670 char fTmp;
4671 char fUnused;
4672 ssValue >> fTmp >> fUnused >> wtx.strFromAccount;
4673 printf("LoadWallet() upgrading tx ver=%d %d '%s' %s\n", wtx.fTimeReceivedIsTxTime, fTmp, wtx.strFromAccount.c_str(), hash.ToString().c_str());
4674 wtx.fTimeReceivedIsTxTime = fTmp;
4675 }
4676 else
4677 {
4678 printf("LoadWallet() repairing tx ver=%d %s\n", wtx.fTimeReceivedIsTxTime, hash.ToString().c_str());
4679 wtx.fTimeReceivedIsTxTime = 0;
4680 }
4681 vWalletUpgrade.push_back(hash);
4682 }
4683
4684 //// debug print
4685 //printf("LoadWallet %s\n", wtx.GetHash().ToString().c_str());
4686 //printf(" %12I64d %s %s %s\n",
4687 // wtx.vout[0].nValue,
4688 // DateTimeStrFormat("%x %H:%M:%S", wtx.GetBlockTime()).c_str(),
4689 // wtx.hashBlock.ToString().substr(0,20).c_str(),
4690 // wtx.mapValue["message"].c_str());
4691 }
4692 else if (strType == "acentry")
4693 {
4694 string strAccount;
4695 ssKey >> strAccount;
4696 uint64 nNumber;
4697 ssKey >> nNumber;
4698 if (nNumber > nAccountingEntryNumber)
4699 nAccountingEntryNumber = nNumber;
4700 }
4701 else if (strType == "key" || strType == "wkey")
4702 {
4703 vector<unsigned char> vchPubKey;
4704 ssKey >> vchPubKey;
4705 CKey key;
4706 if (strType == "key")
4707 {
4708 CPrivKey pkey;
4709 ssValue >> pkey;
4710 key.SetPrivKey(pkey);
4711 if (key.GetPubKey() != vchPubKey || !key.IsValid())
4712 return DB_CORRUPT;
4713 }
4714 else
4715 {
4716 CWalletKey wkey;
4717 ssValue >> wkey;
4718 key.SetPrivKey(wkey.vchPrivKey);
4719 if (key.GetPubKey() != vchPubKey || !key.IsValid())
4720 return DB_CORRUPT;
4721 }
4722 if (!pwallet->LoadKey(key))
4723 return DB_CORRUPT;
4724 }
4725 else if (strType == "mkey")
4726 {
4727 unsigned int nID;
4728 ssKey >> nID;
4729 CMasterKey kMasterKey;
4730 ssValue >> kMasterKey;
4731 if(pwallet->mapMasterKeys.count(nID) != 0)
4732 return DB_CORRUPT;
4733 pwallet->mapMasterKeys[nID] = kMasterKey;
4734 if (pwallet->nMasterKeyMaxID < nID)
4735 pwallet->nMasterKeyMaxID = nID;
4736 }
4737 else if (strType == "ckey")
4738 {
4739 vector<unsigned char> vchPubKey;
4740 ssKey >> vchPubKey;
4741 vector<unsigned char> vchPrivKey;
4742 ssValue >> vchPrivKey;
4743 if (!pwallet->LoadCryptedKey(vchPubKey, vchPrivKey))
4744 return DB_CORRUPT;
4745 fIsEncrypted = true;
4746 }
4747 else if (strType == "defaultkey")
4748 {
4749 ssValue >> pwallet->vchDefaultKey;
4750 }
4751 else if (strType == "pool")
4752 {
4753 int64 nIndex;
4754 ssKey >> nIndex;
4755 pwallet->setKeyPool.insert(nIndex);
4756 }
4757 else if (strType == "version")
4758 {
4759 ssValue >> nFileVersion;
4760 if (nFileVersion == 10300)
4761 nFileVersion = 300;
4762 }
4763 else if (strType == "setting")
4764 {
4765 string strKey;
4766 ssKey >> strKey;
4767
4768 // Options
4769 #ifndef QT_GUI
4770 if (strKey == "fGenerateBitcoins") ssValue >> fGenerateBitcoins;
4771 #endif
4772 if (strKey == "nTransactionFee") ssValue >> nTransactionFee;
4773 if (strKey == "fLimitProcessors") ssValue >> fLimitProcessors;
4774 if (strKey == "nLimitProcessors") ssValue >> nLimitProcessors;
4775 if (strKey == "fMinimizeToTray") ssValue >> fMinimizeToTray;
4776 if (strKey == "fMinimizeOnClose") ssValue >> fMinimizeOnClose;
4777 if (strKey == "fUseProxy") ssValue >> fUseProxy;
4778 if (strKey == "addrProxy") ssValue >> addrProxy;
4779 if (fHaveUPnP && strKey == "fUseUPnP") ssValue >> fUseUPnP;
4780 }
4781 else if (strType == "minversion")
4782 {
4783 int nMinVersion = 0;
4784 ssValue >> nMinVersion;
4785 if (nMinVersion > VERSION)
4786 return DB_TOO_NEW;
4787 }
4788 }
4789 pcursor->close();
4790 }
4791
4792 BOOST_FOREACH(uint256 hash, vWalletUpgrade)
4793 WriteTx(hash, pwallet->mapWallet[hash]);
4794
4795 printf("nFileVersion = %d\n", nFileVersion);
4796 printf("fGenerateBitcoins = %d\n", fGenerateBitcoins);
4797 printf("nTransactionFee = %"PRI64d"\n", nTransactionFee);
4798 printf("fMinimizeToTray = %d\n", fMinimizeToTray);
4799 printf("fMinimizeOnClose = %d\n", fMinimizeOnClose);
4800 printf("fUseProxy = %d\n", fUseProxy);
4801 printf("addrProxy = %s\n", addrProxy.ToString().c_str());
4802 if (fHaveUPnP)
4803 printf("fUseUPnP = %d\n", fUseUPnP);
4804
4805
4806 // Rewrite encrypted wallets of versions 0.4.0 and 0.5.0rc:
4807 if (fIsEncrypted && (nFileVersion == 40000 || nFileVersion == 50000))
4808 return DB_NEED_REWRITE;
4809
4810 if (nFileVersion < VERSION) // Update
4811 {
4812 // Get rid of old debug.log file in current directory
4813 if (nFileVersion <= 105 && !pszSetDataDir[0])
4814 unlink("debug.log");
4815
4816 WriteVersion(VERSION);
4817 }
4818
4819 return DB_LOAD_OK;
4820 }
4821
4822 void ThreadFlushWalletDB(void* parg)
4823 {
4824 const string& strFile = ((const string*)parg)[0];
4825 static bool fOneThread;
4826 if (fOneThread)
4827 return;
4828 fOneThread = true;
4829 if (mapArgs.count("-noflushwallet"))
4830 return;
4831
4832 unsigned int nLastSeen = nWalletDBUpdated;
4833 unsigned int nLastFlushed = nWalletDBUpdated;
4834 int64 nLastWalletUpdate = GetTime();
4835 while (!fShutdown)
4836 {
4837 Sleep(500);
4838
4839 if (nLastSeen != nWalletDBUpdated)
4840 {
4841 nLastSeen = nWalletDBUpdated;
4842 nLastWalletUpdate = GetTime();
4843 }
4844
4845 if (nLastFlushed != nWalletDBUpdated && GetTime() - nLastWalletUpdate >= 2)
4846 {
4847 TRY_CRITICAL_BLOCK(cs_db)
4848 {
4849 // Don't do this if any databases are in use
4850 int nRefCount = 0;
4851 map<string, int>::iterator mi = mapFileUseCount.begin();
4852 while (mi != mapFileUseCount.end())
4853 {
4854 nRefCount += (*mi).second;
4855 mi++;
4856 }
4857
4858 if (nRefCount == 0 && !fShutdown)
4859 {
4860 map<string, int>::iterator mi = mapFileUseCount.find(strFile);
4861 if (mi != mapFileUseCount.end())
4862 {
4863 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
4864 printf("Flushing wallet.dat\n");
4865 nLastFlushed = nWalletDBUpdated;
4866 int64 nStart = GetTimeMillis();
4867
4868 // Flush wallet.dat so it's self contained
4869 CloseDb(strFile);
4870 dbenv.txn_checkpoint(0, 0, 0);
4871 dbenv.lsn_reset(strFile.c_str(), 0);
4872
4873 mapFileUseCount.erase(mi++);
4874 printf("Flushed wallet.dat %"PRI64d"ms\n", GetTimeMillis() - nStart);
4875 }
4876 }
4877 }
4878 }
4879 }
4880 }
4881
4882 bool BackupWallet(const CWallet& wallet, const string& strDest)
4883 {
4884 if (!wallet.fFileBacked)
4885 return false;
4886 while (!fShutdown)
4887 {
4888 CRITICAL_BLOCK(cs_db)
4889 {
4890 if (!mapFileUseCount.count(wallet.strWalletFile) || mapFileUseCount[wallet.strWalletFile] == 0)
4891 {
4892 // Flush log data to the dat file
4893 CloseDb(wallet.strWalletFile);
4894 dbenv.txn_checkpoint(0, 0, 0);
4895 dbenv.lsn_reset(wallet.strWalletFile.c_str(), 0);
4896 mapFileUseCount.erase(wallet.strWalletFile);
4897
4898 // Copy wallet.dat
4899 filesystem::path pathSrc(GetDataDir() + "/" + wallet.strWalletFile);
4900 filesystem::path pathDest(strDest);
4901 if (filesystem::is_directory(pathDest))
4902 pathDest = pathDest / wallet.strWalletFile;
4903 #if BOOST_VERSION >= 104000
4904 filesystem::copy_file(pathSrc, pathDest, filesystem::copy_option::overwrite_if_exists);
4905 #else
4906 filesystem::copy_file(pathSrc, pathDest);
4907 #endif
4908 printf("copied wallet.dat to %s\n", pathDest.string().c_str());
4909
4910 return true;
4911 }
4912 }
4913 Sleep(100);
4914 }
4915 return false;
4916 }
-
+ FDFE29057EEBDD25ED05EC5F7E24489F4A84B11D064E787FC4297B31E872D4DEE501050416728C3B2A62EE9B77269DFFD04509B3FCAD9091A2B63B32F817B32C
bitcoin/src/db.h
(0 . 0)(1 . 485)
4921 // Copyright (c) 2009-2010 Satoshi Nakamoto
4922 // Copyright (c) 2011 The Bitcoin developers
4923 // Distributed under the MIT/X11 software license, see the accompanying
4924 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
4925 #ifndef BITCOIN_DB_H
4926 #define BITCOIN_DB_H
4927
4928 #include "key.h"
4929
4930 #include <map>
4931 #include <string>
4932 #include <vector>
4933
4934 #include <db_cxx.h>
4935
4936 class CTxIndex;
4937 class CDiskBlockIndex;
4938 class CDiskTxPos;
4939 class COutPoint;
4940 class CAddress;
4941 class CWalletTx;
4942 class CWallet;
4943 class CAccount;
4944 class CAccountingEntry;
4945 class CBlockLocator;
4946
4947
4948 extern unsigned int nWalletDBUpdated;
4949 extern DbEnv dbenv;
4950
4951 extern void DBFlush(bool fShutdown);
4952 void ThreadFlushWalletDB(void* parg);
4953 bool BackupWallet(const CWallet& wallet, const std::string& strDest);
4954
4955
4956
4957 class CDB
4958 {
4959 protected:
4960 Db* pdb;
4961 std::string strFile;
4962 std::vector<DbTxn*> vTxn;
4963 bool fReadOnly;
4964
4965 explicit CDB(const char* pszFile, const char* pszMode="r+");
4966 ~CDB() { Close(); }
4967 public:
4968 void Close();
4969 private:
4970 CDB(const CDB&);
4971 void operator=(const CDB&);
4972
4973 protected:
4974 template<typename K, typename T>
4975 bool Read(const K& key, T& value)
4976 {
4977 if (!pdb)
4978 return false;
4979
4980 // Key
4981 CDataStream ssKey(SER_DISK);
4982 ssKey.reserve(1000);
4983 ssKey << key;
4984 Dbt datKey(&ssKey[0], ssKey.size());
4985
4986 // Read
4987 Dbt datValue;
4988 datValue.set_flags(DB_DBT_MALLOC);
4989 int ret = pdb->get(GetTxn(), &datKey, &datValue, 0);
4990 memset(datKey.get_data(), 0, datKey.get_size());
4991 if (datValue.get_data() == NULL)
4992 return false;
4993
4994 // Unserialize value
4995 CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK);
4996 ssValue >> value;
4997
4998 // Clear and free memory
4999 memset(datValue.get_data(), 0, datValue.get_size());
5000 free(datValue.get_data());
5001 return (ret == 0);
5002 }
5003
5004 template<typename K, typename T>
5005 bool Write(const K& key, const T& value, bool fOverwrite=true)
5006 {
5007 if (!pdb)
5008 return false;
5009 if (fReadOnly)
5010 assert(!"Write called on database in read-only mode");
5011
5012 // Key
5013 CDataStream ssKey(SER_DISK);
5014 ssKey.reserve(1000);
5015 ssKey << key;
5016 Dbt datKey(&ssKey[0], ssKey.size());
5017
5018 // Value
5019 CDataStream ssValue(SER_DISK);
5020 ssValue.reserve(10000);
5021 ssValue << value;
5022 Dbt datValue(&ssValue[0], ssValue.size());
5023
5024 // Write
5025 int ret = pdb->put(GetTxn(), &datKey, &datValue, (fOverwrite ? 0 : DB_NOOVERWRITE));
5026
5027 // Clear memory in case it was a private key
5028 memset(datKey.get_data(), 0, datKey.get_size());
5029 memset(datValue.get_data(), 0, datValue.get_size());
5030 return (ret == 0);
5031 }
5032
5033 template<typename K>
5034 bool Erase(const K& key)
5035 {
5036 if (!pdb)
5037 return false;
5038 if (fReadOnly)
5039 assert(!"Erase called on database in read-only mode");
5040
5041 // Key
5042 CDataStream ssKey(SER_DISK);
5043 ssKey.reserve(1000);
5044 ssKey << key;
5045 Dbt datKey(&ssKey[0], ssKey.size());
5046
5047 // Erase
5048 int ret = pdb->del(GetTxn(), &datKey, 0);
5049
5050 // Clear memory
5051 memset(datKey.get_data(), 0, datKey.get_size());
5052 return (ret == 0 || ret == DB_NOTFOUND);
5053 }
5054
5055 template<typename K>
5056 bool Exists(const K& key)
5057 {
5058 if (!pdb)
5059 return false;
5060
5061 // Key
5062 CDataStream ssKey(SER_DISK);
5063 ssKey.reserve(1000);
5064 ssKey << key;
5065 Dbt datKey(&ssKey[0], ssKey.size());
5066
5067 // Exists
5068 int ret = pdb->exists(GetTxn(), &datKey, 0);
5069
5070 // Clear memory
5071 memset(datKey.get_data(), 0, datKey.get_size());
5072 return (ret == 0);
5073 }
5074
5075 Dbc* GetCursor()
5076 {
5077 if (!pdb)
5078 return NULL;
5079 Dbc* pcursor = NULL;
5080 int ret = pdb->cursor(NULL, &pcursor, 0);
5081 if (ret != 0)
5082 return NULL;
5083 return pcursor;
5084 }
5085
5086 int ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue, unsigned int fFlags=DB_NEXT)
5087 {
5088 // Read at cursor
5089 Dbt datKey;
5090 if (fFlags == DB_SET || fFlags == DB_SET_RANGE || fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)
5091 {
5092 datKey.set_data(&ssKey[0]);
5093 datKey.set_size(ssKey.size());
5094 }
5095 Dbt datValue;
5096 if (fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)
5097 {
5098 datValue.set_data(&ssValue[0]);
5099 datValue.set_size(ssValue.size());
5100 }
5101 datKey.set_flags(DB_DBT_MALLOC);
5102 datValue.set_flags(DB_DBT_MALLOC);
5103 int ret = pcursor->get(&datKey, &datValue, fFlags);
5104 if (ret != 0)
5105 return ret;
5106 else if (datKey.get_data() == NULL || datValue.get_data() == NULL)
5107 return 99999;
5108
5109 // Convert to streams
5110 ssKey.SetType(SER_DISK);
5111 ssKey.clear();
5112 ssKey.write((char*)datKey.get_data(), datKey.get_size());
5113 ssValue.SetType(SER_DISK);
5114 ssValue.clear();
5115 ssValue.write((char*)datValue.get_data(), datValue.get_size());
5116
5117 // Clear and free memory
5118 memset(datKey.get_data(), 0, datKey.get_size());
5119 memset(datValue.get_data(), 0, datValue.get_size());
5120 free(datKey.get_data());
5121 free(datValue.get_data());
5122 return 0;
5123 }
5124
5125 DbTxn* GetTxn()
5126 {
5127 if (!vTxn.empty())
5128 return vTxn.back();
5129 else
5130 return NULL;
5131 }
5132
5133 public:
5134 bool TxnBegin()
5135 {
5136 if (!pdb)
5137 return false;
5138 DbTxn* ptxn = NULL;
5139 int ret = dbenv.txn_begin(GetTxn(), &ptxn, DB_TXN_NOSYNC);
5140 if (!ptxn || ret != 0)
5141 return false;
5142 vTxn.push_back(ptxn);
5143 return true;
5144 }
5145
5146 bool TxnCommit()
5147 {
5148 if (!pdb)
5149 return false;
5150 if (vTxn.empty())
5151 return false;
5152 int ret = vTxn.back()->commit(0);
5153 vTxn.pop_back();
5154 return (ret == 0);
5155 }
5156
5157 bool TxnAbort()
5158 {
5159 if (!pdb)
5160 return false;
5161 if (vTxn.empty())
5162 return false;
5163 int ret = vTxn.back()->abort();
5164 vTxn.pop_back();
5165 return (ret == 0);
5166 }
5167
5168 bool ReadVersion(int& nVersion)
5169 {
5170 nVersion = 0;
5171 return Read(std::string("version"), nVersion);
5172 }
5173
5174 bool WriteVersion(int nVersion)
5175 {
5176 return Write(std::string("version"), nVersion);
5177 }
5178
5179 bool static Rewrite(const std::string& strFile, const char* pszSkip = NULL);
5180 };
5181
5182
5183
5184
5185
5186
5187
5188
5189 class CTxDB : public CDB
5190 {
5191 public:
5192 CTxDB(const char* pszMode="r+") : CDB("blkindex.dat", pszMode) { }
5193 private:
5194 CTxDB(const CTxDB&);
5195 void operator=(const CTxDB&);
5196 public:
5197 bool ReadTxIndex(uint256 hash, CTxIndex& txindex);
5198 bool UpdateTxIndex(uint256 hash, const CTxIndex& txindex);
5199 bool AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight);
5200 bool EraseTxIndex(const CTransaction& tx);
5201 bool ContainsTx(uint256 hash);
5202 bool ReadOwnerTxes(uint160 hash160, int nHeight, std::vector<CTransaction>& vtx);
5203 bool ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex);
5204 bool ReadDiskTx(uint256 hash, CTransaction& tx);
5205 bool ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex);
5206 bool ReadDiskTx(COutPoint outpoint, CTransaction& tx);
5207 bool WriteBlockIndex(const CDiskBlockIndex& blockindex);
5208 bool EraseBlockIndex(uint256 hash);
5209 bool ReadHashBestChain(uint256& hashBestChain);
5210 bool WriteHashBestChain(uint256 hashBestChain);
5211 bool ReadBestInvalidWork(CBigNum& bnBestInvalidWork);
5212 bool WriteBestInvalidWork(CBigNum bnBestInvalidWork);
5213 bool LoadBlockIndex();
5214 };
5215
5216
5217
5218
5219
5220 class CAddrDB : public CDB
5221 {
5222 public:
5223 CAddrDB(const char* pszMode="r+") : CDB("addr.dat", pszMode) { }
5224 private:
5225 CAddrDB(const CAddrDB&);
5226 void operator=(const CAddrDB&);
5227 public:
5228 bool WriteAddress(const CAddress& addr);
5229 bool EraseAddress(const CAddress& addr);
5230 bool LoadAddresses();
5231 };
5232
5233 bool LoadAddresses();
5234
5235
5236
5237 class CKeyPool
5238 {
5239 public:
5240 int64 nTime;
5241 std::vector<unsigned char> vchPubKey;
5242
5243 CKeyPool()
5244 {
5245 nTime = GetTime();
5246 }
5247
5248 CKeyPool(const std::vector<unsigned char>& vchPubKeyIn)
5249 {
5250 nTime = GetTime();
5251 vchPubKey = vchPubKeyIn;
5252 }
5253
5254 IMPLEMENT_SERIALIZE
5255 (
5256 if (!(nType & SER_GETHASH))
5257 READWRITE(nVersion);
5258 READWRITE(nTime);
5259 READWRITE(vchPubKey);
5260 )
5261 };
5262
5263
5264
5265
5266 enum DBErrors
5267 {
5268 DB_LOAD_OK,
5269 DB_CORRUPT,
5270 DB_TOO_NEW,
5271 DB_LOAD_FAIL,
5272 DB_NEED_REWRITE
5273 };
5274
5275 class CWalletDB : public CDB
5276 {
5277 public:
5278 CWalletDB(std::string strFilename, const char* pszMode="r+") : CDB(strFilename.c_str(), pszMode)
5279 {
5280 }
5281 private:
5282 CWalletDB(const CWalletDB&);
5283 void operator=(const CWalletDB&);
5284 public:
5285 bool ReadName(const std::string& strAddress, std::string& strName)
5286 {
5287 strName = "";
5288 return Read(std::make_pair(std::string("name"), strAddress), strName);
5289 }
5290
5291 bool WriteName(const std::string& strAddress, const std::string& strName);
5292
5293 bool EraseName(const std::string& strAddress);
5294
5295 bool ReadTx(uint256 hash, CWalletTx& wtx)
5296 {
5297 return Read(std::make_pair(std::string("tx"), hash), wtx);
5298 }
5299
5300 bool WriteTx(uint256 hash, const CWalletTx& wtx)
5301 {
5302 nWalletDBUpdated++;
5303 return Write(std::make_pair(std::string("tx"), hash), wtx);
5304 }
5305
5306 bool EraseTx(uint256 hash)
5307 {
5308 nWalletDBUpdated++;
5309 return Erase(std::make_pair(std::string("tx"), hash));
5310 }
5311
5312 bool ReadKey(const std::vector<unsigned char>& vchPubKey, CPrivKey& vchPrivKey)
5313 {
5314 vchPrivKey.clear();
5315 return Read(std::make_pair(std::string("key"), vchPubKey), vchPrivKey);
5316 }
5317
5318 bool WriteKey(const std::vector<unsigned char>& vchPubKey, const CPrivKey& vchPrivKey)
5319 {
5320 nWalletDBUpdated++;
5321 return Write(std::make_pair(std::string("key"), vchPubKey), vchPrivKey, false);
5322 }
5323
5324 bool WriteCryptedKey(const std::vector<unsigned char>& vchPubKey, const std::vector<unsigned char>& vchCryptedSecret, bool fEraseUnencryptedKey = true)
5325 {
5326 nWalletDBUpdated++;
5327 if (!Write(std::make_pair(std::string("ckey"), vchPubKey), vchCryptedSecret, false))
5328 return false;
5329 if (fEraseUnencryptedKey)
5330 {
5331 Erase(std::make_pair(std::string("key"), vchPubKey));
5332 Erase(std::make_pair(std::string("wkey"), vchPubKey));
5333 }
5334 return true;
5335 }
5336
5337 bool WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey)
5338 {
5339 nWalletDBUpdated++;
5340 return Write(std::make_pair(std::string("mkey"), nID), kMasterKey, true);
5341 }
5342
5343 bool WriteBestBlock(const CBlockLocator& locator)
5344 {
5345 nWalletDBUpdated++;
5346 return Write(std::string("bestblock"), locator);
5347 }
5348
5349 bool ReadBestBlock(CBlockLocator& locator)
5350 {
5351 return Read(std::string("bestblock"), locator);
5352 }
5353
5354 bool ReadDefaultKey(std::vector<unsigned char>& vchPubKey)
5355 {
5356 vchPubKey.clear();
5357 return Read(std::string("defaultkey"), vchPubKey);
5358 }
5359
5360 bool WriteDefaultKey(const std::vector<unsigned char>& vchPubKey)
5361 {
5362 nWalletDBUpdated++;
5363 return Write(std::string("defaultkey"), vchPubKey);
5364 }
5365
5366 bool ReadPool(int64 nPool, CKeyPool& keypool)
5367 {
5368 return Read(std::make_pair(std::string("pool"), nPool), keypool);
5369 }
5370
5371 bool WritePool(int64 nPool, const CKeyPool& keypool)
5372 {
5373 nWalletDBUpdated++;
5374 return Write(std::make_pair(std::string("pool"), nPool), keypool);
5375 }
5376
5377 bool ErasePool(int64 nPool)
5378 {
5379 nWalletDBUpdated++;
5380 return Erase(std::make_pair(std::string("pool"), nPool));
5381 }
5382
5383 template<typename T>
5384 bool ReadSetting(const std::string& strKey, T& value)
5385 {
5386 return Read(std::make_pair(std::string("setting"), strKey), value);
5387 }
5388
5389 template<typename T>
5390 bool WriteSetting(const std::string& strKey, const T& value)
5391 {
5392 nWalletDBUpdated++;
5393 return Write(std::make_pair(std::string("setting"), strKey), value);
5394 }
5395
5396 bool ReadAccount(const std::string& strAccount, CAccount& account);
5397 bool WriteAccount(const std::string& strAccount, const CAccount& account);
5398 bool WriteAccountingEntry(const CAccountingEntry& acentry);
5399 int64 GetAccountCreditDebit(const std::string& strAccount);
5400 void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& acentries);
5401
5402 int LoadWallet(CWallet* pwallet);
5403 };
5404
5405 #endif
-
+ 4D28E9CD20CADDB467B279FC8C18282F3690D1C5C8D2CBFCF1B9D4FC3AE2E009960DED1240B88FC23E2FE69D69410A9FFE50CFAD1A3F3A87496BB0868D8CECF4
bitcoin/src/headers.h
(0 . 0)(1 . 96)
5410 // Copyright (c) 2009-2010 Satoshi Nakamoto
5411 // Copyright (c) 2009-2012 The Bitcoin developers
5412 // Distributed under the MIT/X11 software license, see the accompanying
5413 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
5414
5415 #ifdef _MSC_VER
5416 #pragma warning(disable:4786)
5417 #pragma warning(disable:4804)
5418 #pragma warning(disable:4805)
5419 #pragma warning(disable:4717)
5420 #endif
5421 #ifdef _WIN32_WINNT
5422 #undef _WIN32_WINNT
5423 #endif
5424 #define _WIN32_WINNT 0x0500
5425 #ifdef _WIN32_IE
5426 #undef _WIN32_IE
5427 #endif
5428 #define _WIN32_IE 0x0400
5429 #define WIN32_LEAN_AND_MEAN 1
5430
5431 // Include boost/foreach here as it defines __STDC_LIMIT_MACROS on some systems.
5432 #include <boost/foreach.hpp>
5433 #ifndef __STDC_LIMIT_MACROS
5434 #define __STDC_LIMIT_MACROS // to enable UINT64_MAX from stdint.h
5435 #endif
5436
5437 #if (defined(__unix__) || defined(unix)) && !defined(USG)
5438 #include <sys/param.h> // to get BSD define
5439 #endif
5440 #ifdef MAC_OSX
5441 #ifndef BSD
5442 #define BSD 1
5443 #endif
5444 #endif
5445 #include <openssl/buffer.h>
5446 #include <openssl/ecdsa.h>
5447 #include <openssl/evp.h>
5448 #include <openssl/rand.h>
5449 #include <openssl/sha.h>
5450 #include <openssl/ripemd.h>
5451 #include <db_cxx.h>
5452 #include <stdio.h>
5453 #include <stdlib.h>
5454 #include <time.h>
5455 #include <math.h>
5456 #include <limits.h>
5457 #include <float.h>
5458 #include <assert.h>
5459 #include <iostream>
5460 #include <sstream>
5461 #include <string>
5462 #include <vector>
5463 #include <list>
5464 #include <deque>
5465 #include <map>
5466
5467 #ifdef WIN32
5468 #include <windows.h>
5469 #include <winsock2.h>
5470 #include <mswsock.h>
5471 #include <shlobj.h>
5472 #include <shlwapi.h>
5473 #include <io.h>
5474 #include <process.h>
5475 #include <malloc.h>
5476 #else
5477 #include <sys/time.h>
5478 #include <sys/resource.h>
5479 #include <sys/socket.h>
5480 #include <sys/stat.h>
5481 #include <arpa/inet.h>
5482 #include <netdb.h>
5483 #include <unistd.h>
5484 #include <errno.h>
5485 #include <net/if.h>
5486 #include <ifaddrs.h>
5487 #include <fcntl.h>
5488 #include <signal.h>
5489 #endif
5490 #ifdef BSD
5491 #include <netinet/in.h>
5492 #endif
5493
5494
5495 #include "serialize.h"
5496 #include "uint256.h"
5497 #include "util.h"
5498 #include "bignum.h"
5499 #include "base58.h"
5500 #include "main.h"
5501 #ifdef QT_GUI
5502 #include "qtui.h"
5503 #else
5504 #include "noui.h"
5505 #endif
-
+ 1BB5D8AF6051E25FC87AB7438B6DAFC864BE7792B04C6AA0D8942EFE701B2B4ABFCD1902B33CC4B1C2993668676E3C7D8F90BD6C075C70906D0C7E9C2DB4E83B
bitcoin/src/init.cpp
(0 . 0)(1 . 550)
5510 // Copyright (c) 2009-2010 Satoshi Nakamoto
5511 // Copyright (c) 2009-2012 The Bitcoin developers
5512 // Distributed under the MIT/X11 software license, see the accompanying
5513 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
5514 #include "headers.h"
5515 #include "db.h"
5516 #include "bitcoinrpc.h"
5517 #include "net.h"
5518 #include "init.h"
5519 #include "strlcpy.h"
5520 #include <boost/filesystem.hpp>
5521 #include <boost/filesystem/fstream.hpp>
5522 #include <boost/interprocess/sync/file_lock.hpp>
5523
5524 #if defined(BITCOIN_NEED_QT_PLUGINS) && !defined(_BITCOIN_QT_PLUGINS_INCLUDED)
5525 #define _BITCOIN_QT_PLUGINS_INCLUDED
5526 #define __INSURE__
5527 #include <QtPlugin>
5528 Q_IMPORT_PLUGIN(qcncodecs)
5529 Q_IMPORT_PLUGIN(qjpcodecs)
5530 Q_IMPORT_PLUGIN(qtwcodecs)
5531 Q_IMPORT_PLUGIN(qkrcodecs)
5532 Q_IMPORT_PLUGIN(qtaccessiblewidgets)
5533 #endif
5534
5535 using namespace std;
5536 using namespace boost;
5537
5538 CWallet* pwalletMain;
5539
5540 //////////////////////////////////////////////////////////////////////////////
5541 //
5542 // Shutdown
5543 //
5544
5545 void ExitTimeout(void* parg)
5546 {
5547 #ifdef WIN32
5548 Sleep(5000);
5549 ExitProcess(0);
5550 #endif
5551 }
5552
5553 void Shutdown(void* parg)
5554 {
5555 static CCriticalSection cs_Shutdown;
5556 static bool fTaken;
5557 bool fFirstThread = false;
5558 TRY_CRITICAL_BLOCK(cs_Shutdown)
5559 {
5560 fFirstThread = !fTaken;
5561 fTaken = true;
5562 }
5563 static bool fExit;
5564 if (fFirstThread)
5565 {
5566 fShutdown = true;
5567 nTransactionsUpdated++;
5568 DBFlush(false);
5569 StopNode();
5570 DBFlush(true);
5571 boost::filesystem::remove(GetPidFile());
5572 UnregisterWallet(pwalletMain);
5573 delete pwalletMain;
5574 CreateThread(ExitTimeout, NULL);
5575 Sleep(50);
5576 printf("Bitcoin exiting\n\n");
5577 fExit = true;
5578 exit(0);
5579 }
5580 else
5581 {
5582 while (!fExit)
5583 Sleep(500);
5584 Sleep(100);
5585 ExitThread(0);
5586 }
5587 }
5588
5589 void HandleSIGTERM(int)
5590 {
5591 fRequestShutdown = true;
5592 }
5593
5594
5595
5596
5597
5598
5599 //////////////////////////////////////////////////////////////////////////////
5600 //
5601 // Start
5602 //
5603 #if !defined(QT_GUI)
5604 int main(int argc, char* argv[])
5605 {
5606 bool fRet = false;
5607 fRet = AppInit(argc, argv);
5608
5609 if (fRet && fDaemon)
5610 return 0;
5611
5612 return 1;
5613 }
5614 #endif
5615
5616 bool AppInit(int argc, char* argv[])
5617 {
5618 bool fRet = false;
5619 try
5620 {
5621 fRet = AppInit2(argc, argv);
5622 }
5623 catch (std::exception& e) {
5624 PrintException(&e, "AppInit()");
5625 } catch (...) {
5626 PrintException(NULL, "AppInit()");
5627 }
5628 if (!fRet)
5629 Shutdown(NULL);
5630 return fRet;
5631 }
5632
5633 bool AppInit2(int argc, char* argv[])
5634 {
5635 #ifdef _MSC_VER
5636 // Turn off microsoft heap dump noise
5637 _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
5638 _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0));
5639 #endif
5640 #if _MSC_VER >= 1400
5641 // Disable confusing "helpful" text message on abort, ctrl-c
5642 _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
5643 #endif
5644 #ifndef WIN32
5645 umask(077);
5646 #endif
5647 #ifndef WIN32
5648 // Clean shutdown on SIGTERM
5649 struct sigaction sa;
5650 sa.sa_handler = HandleSIGTERM;
5651 sigemptyset(&sa.sa_mask);
5652 sa.sa_flags = 0;
5653 sigaction(SIGTERM, &sa, NULL);
5654 sigaction(SIGINT, &sa, NULL);
5655 sigaction(SIGHUP, &sa, NULL);
5656 #endif
5657
5658 //
5659 // Parameters
5660 //
5661 ParseParameters(argc, argv);
5662
5663 if (mapArgs.count("-datadir"))
5664 {
5665 if (filesystem::is_directory(filesystem::system_complete(mapArgs["-datadir"])))
5666 {
5667 filesystem::path pathDataDir = filesystem::system_complete(mapArgs["-datadir"]);
5668 strlcpy(pszSetDataDir, pathDataDir.string().c_str(), sizeof(pszSetDataDir));
5669 }
5670 else
5671 {
5672 fprintf(stderr, "Error: Specified directory does not exist\n");
5673 Shutdown(NULL);
5674 }
5675 }
5676
5677
5678 ReadConfigFile(mapArgs, mapMultiArgs); // Must be done after processing datadir
5679
5680 if (mapArgs.count("-?") || mapArgs.count("--help"))
5681 {
5682 string strUsage = string() +
5683 _("Bitcoin version") + " " + FormatFullVersion() + "\n\n" +
5684 _("Usage:") + "\t\t\t\t\t\t\t\t\t\t\n" +
5685 " bitcoind [options] \t " + "\n" +
5686 " bitcoind [options] <command> [params]\t " + _("Send command to -server or bitcoind\n") +
5687 " bitcoind [options] help \t\t " + _("List commands\n") +
5688 " bitcoind [options] help <command> \t\t " + _("Get help for a command\n") +
5689 _("Options:\n") +
5690 " -conf=<file> \t\t " + _("Specify configuration file (default: bitcoin.conf)\n") +
5691 " -pid=<file> \t\t " + _("Specify pid file (default: bitcoind.pid)\n") +
5692 " -gen \t\t " + _("Generate coins\n") +
5693 " -gen=0 \t\t " + _("Don't generate coins\n") +
5694 " -min \t\t " + _("Start minimized\n") +
5695 " -datadir=<dir> \t\t " + _("Specify data directory\n") +
5696 " -timeout=<n> \t " + _("Specify connection timeout (in milliseconds)\n") +
5697 " -proxy=<ip:port> \t " + _("Connect through socks4 proxy\n") +
5698 " -dns \t " + _("Allow DNS lookups for addnode and connect\n") +
5699 " -port=<port> \t\t " + _("Listen for connections on <port> (default: 8333 or testnet: 18333)\n") +
5700 " -maxconnections=<n>\t " + _("Maintain at most <n> connections to peers (default: 125)\n") +
5701 " -addnode=<ip> \t " + _("Add a node to connect to\n") +
5702 " -connect=<ip> \t\t " + _("Connect only to the specified node\n") +
5703 " -noirc \t " + _("Don't find peers using internet relay chat\n") +
5704 " -nolisten \t " + _("Don't accept connections from outside\n") +
5705 " -nodnsseed \t " + _("Don't bootstrap list of peers using DNS\n") +
5706 " -banscore=<n> \t " + _("Threshold for disconnecting misbehaving peers (default: 100)\n") +
5707 " -bantime=<n> \t " + _("Number of seconds to keep misbehaving peers from reconnecting (default: 86400)\n") +
5708 " -maxreceivebuffer=<n>\t " + _("Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000)\n") +
5709 " -maxsendbuffer=<n>\t " + _("Maximum per-connection send buffer, <n>*1000 bytes (default: 10000)\n") +
5710 #ifdef USE_UPNP
5711 #if USE_UPNP
5712 " -noupnp \t " + _("Don't attempt to use UPnP to map the listening port\n") +
5713 #else
5714 " -upnp \t " + _("Attempt to use UPnP to map the listening port\n") +
5715 #endif
5716 #endif
5717 " -paytxfee=<amt> \t " + _("Fee per kB to add to transactions you send\n") +
5718 #ifdef QT_GUI
5719 " -server \t\t " + _("Accept command line and JSON-RPC commands\n") +
5720 #endif
5721 #if !defined(WIN32) && !defined(QT_GUI)
5722 " -daemon \t\t " + _("Run in the background as a daemon and accept commands\n") +
5723 #endif
5724 " -testnet \t\t " + _("Use the test network\n") +
5725 " -debug \t\t " + _("Output extra debugging information\n") +
5726 " -logtimestamps \t " + _("Prepend debug output with timestamp\n") +
5727 " -printtoconsole \t " + _("Send trace/debug info to console instead of debug.log file\n") +
5728 #ifdef WIN32
5729 " -printtodebugger \t " + _("Send trace/debug info to debugger\n") +
5730 #endif
5731 " -rpcuser=<user> \t " + _("Username for JSON-RPC connections\n") +
5732 " -rpcpassword=<pw>\t " + _("Password for JSON-RPC connections\n") +
5733 " -rpcport=<port> \t\t " + _("Listen for JSON-RPC connections on <port> (default: 8332)\n") +
5734 " -rpcallowip=<ip> \t\t " + _("Allow JSON-RPC connections from specified IP address\n") +
5735 " -rpcconnect=<ip> \t " + _("Send commands to node running on <ip> (default: 127.0.0.1)\n") +
5736 " -keypool=<n> \t " + _("Set key pool size to <n> (default: 100)\n") +
5737 " -rescan \t " + _("Rescan the block chain for missing wallet transactions\n");
5738
5739 #ifdef USE_SSL
5740 strUsage += string() +
5741 _("\nSSL options: (see the Bitcoin Wiki for SSL setup instructions)\n") +
5742 " -rpcssl \t " + _("Use OpenSSL (https) for JSON-RPC connections\n") +
5743 " -rpcsslcertificatechainfile=<file.cert>\t " + _("Server certificate file (default: server.cert)\n") +
5744 " -rpcsslprivatekeyfile=<file.pem> \t " + _("Server private key (default: server.pem)\n") +
5745 " -rpcsslciphers=<ciphers> \t " + _("Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)\n");
5746 #endif
5747
5748 strUsage += string() +
5749 " -? \t\t " + _("This help message\n");
5750
5751 // Remove tabs
5752 strUsage.erase(std::remove(strUsage.begin(), strUsage.end(), '\t'), strUsage.end());
5753 #if defined(QT_GUI) && defined(WIN32)
5754 // On windows, show a message box, as there is no stderr
5755 wxMessageBox(strUsage, "Usage");
5756 #else
5757 fprintf(stderr, "%s", strUsage.c_str());
5758 #endif
5759 return false;
5760 }
5761
5762 fTestNet = GetBoolArg("-testnet");
5763 fDebug = GetBoolArg("-debug");
5764
5765 #if !defined(WIN32) && !defined(QT_GUI)
5766 fDaemon = GetBoolArg("-daemon");
5767 #else
5768 fDaemon = false;
5769 #endif
5770
5771 if (fDaemon)
5772 fServer = true;
5773 else
5774 fServer = GetBoolArg("-server");
5775
5776 /* force fServer when running without GUI */
5777 #if !defined(QT_GUI)
5778 fServer = true;
5779 #endif
5780 fPrintToConsole = GetBoolArg("-printtoconsole");
5781 fPrintToDebugger = GetBoolArg("-printtodebugger");
5782 fLogTimestamps = GetBoolArg("-logtimestamps");
5783
5784 #ifndef QT_GUI
5785 for (int i = 1; i < argc; i++)
5786 if (!IsSwitchChar(argv[i][0]))
5787 fCommandLine = true;
5788
5789 if (fCommandLine)
5790 {
5791 int ret = CommandLineRPC(argc, argv);
5792 exit(ret);
5793 }
5794 #endif
5795
5796 #if !defined(WIN32) && !defined(QT_GUI)
5797 if (fDaemon)
5798 {
5799 // Daemonize
5800 pid_t pid = fork();
5801 if (pid < 0)
5802 {
5803 fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno);
5804 return false;
5805 }
5806 if (pid > 0)
5807 {
5808 CreatePidFile(GetPidFile(), pid);
5809 return true;
5810 }
5811
5812 pid_t sid = setsid();
5813 if (sid < 0)
5814 fprintf(stderr, "Error: setsid() returned %d errno %d\n", sid, errno);
5815 }
5816 #endif
5817
5818 if (!fDebug && !pszSetDataDir[0])
5819 ShrinkDebugFile();
5820 printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
5821 printf("Bitcoin version %s\n", FormatFullVersion().c_str());
5822 printf("Default data directory %s\n", GetDefaultDataDir().c_str());
5823
5824 if (GetBoolArg("-loadblockindextest"))
5825 {
5826 CTxDB txdb("r");
5827 txdb.LoadBlockIndex();
5828 PrintBlockTree();
5829 return false;
5830 }
5831
5832 // Make sure only a single bitcoin process is using the data directory.
5833 string strLockFile = GetDataDir() + "/.lock";
5834 FILE* file = fopen(strLockFile.c_str(), "a"); // empty lock file; created if it doesn't exist.
5835 if (file) fclose(file);
5836 static boost::interprocess::file_lock lock(strLockFile.c_str());
5837 if (!lock.try_lock())
5838 {
5839 wxMessageBox(strprintf(_("Cannot obtain a lock on data directory %s. Bitcoin is probably already running."), GetDataDir().c_str()), "Bitcoin");
5840 return false;
5841 }
5842
5843 string strErrors;
5844
5845 //
5846 // Load data files
5847 //
5848 if (fDaemon)
5849 fprintf(stdout, "bitcoin server starting\n");
5850 strErrors = "";
5851 int64 nStart;
5852
5853 InitMessage(_("Loading addresses..."));
5854 printf("Loading addresses...\n");
5855 nStart = GetTimeMillis();
5856 if (!LoadAddresses())
5857 strErrors += _("Error loading addr.dat \n");
5858 printf(" addresses %15"PRI64d"ms\n", GetTimeMillis() - nStart);
5859
5860 InitMessage(_("Loading block index..."));
5861 printf("Loading block index...\n");
5862 nStart = GetTimeMillis();
5863 if (!LoadBlockIndex())
5864 strErrors += _("Error loading blkindex.dat \n");
5865 printf(" block index %15"PRI64d"ms\n", GetTimeMillis() - nStart);
5866
5867 InitMessage(_("Loading wallet..."));
5868 printf("Loading wallet...\n");
5869 nStart = GetTimeMillis();
5870 bool fFirstRun;
5871 pwalletMain = new CWallet("wallet.dat");
5872 int nLoadWalletRet = pwalletMain->LoadWallet(fFirstRun);
5873 if (nLoadWalletRet != DB_LOAD_OK)
5874 {
5875 if (nLoadWalletRet == DB_CORRUPT)
5876 strErrors += _("Error loading wallet.dat: Wallet corrupted \n");
5877 else if (nLoadWalletRet == DB_TOO_NEW)
5878 strErrors += _("Error loading wallet.dat: Wallet requires newer version of Bitcoin \n");
5879 else if (nLoadWalletRet == DB_NEED_REWRITE)
5880 {
5881 strErrors += _("Wallet needed to be rewritten: restart Bitcoin to complete \n");
5882 wxMessageBox(strErrors, "Bitcoin", wxOK | wxICON_ERROR);
5883 return false;
5884 }
5885 else
5886 strErrors += _("Error loading wallet.dat \n");
5887 }
5888 printf(" wallet %15"PRI64d"ms\n", GetTimeMillis() - nStart);
5889
5890 RegisterWallet(pwalletMain);
5891
5892 CBlockIndex *pindexRescan = pindexBest;
5893 if (GetBoolArg("-rescan"))
5894 pindexRescan = pindexGenesisBlock;
5895 else
5896 {
5897 CWalletDB walletdb("wallet.dat");
5898 CBlockLocator locator;
5899 if (walletdb.ReadBestBlock(locator))
5900 pindexRescan = locator.GetBlockIndex();
5901 }
5902 if (pindexBest != pindexRescan)
5903 {
5904 InitMessage(_("Rescanning..."));
5905 printf("Rescanning last %i blocks (from block %i)...\n", pindexBest->nHeight - pindexRescan->nHeight, pindexRescan->nHeight);
5906 nStart = GetTimeMillis();
5907 pwalletMain->ScanForWalletTransactions(pindexRescan, true);
5908 printf(" rescan %15"PRI64d"ms\n", GetTimeMillis() - nStart);
5909 }
5910
5911 InitMessage(_("Done loading"));
5912 printf("Done loading\n");
5913
5914 //// debug print
5915 printf("mapBlockIndex.size() = %d\n", mapBlockIndex.size());
5916 printf("nBestHeight = %d\n", nBestHeight);
5917 printf("setKeyPool.size() = %d\n", pwalletMain->setKeyPool.size());
5918 printf("mapWallet.size() = %d\n", pwalletMain->mapWallet.size());
5919 printf("mapAddressBook.size() = %d\n", pwalletMain->mapAddressBook.size());
5920
5921 if (!strErrors.empty())
5922 {
5923 wxMessageBox(strErrors, "Bitcoin", wxOK | wxICON_ERROR);
5924 return false;
5925 }
5926
5927 // Add wallet transactions that aren't already in a block to mapTransactions
5928 pwalletMain->ReacceptWalletTransactions();
5929
5930 // Note: Bitcoin-QT stores several settings in the wallet, so we want
5931 // to load the wallet BEFORE parsing command-line arguments, so
5932 // the command-line/bitcoin.conf settings override GUI setting.
5933
5934 //
5935 // Parameters
5936 //
5937 if (GetBoolArg("-printblockindex") || GetBoolArg("-printblocktree"))
5938 {
5939 PrintBlockTree();
5940 return false;
5941 }
5942
5943 if (mapArgs.count("-timeout"))
5944 {
5945 int nNewTimeout = GetArg("-timeout", 5000);
5946 if (nNewTimeout > 0 && nNewTimeout < 600000)
5947 nConnectTimeout = nNewTimeout;
5948 }
5949
5950 if (mapArgs.count("-printblock"))
5951 {
5952 string strMatch = mapArgs["-printblock"];
5953 int nFound = 0;
5954 for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi)
5955 {
5956 uint256 hash = (*mi).first;
5957 if (strncmp(hash.ToString().c_str(), strMatch.c_str(), strMatch.size()) == 0)
5958 {
5959 CBlockIndex* pindex = (*mi).second;
5960 CBlock block;
5961 block.ReadFromDisk(pindex);
5962 block.BuildMerkleTree();
5963 block.print();
5964 printf("\n");
5965 nFound++;
5966 }
5967 }
5968 if (nFound == 0)
5969 printf("No blocks matching %s were found\n", strMatch.c_str());
5970 return false;
5971 }
5972
5973 fGenerateBitcoins = GetBoolArg("-gen");
5974
5975 if (mapArgs.count("-proxy"))
5976 {
5977 fUseProxy = true;
5978 addrProxy = CAddress(mapArgs["-proxy"]);
5979 if (!addrProxy.IsValid())
5980 {
5981 wxMessageBox(_("Invalid -proxy address"), "Bitcoin");
5982 return false;
5983 }
5984 }
5985
5986 bool fTor = (fUseProxy && addrProxy.port == htons(9050));
5987 if (fTor)
5988 {
5989 // Use SoftSetArg here so user can override any of these if they wish.
5990 // Note: the GetBoolArg() calls for all of these must happen later.
5991 SoftSetArg("-nolisten", true);
5992 SoftSetArg("-noirc", true);
5993 SoftSetArg("-nodnsseed", true);
5994 SoftSetArg("-noupnp", true);
5995 SoftSetArg("-upnp", false);
5996 SoftSetArg("-dns", false);
5997 }
5998
5999 fAllowDNS = GetBoolArg("-dns");
6000 fNoListen = GetBoolArg("-nolisten");
6001
6002 // Command-line args override in-wallet settings:
6003 if (mapArgs.count("-upnp"))
6004 fUseUPnP = GetBoolArg("-upnp");
6005 else if (mapArgs.count("-noupnp"))
6006 fUseUPnP = !GetBoolArg("-noupnp");
6007
6008 if (!fNoListen)
6009 {
6010 if (!BindListenPort(strErrors))
6011 {
6012 wxMessageBox(strErrors, "Bitcoin");
6013 return false;
6014 }
6015 }
6016
6017 if (mapArgs.count("-addnode"))
6018 {
6019 BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
6020 {
6021 CAddress addr(strAddr, fAllowDNS);
6022 addr.nTime = 0; // so it won't relay unless successfully connected
6023 if (addr.IsValid())
6024 AddAddress(addr);
6025 }
6026 }
6027
6028 if (mapArgs.count("-paytxfee"))
6029 {
6030 if (!ParseMoney(mapArgs["-paytxfee"], nTransactionFee))
6031 {
6032 wxMessageBox(_("Invalid amount for -paytxfee=<amount>"), "Bitcoin");
6033 return false;
6034 }
6035 if (nTransactionFee > 0.25 * COIN)
6036 wxMessageBox(_("Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction."), "Bitcoin", wxOK | wxICON_EXCLAMATION);
6037 }
6038
6039 //
6040 // Start the node
6041 //
6042 if (!CheckDiskSpace())
6043 return false;
6044
6045 RandAddSeedPerfmon();
6046
6047 if (!CreateThread(StartNode, NULL))
6048 wxMessageBox(_("Error: CreateThread(StartNode) failed"), "Bitcoin");
6049
6050 if (fServer)
6051 CreateThread(ThreadRPCServer, NULL);
6052
6053 #if !defined(QT_GUI)
6054 while (1)
6055 Sleep(5000);
6056 #endif
6057
6058 return true;
6059 }
-
+ AA2AC5386F11AB61AE761A82E90A3465EBDE345C1092085003522B6353B129C16288527BAADD17062566BF746C54535D658BE1525BD6FD27BF0FA1DB0953C04A
bitcoin/src/init.h
(0 . 0)(1 . 14)
6064 // Copyright (c) 2009-2010 Satoshi Nakamoto
6065 // Copyright (c) 2011 The Bitcoin developers
6066 // Distributed under the MIT/X11 software license, see the accompanying
6067 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
6068 #ifndef BITCOIN_INIT_H
6069 #define BITCOIN_INIT_H
6070
6071 extern CWallet* pwalletMain;
6072
6073 void Shutdown(void* parg);
6074 bool AppInit(int argc, char* argv[]);
6075 bool AppInit2(int argc, char* argv[]);
6076
6077 #endif
-
+ 775141F07CE491A331E51FE97B43D4F2D1891EB720FC6706D06747959653E8171CB46DAA77EFD73E202B1E1419F26036C92CC106DE34D22245489B3F7B333BCB
bitcoin/src/irc.cpp
(0 . 0)(1 . 440)
6082 // Copyright (c) 2009-2010 Satoshi Nakamoto
6083 // Copyright (c) 2009-2012 The Bitcoin developers
6084 // Distributed under the MIT/X11 software license, see the accompanying
6085 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
6086
6087 #include "headers.h"
6088 #include "irc.h"
6089 #include "net.h"
6090 #include "strlcpy.h"
6091
6092 using namespace std;
6093 using namespace boost;
6094
6095 int nGotIRCAddresses = 0;
6096 bool fGotExternalIP = false;
6097
6098 void ThreadIRCSeed2(void* parg);
6099
6100
6101
6102
6103 #pragma pack(push, 1)
6104 struct ircaddr
6105 {
6106 int ip;
6107 short port;
6108 };
6109 #pragma pack(pop)
6110
6111 string EncodeAddress(const CAddress& addr)
6112 {
6113 struct ircaddr tmp;
6114 tmp.ip = addr.ip;
6115 tmp.port = addr.port;
6116
6117 vector<unsigned char> vch(UBEGIN(tmp), UEND(tmp));
6118 return string("u") + EncodeBase58Check(vch);
6119 }
6120
6121 bool DecodeAddress(string str, CAddress& addr)
6122 {
6123 vector<unsigned char> vch;
6124 if (!DecodeBase58Check(str.substr(1), vch))
6125 return false;
6126
6127 struct ircaddr tmp;
6128 if (vch.size() != sizeof(tmp))
6129 return false;
6130 memcpy(&tmp, &vch[0], sizeof(tmp));
6131
6132 addr = CAddress(tmp.ip, ntohs(tmp.port), NODE_NETWORK);
6133 return true;
6134 }
6135
6136
6137
6138
6139
6140
6141 static bool Send(SOCKET hSocket, const char* pszSend)
6142 {
6143 if (strstr(pszSend, "PONG") != pszSend)
6144 printf("IRC SENDING: %s\n", pszSend);
6145 const char* psz = pszSend;
6146 const char* pszEnd = psz + strlen(psz);
6147 while (psz < pszEnd)
6148 {
6149 int ret = send(hSocket, psz, pszEnd - psz, MSG_NOSIGNAL);
6150 if (ret < 0)
6151 return false;
6152 psz += ret;
6153 }
6154 return true;
6155 }
6156
6157 bool RecvLine(SOCKET hSocket, string& strLine)
6158 {
6159 strLine = "";
6160 loop
6161 {
6162 char c;
6163 int nBytes = recv(hSocket, &c, 1, 0);
6164 if (nBytes > 0)
6165 {
6166 if (c == '\n')
6167 continue;
6168 if (c == '\r')
6169 return true;
6170 strLine += c;
6171 if (strLine.size() >= 9000)
6172 return true;
6173 }
6174 else if (nBytes <= 0)
6175 {
6176 if (fShutdown)
6177 return false;
6178 if (nBytes < 0)
6179 {
6180 int nErr = WSAGetLastError();
6181 if (nErr == WSAEMSGSIZE)
6182 continue;
6183 if (nErr == WSAEWOULDBLOCK || nErr == WSAEINTR || nErr == WSAEINPROGRESS)
6184 {
6185 Sleep(10);
6186 continue;
6187 }
6188 }
6189 if (!strLine.empty())
6190 return true;
6191 if (nBytes == 0)
6192 {
6193 // socket closed
6194 printf("socket closed\n");
6195 return false;
6196 }
6197 else
6198 {
6199 // socket error
6200 int nErr = WSAGetLastError();
6201 printf("recv failed: %d\n", nErr);
6202 return false;
6203 }
6204 }
6205 }
6206 }
6207
6208 bool RecvLineIRC(SOCKET hSocket, string& strLine)
6209 {
6210 loop
6211 {
6212 bool fRet = RecvLine(hSocket, strLine);
6213 if (fRet)
6214 {
6215 if (fShutdown)
6216 return false;
6217 vector<string> vWords;
6218 ParseString(strLine, ' ', vWords);
6219 if (vWords.size() >= 1 && vWords[0] == "PING")
6220 {
6221 strLine[1] = 'O';
6222 strLine += '\r';
6223 Send(hSocket, strLine.c_str());
6224 continue;
6225 }
6226 }
6227 return fRet;
6228 }
6229 }
6230
6231 int RecvUntil(SOCKET hSocket, const char* psz1, const char* psz2=NULL, const char* psz3=NULL, const char* psz4=NULL)
6232 {
6233 loop
6234 {
6235 string strLine;
6236 strLine.reserve(10000);
6237 if (!RecvLineIRC(hSocket, strLine))
6238 return 0;
6239 printf("IRC %s\n", strLine.c_str());
6240 if (psz1 && strLine.find(psz1) != -1)
6241 return 1;
6242 if (psz2 && strLine.find(psz2) != -1)
6243 return 2;
6244 if (psz3 && strLine.find(psz3) != -1)
6245 return 3;
6246 if (psz4 && strLine.find(psz4) != -1)
6247 return 4;
6248 }
6249 }
6250
6251 bool Wait(int nSeconds)
6252 {
6253 if (fShutdown)
6254 return false;
6255 printf("IRC waiting %d seconds to reconnect\n", nSeconds);
6256 for (int i = 0; i < nSeconds; i++)
6257 {
6258 if (fShutdown)
6259 return false;
6260 Sleep(1000);
6261 }
6262 return true;
6263 }
6264
6265 bool RecvCodeLine(SOCKET hSocket, const char* psz1, string& strRet)
6266 {
6267 strRet.clear();
6268 loop
6269 {
6270 string strLine;
6271 if (!RecvLineIRC(hSocket, strLine))
6272 return false;
6273
6274 vector<string> vWords;
6275 ParseString(strLine, ' ', vWords);
6276 if (vWords.size() < 2)
6277 continue;
6278
6279 if (vWords[1] == psz1)
6280 {
6281 printf("IRC %s\n", strLine.c_str());
6282 strRet = strLine;
6283 return true;
6284 }
6285 }
6286 }
6287
6288 bool GetIPFromIRC(SOCKET hSocket, string strMyName, unsigned int& ipRet)
6289 {
6290 Send(hSocket, strprintf("USERHOST %s\r", strMyName.c_str()).c_str());
6291
6292 string strLine;
6293 if (!RecvCodeLine(hSocket, "302", strLine))
6294 return false;
6295
6296 vector<string> vWords;
6297 ParseString(strLine, ' ', vWords);
6298 if (vWords.size() < 4)
6299 return false;
6300
6301 string str = vWords[3];
6302 if (str.rfind("@") == string::npos)
6303 return false;
6304 string strHost = str.substr(str.rfind("@")+1);
6305
6306 // Hybrid IRC used by lfnet always returns IP when you userhost yourself,
6307 // but in case another IRC is ever used this should work.
6308 printf("GetIPFromIRC() got userhost %s\n", strHost.c_str());
6309 if (fUseProxy)
6310 return false;
6311 CAddress addr(strHost, 0, true);
6312 if (!addr.IsValid())
6313 return false;
6314 ipRet = addr.ip;
6315
6316 return true;
6317 }
6318
6319
6320
6321 void ThreadIRCSeed(void* parg)
6322 {
6323 IMPLEMENT_RANDOMIZE_STACK(ThreadIRCSeed(parg));
6324 try
6325 {
6326 ThreadIRCSeed2(parg);
6327 }
6328 catch (std::exception& e) {
6329 PrintExceptionContinue(&e, "ThreadIRCSeed()");
6330 } catch (...) {
6331 PrintExceptionContinue(NULL, "ThreadIRCSeed()");
6332 }
6333 printf("ThreadIRCSeed exiting\n");
6334 }
6335
6336 void ThreadIRCSeed2(void* parg)
6337 {
6338 /* Dont advertise on IRC if we don't allow incoming connections */
6339 if (mapArgs.count("-connect") || fNoListen)
6340 return;
6341
6342 if (GetBoolArg("-noirc"))
6343 return;
6344 printf("ThreadIRCSeed started\n");
6345 int nErrorWait = 10;
6346 int nRetryWait = 10;
6347 bool fNameInUse = false;
6348
6349 while (!fShutdown)
6350 {
6351 CAddress addrConnect("92.243.23.21", 6667); // irc.lfnet.org
6352
6353 CAddress addrIRC("irc.lfnet.org", 6667, true);
6354 if (addrIRC.IsValid())
6355 addrConnect = addrIRC;
6356
6357 SOCKET hSocket;
6358 if (!ConnectSocket(addrConnect, hSocket))
6359 {
6360 printf("IRC connect failed\n");
6361 nErrorWait = nErrorWait * 11 / 10;
6362 if (Wait(nErrorWait += 60))
6363 continue;
6364 else
6365 return;
6366 }
6367
6368 if (!RecvUntil(hSocket, "Found your hostname", "using your IP address instead", "Couldn't look up your hostname", "ignoring hostname"))
6369 {
6370 closesocket(hSocket);
6371 hSocket = INVALID_SOCKET;
6372 nErrorWait = nErrorWait * 11 / 10;
6373 if (Wait(nErrorWait += 60))
6374 continue;
6375 else
6376 return;
6377 }
6378
6379 string strMyName;
6380 if (addrLocalHost.IsRoutable() && !fUseProxy && !fNameInUse)
6381 strMyName = EncodeAddress(addrLocalHost);
6382 else
6383 strMyName = strprintf("x%u", GetRand(1000000000));
6384
6385 Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str());
6386 Send(hSocket, strprintf("USER %s 8 * : %s\r", strMyName.c_str(), strMyName.c_str()).c_str());
6387
6388 int nRet = RecvUntil(hSocket, " 004 ", " 433 ");
6389 if (nRet != 1)
6390 {
6391 closesocket(hSocket);
6392 hSocket = INVALID_SOCKET;
6393 if (nRet == 2)
6394 {
6395 printf("IRC name already in use\n");
6396 fNameInUse = true;
6397 Wait(10);
6398 continue;
6399 }
6400 nErrorWait = nErrorWait * 11 / 10;
6401 if (Wait(nErrorWait += 60))
6402 continue;
6403 else
6404 return;
6405 }
6406 Sleep(500);
6407
6408 // Get our external IP from the IRC server and re-nick before joining the channel
6409 CAddress addrFromIRC;
6410 if (GetIPFromIRC(hSocket, strMyName, addrFromIRC.ip))
6411 {
6412 printf("GetIPFromIRC() returned %s\n", addrFromIRC.ToStringIP().c_str());
6413 if (!fUseProxy && addrFromIRC.IsRoutable())
6414 {
6415 // IRC lets you to re-nick
6416 fGotExternalIP = true;
6417 addrLocalHost.ip = addrFromIRC.ip;
6418 strMyName = EncodeAddress(addrLocalHost);
6419 Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str());
6420 }
6421 }
6422
6423 if (fTestNet) {
6424 Send(hSocket, "JOIN #bitcoinTEST\r");
6425 Send(hSocket, "WHO #bitcoinTEST\r");
6426 } else {
6427 // randomly join #bitcoin00-#bitcoin99
6428 int channel_number = GetRandInt(100);
6429 Send(hSocket, strprintf("JOIN #bitcoin%02d\r", channel_number).c_str());
6430 Send(hSocket, strprintf("WHO #bitcoin%02d\r", channel_number).c_str());
6431 }
6432
6433 int64 nStart = GetTime();
6434 string strLine;
6435 strLine.reserve(10000);
6436 while (!fShutdown && RecvLineIRC(hSocket, strLine))
6437 {
6438 if (strLine.empty() || strLine.size() > 900 || strLine[0] != ':')
6439 continue;
6440
6441 vector<string> vWords;
6442 ParseString(strLine, ' ', vWords);
6443 if (vWords.size() < 2)
6444 continue;
6445
6446 char pszName[10000];
6447 pszName[0] = '\0';
6448
6449 if (vWords[1] == "352" && vWords.size() >= 8)
6450 {
6451 // index 7 is limited to 16 characters
6452 // could get full length name at index 10, but would be different from join messages
6453 strlcpy(pszName, vWords[7].c_str(), sizeof(pszName));
6454 printf("IRC got who\n");
6455 }
6456
6457 if (vWords[1] == "JOIN" && vWords[0].size() > 1)
6458 {
6459 // :username!username@50000007.F000000B.90000002.IP JOIN :#channelname
6460 strlcpy(pszName, vWords[0].c_str() + 1, sizeof(pszName));
6461 if (strchr(pszName, '!'))
6462 *strchr(pszName, '!') = '\0';
6463 printf("IRC got join\n");
6464 }
6465
6466 if (pszName[0] == 'u')
6467 {
6468 CAddress addr;
6469 if (DecodeAddress(pszName, addr))
6470 {
6471 addr.nTime = GetAdjustedTime();
6472 if (AddAddress(addr, 51 * 60))
6473 printf("IRC got new address: %s\n", addr.ToString().c_str());
6474 nGotIRCAddresses++;
6475 }
6476 else
6477 {
6478 printf("IRC decode failed\n");
6479 }
6480 }
6481 }
6482 closesocket(hSocket);
6483 hSocket = INVALID_SOCKET;
6484
6485 if (GetTime() - nStart > 20 * 60)
6486 {
6487 nErrorWait /= 3;
6488 nRetryWait /= 3;
6489 }
6490
6491 nRetryWait = nRetryWait * 11 / 10;
6492 if (!Wait(nRetryWait += 60))
6493 return;
6494 }
6495 }
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506 #ifdef TEST
6507 int main(int argc, char *argv[])
6508 {
6509 WSADATA wsadata;
6510 if (WSAStartup(MAKEWORD(2,2), &wsadata) != NO_ERROR)
6511 {
6512 printf("Error at WSAStartup()\n");
6513 return false;
6514 }
6515
6516 ThreadIRCSeed(NULL);
6517
6518 WSACleanup();
6519 return 0;
6520 }
6521 #endif
-
+ ED3B395DC5D402E50FB6A46188AC5AC5AC249F9A0FF7EB026F66B1B3CB057C1FB660C76EC0626CADDC056B36F208CB8951603316A49B2F2EA25721EFE05B5B4D
bitcoin/src/irc.h
(0 . 0)(1 . 14)
6526 // Copyright (c) 2009-2010 Satoshi Nakamoto
6527 // Copyright (c) 2011 The Bitcoin developers
6528 // Distributed under the MIT/X11 software license, see the accompanying
6529 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
6530 #ifndef BITCOIN_IRC_H
6531 #define BITCOIN_IRC_H
6532
6533 bool RecvLine(SOCKET hSocket, std::string& strLine);
6534 void ThreadIRCSeed(void* parg);
6535
6536 extern int nGotIRCAddresses;
6537 extern bool fGotExternalIP;
6538
6539 #endif
-
+ 36826C0EB701B0DCEB3FA63898318089CC6574EB7AE37351A614837E9960807643B7FDF6882EFB36366AED3754EAE7CF888A80CA808E39B249F09C265AC3E4FF
bitcoin/src/json/LICENSE.txt
(0 . 0)(1 . 24)
6544 The MIT License
6545
6546 Copyright (c) 2007 - 2009 John W. Wilkinson
6547
6548 Permission is hereby granted, free of charge, to any person
6549 obtaining a copy of this software and associated documentation
6550 files (the "Software"), to deal in the Software without
6551 restriction, including without limitation the rights to use,
6552 copy, modify, merge, publish, distribute, sublicense, and/or sell
6553 copies of the Software, and to permit persons to whom the
6554 Software is furnished to do so, subject to the following
6555 conditions:
6556
6557 The above copyright notice and this permission notice shall be
6558 included in all copies or substantial portions of the Software.
6559
6560 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
6561 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
6562 OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
6563 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
6564 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
6565 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
6566 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
6567 OTHER DEALINGS IN THE SOFTWARE.
-
+ 67E4DA87D6BB985B4DFCDC2004793A6925B7E52995FEA0E1854579D8C16D958C43A7CB16C9DDDF6C6CE4418A27217A82D6184577A3B7A91094A2DFF5516C6850
bitcoin/src/json/json_spirit.h
(0 . 0)(1 . 18)
6572 #ifndef JSON_SPIRIT
6573 #define JSON_SPIRIT
6574
6575 // Copyright John W. Wilkinson 2007 - 2009.
6576 // Distributed under the MIT License, see accompanying file LICENSE.txt
6577
6578 // json spirit version 4.03
6579
6580 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
6581 # pragma once
6582 #endif
6583
6584 #include "json_spirit_value.h"
6585 #include "json_spirit_reader.h"
6586 #include "json_spirit_writer.h"
6587 #include "json_spirit_utils.h"
6588
6589 #endif
-
+ 600ED3109FE300901FCE137014A6B34A72A27F7E701DAE5AAB442BE3BC4DDF70E2C23D648EC468D889FEE6BA7CA572093262028B503BD1F948C72F6819A5FB6F
bitcoin/src/json/json_spirit_error_position.h
(0 . 0)(1 . 54)
6594 #ifndef JSON_SPIRIT_ERROR_POSITION
6595 #define JSON_SPIRIT_ERROR_POSITION
6596
6597 // Copyright John W. Wilkinson 2007 - 2009.
6598 // Distributed under the MIT License, see accompanying file LICENSE.txt
6599
6600 // json spirit version 4.03
6601
6602 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
6603 # pragma once
6604 #endif
6605
6606 #include <string>
6607
6608 namespace json_spirit
6609 {
6610 // An Error_position exception is thrown by the "read_or_throw" functions below on finding an error.
6611 // Note the "read_or_throw" functions are around 3 times slower than the standard functions "read"
6612 // functions that return a bool.
6613 //
6614 struct Error_position
6615 {
6616 Error_position();
6617 Error_position( unsigned int line, unsigned int column, const std::string& reason );
6618 bool operator==( const Error_position& lhs ) const;
6619 unsigned int line_;
6620 unsigned int column_;
6621 std::string reason_;
6622 };
6623
6624 inline Error_position::Error_position()
6625 : line_( 0 )
6626 , column_( 0 )
6627 {
6628 }
6629
6630 inline Error_position::Error_position( unsigned int line, unsigned int column, const std::string& reason )
6631 : line_( line )
6632 , column_( column )
6633 , reason_( reason )
6634 {
6635 }
6636
6637 inline bool Error_position::operator==( const Error_position& lhs ) const
6638 {
6639 if( this == &lhs ) return true;
6640
6641 return ( reason_ == lhs.reason_ ) &&
6642 ( line_ == lhs.line_ ) &&
6643 ( column_ == lhs.column_ );
6644 }
6645 }
6646
6647 #endif
-
+ 0DB39BEC3533E078194704458FB981941C6A9EA452C1B7C9A1C71E56FD5EE463B4455503C76A2BF1BD1F9415BB920D7B0F9322167BB1507F87EFA4764A5D11DF
bitcoin/src/json/json_spirit_reader.cpp
(0 . 0)(1 . 137)
6652 // Copyright John W. Wilkinson 2007 - 2009.
6653 // Distributed under the MIT License, see accompanying file LICENSE.txt
6654
6655 // json spirit version 4.03
6656
6657 #include "json_spirit_reader.h"
6658 #include "json_spirit_reader_template.h"
6659
6660 using namespace json_spirit;
6661
6662 bool json_spirit::read( const std::string& s, Value& value )
6663 {
6664 return read_string( s, value );
6665 }
6666
6667 void json_spirit::read_or_throw( const std::string& s, Value& value )
6668 {
6669 read_string_or_throw( s, value );
6670 }
6671
6672 bool json_spirit::read( std::istream& is, Value& value )
6673 {
6674 return read_stream( is, value );
6675 }
6676
6677 void json_spirit::read_or_throw( std::istream& is, Value& value )
6678 {
6679 read_stream_or_throw( is, value );
6680 }
6681
6682 bool json_spirit::read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value )
6683 {
6684 return read_range( begin, end, value );
6685 }
6686
6687 void json_spirit::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value )
6688 {
6689 begin = read_range_or_throw( begin, end, value );
6690 }
6691
6692 #ifndef BOOST_NO_STD_WSTRING
6693
6694 bool json_spirit::read( const std::wstring& s, wValue& value )
6695 {
6696 return read_string( s, value );
6697 }
6698
6699 void json_spirit::read_or_throw( const std::wstring& s, wValue& value )
6700 {
6701 read_string_or_throw( s, value );
6702 }
6703
6704 bool json_spirit::read( std::wistream& is, wValue& value )
6705 {
6706 return read_stream( is, value );
6707 }
6708
6709 void json_spirit::read_or_throw( std::wistream& is, wValue& value )
6710 {
6711 read_stream_or_throw( is, value );
6712 }
6713
6714 bool json_spirit::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value )
6715 {
6716 return read_range( begin, end, value );
6717 }
6718
6719 void json_spirit::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value )
6720 {
6721 begin = read_range_or_throw( begin, end, value );
6722 }
6723
6724 #endif
6725
6726 bool json_spirit::read( const std::string& s, mValue& value )
6727 {
6728 return read_string( s, value );
6729 }
6730
6731 void json_spirit::read_or_throw( const std::string& s, mValue& value )
6732 {
6733 read_string_or_throw( s, value );
6734 }
6735
6736 bool json_spirit::read( std::istream& is, mValue& value )
6737 {
6738 return read_stream( is, value );
6739 }
6740
6741 void json_spirit::read_or_throw( std::istream& is, mValue& value )
6742 {
6743 read_stream_or_throw( is, value );
6744 }
6745
6746 bool json_spirit::read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value )
6747 {
6748 return read_range( begin, end, value );
6749 }
6750
6751 void json_spirit::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value )
6752 {
6753 begin = read_range_or_throw( begin, end, value );
6754 }
6755
6756 #ifndef BOOST_NO_STD_WSTRING
6757
6758 bool json_spirit::read( const std::wstring& s, wmValue& value )
6759 {
6760 return read_string( s, value );
6761 }
6762
6763 void json_spirit::read_or_throw( const std::wstring& s, wmValue& value )
6764 {
6765 read_string_or_throw( s, value );
6766 }
6767
6768 bool json_spirit::read( std::wistream& is, wmValue& value )
6769 {
6770 return read_stream( is, value );
6771 }
6772
6773 void json_spirit::read_or_throw( std::wistream& is, wmValue& value )
6774 {
6775 read_stream_or_throw( is, value );
6776 }
6777
6778 bool json_spirit::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value )
6779 {
6780 return read_range( begin, end, value );
6781 }
6782
6783 void json_spirit::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value )
6784 {
6785 begin = read_range_or_throw( begin, end, value );
6786 }
6787
6788 #endif
-
+ BF51A9ABB791037B7890EEFAE05FB29CBBC2BDDA5D01C15BBC784D97CDBB66BF9F6BDB6791D697D68FEDCCEA89661B07AF768F7981287F724921D8F57B6D37C7
bitcoin/src/json/json_spirit_reader.h
(0 . 0)(1 . 62)
6793 #ifndef JSON_SPIRIT_READER
6794 #define JSON_SPIRIT_READER
6795
6796 // Copyright John W. Wilkinson 2007 - 2009.
6797 // Distributed under the MIT License, see accompanying file LICENSE.txt
6798
6799 // json spirit version 4.03
6800
6801 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
6802 # pragma once
6803 #endif
6804
6805 #include "json_spirit_value.h"
6806 #include "json_spirit_error_position.h"
6807 #include <iostream>
6808
6809 namespace json_spirit
6810 {
6811 // functions to reads a JSON values
6812
6813 bool read( const std::string& s, Value& value );
6814 bool read( std::istream& is, Value& value );
6815 bool read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value );
6816
6817 void read_or_throw( const std::string& s, Value& value );
6818 void read_or_throw( std::istream& is, Value& value );
6819 void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value );
6820
6821 #ifndef BOOST_NO_STD_WSTRING
6822
6823 bool read( const std::wstring& s, wValue& value );
6824 bool read( std::wistream& is, wValue& value );
6825 bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value );
6826
6827 void read_or_throw( const std::wstring& s, wValue& value );
6828 void read_or_throw( std::wistream& is, wValue& value );
6829 void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value );
6830
6831 #endif
6832
6833 bool read( const std::string& s, mValue& value );
6834 bool read( std::istream& is, mValue& value );
6835 bool read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value );
6836
6837 void read_or_throw( const std::string& s, mValue& value );
6838 void read_or_throw( std::istream& is, mValue& value );
6839 void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value );
6840
6841 #ifndef BOOST_NO_STD_WSTRING
6842
6843 bool read( const std::wstring& s, wmValue& value );
6844 bool read( std::wistream& is, wmValue& value );
6845 bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value );
6846
6847 void read_or_throw( const std::wstring& s, wmValue& value );
6848 void read_or_throw( std::wistream& is, wmValue& value );
6849 void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value );
6850
6851 #endif
6852 }
6853
6854 #endif
-
+ 4A8C61D35A342DFC91AA5D3B9CFEE382CF8D3296307DB5FB14AC52B13A4B3BDFDEFE138B644B8775F942F4F444913F6A741210D851C8124CE33B526A2C9838B2
bitcoin/src/json/json_spirit_reader_template.h
(0 . 0)(1 . 612)
6859 #ifndef JSON_SPIRIT_READER_TEMPLATE
6860 #define JSON_SPIRIT_READER_TEMPLATE
6861
6862 // Copyright John W. Wilkinson 2007 - 2009.
6863 // Distributed under the MIT License, see accompanying file LICENSE.txt
6864
6865 // json spirit version 4.03
6866
6867 #include "json_spirit_value.h"
6868 #include "json_spirit_error_position.h"
6869
6870 //#define BOOST_SPIRIT_THREADSAFE // uncomment for multithreaded use, requires linking to boost.thread
6871
6872 #include <boost/bind.hpp>
6873 #include <boost/function.hpp>
6874 #include <boost/version.hpp>
6875
6876 #if BOOST_VERSION >= 103800
6877 #include <boost/spirit/include/classic_core.hpp>
6878 #include <boost/spirit/include/classic_confix.hpp>
6879 #include <boost/spirit/include/classic_escape_char.hpp>
6880 #include <boost/spirit/include/classic_multi_pass.hpp>
6881 #include <boost/spirit/include/classic_position_iterator.hpp>
6882 #define spirit_namespace boost::spirit::classic
6883 #else
6884 #include <boost/spirit/core.hpp>
6885 #include <boost/spirit/utility/confix.hpp>
6886 #include <boost/spirit/utility/escape_char.hpp>
6887 #include <boost/spirit/iterator/multi_pass.hpp>
6888 #include <boost/spirit/iterator/position_iterator.hpp>
6889 #define spirit_namespace boost::spirit
6890 #endif
6891
6892 namespace json_spirit
6893 {
6894 const spirit_namespace::int_parser < boost::int64_t > int64_p = spirit_namespace::int_parser < boost::int64_t >();
6895 const spirit_namespace::uint_parser< boost::uint64_t > uint64_p = spirit_namespace::uint_parser< boost::uint64_t >();
6896
6897 template< class Iter_type >
6898 bool is_eq( Iter_type first, Iter_type last, const char* c_str )
6899 {
6900 for( Iter_type i = first; i != last; ++i, ++c_str )
6901 {
6902 if( *c_str == 0 ) return false;
6903
6904 if( *i != *c_str ) return false;
6905 }
6906
6907 return true;
6908 }
6909
6910 template< class Char_type >
6911 Char_type hex_to_num( const Char_type c )
6912 {
6913 if( ( c >= '0' ) && ( c <= '9' ) ) return c - '0';
6914 if( ( c >= 'a' ) && ( c <= 'f' ) ) return c - 'a' + 10;
6915 if( ( c >= 'A' ) && ( c <= 'F' ) ) return c - 'A' + 10;
6916 return 0;
6917 }
6918
6919 template< class Char_type, class Iter_type >
6920 Char_type hex_str_to_char( Iter_type& begin )
6921 {
6922 const Char_type c1( *( ++begin ) );
6923 const Char_type c2( *( ++begin ) );
6924
6925 return ( hex_to_num( c1 ) << 4 ) + hex_to_num( c2 );
6926 }
6927
6928 template< class Char_type, class Iter_type >
6929 Char_type unicode_str_to_char( Iter_type& begin )
6930 {
6931 const Char_type c1( *( ++begin ) );
6932 const Char_type c2( *( ++begin ) );
6933 const Char_type c3( *( ++begin ) );
6934 const Char_type c4( *( ++begin ) );
6935
6936 return ( hex_to_num( c1 ) << 12 ) +
6937 ( hex_to_num( c2 ) << 8 ) +
6938 ( hex_to_num( c3 ) << 4 ) +
6939 hex_to_num( c4 );
6940 }
6941
6942 template< class String_type >
6943 void append_esc_char_and_incr_iter( String_type& s,
6944 typename String_type::const_iterator& begin,
6945 typename String_type::const_iterator end )
6946 {
6947 typedef typename String_type::value_type Char_type;
6948
6949 const Char_type c2( *begin );
6950
6951 switch( c2 )
6952 {
6953 case 't': s += '\t'; break;
6954 case 'b': s += '\b'; break;
6955 case 'f': s += '\f'; break;
6956 case 'n': s += '\n'; break;
6957 case 'r': s += '\r'; break;
6958 case '\\': s += '\\'; break;
6959 case '/': s += '/'; break;
6960 case '"': s += '"'; break;
6961 case 'x':
6962 {
6963 if( end - begin >= 3 ) // expecting "xHH..."
6964 {
6965 s += hex_str_to_char< Char_type >( begin );
6966 }
6967 break;
6968 }
6969 case 'u':
6970 {
6971 if( end - begin >= 5 ) // expecting "uHHHH..."
6972 {
6973 s += unicode_str_to_char< Char_type >( begin );
6974 }
6975 break;
6976 }
6977 }
6978 }
6979
6980 template< class String_type >
6981 String_type substitute_esc_chars( typename String_type::const_iterator begin,
6982 typename String_type::const_iterator end )
6983 {
6984 typedef typename String_type::const_iterator Iter_type;
6985
6986 if( end - begin < 2 ) return String_type( begin, end );
6987
6988 String_type result;
6989
6990 result.reserve( end - begin );
6991
6992 const Iter_type end_minus_1( end - 1 );
6993
6994 Iter_type substr_start = begin;
6995 Iter_type i = begin;
6996
6997 for( ; i < end_minus_1; ++i )
6998 {
6999 if( *i == '\\' )
7000 {
7001 result.append( substr_start, i );
7002
7003 ++i; // skip the '\'
7004
7005 append_esc_char_and_incr_iter( result, i, end );
7006
7007 substr_start = i + 1;
7008 }
7009 }
7010
7011 result.append( substr_start, end );
7012
7013 return result;
7014 }
7015
7016 template< class String_type >
7017 String_type get_str_( typename String_type::const_iterator begin,
7018 typename String_type::const_iterator end )
7019 {
7020 assert( end - begin >= 2 );
7021
7022 typedef typename String_type::const_iterator Iter_type;
7023
7024 Iter_type str_without_quotes( ++begin );
7025 Iter_type end_without_quotes( --end );
7026
7027 return substitute_esc_chars< String_type >( str_without_quotes, end_without_quotes );
7028 }
7029
7030 inline std::string get_str( std::string::const_iterator begin, std::string::const_iterator end )
7031 {
7032 return get_str_< std::string >( begin, end );
7033 }
7034
7035 inline std::wstring get_str( std::wstring::const_iterator begin, std::wstring::const_iterator end )
7036 {
7037 return get_str_< std::wstring >( begin, end );
7038 }
7039
7040 template< class String_type, class Iter_type >
7041 String_type get_str( Iter_type begin, Iter_type end )
7042 {
7043 const String_type tmp( begin, end ); // convert multipass iterators to string iterators
7044
7045 return get_str( tmp.begin(), tmp.end() );
7046 }
7047
7048 // this class's methods get called by the spirit parse resulting
7049 // in the creation of a JSON object or array
7050 //
7051 // NB Iter_type could be a std::string iterator, wstring iterator, a position iterator or a multipass iterator
7052 //
7053 template< class Value_type, class Iter_type >
7054 class Semantic_actions
7055 {
7056 public:
7057
7058 typedef typename Value_type::Config_type Config_type;
7059 typedef typename Config_type::String_type String_type;
7060 typedef typename Config_type::Object_type Object_type;
7061 typedef typename Config_type::Array_type Array_type;
7062 typedef typename String_type::value_type Char_type;
7063
7064 Semantic_actions( Value_type& value )
7065 : value_( value )
7066 , current_p_( 0 )
7067 {
7068 }
7069
7070 void begin_obj( Char_type c )
7071 {
7072 assert( c == '{' );
7073
7074 begin_compound< Object_type >();
7075 }
7076
7077 void end_obj( Char_type c )
7078 {
7079 assert( c == '}' );
7080
7081 end_compound();
7082 }
7083
7084 void begin_array( Char_type c )
7085 {
7086 assert( c == '[' );
7087
7088 begin_compound< Array_type >();
7089 }
7090
7091 void end_array( Char_type c )
7092 {
7093 assert( c == ']' );
7094
7095 end_compound();
7096 }
7097
7098 void new_name( Iter_type begin, Iter_type end )
7099 {
7100 assert( current_p_->type() == obj_type );
7101
7102 name_ = get_str< String_type >( begin, end );
7103 }
7104
7105 void new_str( Iter_type begin, Iter_type end )
7106 {
7107 add_to_current( get_str< String_type >( begin, end ) );
7108 }
7109
7110 void new_true( Iter_type begin, Iter_type end )
7111 {
7112 assert( is_eq( begin, end, "true" ) );
7113
7114 add_to_current( true );
7115 }
7116
7117 void new_false( Iter_type begin, Iter_type end )
7118 {
7119 assert( is_eq( begin, end, "false" ) );
7120
7121 add_to_current( false );
7122 }
7123
7124 void new_null( Iter_type begin, Iter_type end )
7125 {
7126 assert( is_eq( begin, end, "null" ) );
7127
7128 add_to_current( Value_type() );
7129 }
7130
7131 void new_int( boost::int64_t i )
7132 {
7133 add_to_current( i );
7134 }
7135
7136 void new_uint64( boost::uint64_t ui )
7137 {
7138 add_to_current( ui );
7139 }
7140
7141 void new_real( double d )
7142 {
7143 add_to_current( d );
7144 }
7145
7146 private:
7147
7148 Semantic_actions& operator=( const Semantic_actions& );
7149 // to prevent "assignment operator could not be generated" warning
7150
7151 Value_type* add_first( const Value_type& value )
7152 {
7153 assert( current_p_ == 0 );
7154
7155 value_ = value;
7156 current_p_ = &value_;
7157 return current_p_;
7158 }
7159
7160 template< class Array_or_obj >
7161 void begin_compound()
7162 {
7163 if( current_p_ == 0 )
7164 {
7165 add_first( Array_or_obj() );
7166 }
7167 else
7168 {
7169 stack_.push_back( current_p_ );
7170
7171 Array_or_obj new_array_or_obj; // avoid copy by building new array or object in place
7172
7173 current_p_ = add_to_current( new_array_or_obj );
7174 }
7175 }
7176
7177 void end_compound()
7178 {
7179 if( current_p_ != &value_ )
7180 {
7181 current_p_ = stack_.back();
7182
7183 stack_.pop_back();
7184 }
7185 }
7186
7187 Value_type* add_to_current( const Value_type& value )
7188 {
7189 if( current_p_ == 0 )
7190 {
7191 return add_first( value );
7192 }
7193 else if( current_p_->type() == array_type )
7194 {
7195 current_p_->get_array().push_back( value );
7196
7197 return ¤t_p_->get_array().back();
7198 }
7199
7200 assert( current_p_->type() == obj_type );
7201
7202 return &Config_type::add( current_p_->get_obj(), name_, value );
7203 }
7204
7205 Value_type& value_; // this is the object or array that is being created
7206 Value_type* current_p_; // the child object or array that is currently being constructed
7207
7208 std::vector< Value_type* > stack_; // previous child objects and arrays
7209
7210 String_type name_; // of current name/value pair
7211 };
7212
7213 template< typename Iter_type >
7214 void throw_error( spirit_namespace::position_iterator< Iter_type > i, const std::string& reason )
7215 {
7216 throw Error_position( i.get_position().line, i.get_position().column, reason );
7217 }
7218
7219 template< typename Iter_type >
7220 void throw_error( Iter_type i, const std::string& reason )
7221 {
7222 throw reason;
7223 }
7224
7225 // the spirit grammer
7226 //
7227 template< class Value_type, class Iter_type >
7228 class Json_grammer : public spirit_namespace::grammar< Json_grammer< Value_type, Iter_type > >
7229 {
7230 public:
7231
7232 typedef Semantic_actions< Value_type, Iter_type > Semantic_actions_t;
7233
7234 Json_grammer( Semantic_actions_t& semantic_actions )
7235 : actions_( semantic_actions )
7236 {
7237 }
7238
7239 static void throw_not_value( Iter_type begin, Iter_type end )
7240 {
7241 throw_error( begin, "not a value" );
7242 }
7243
7244 static void throw_not_array( Iter_type begin, Iter_type end )
7245 {
7246 throw_error( begin, "not an array" );
7247 }
7248
7249 static void throw_not_object( Iter_type begin, Iter_type end )
7250 {
7251 throw_error( begin, "not an object" );
7252 }
7253
7254 static void throw_not_pair( Iter_type begin, Iter_type end )
7255 {
7256 throw_error( begin, "not a pair" );
7257 }
7258
7259 static void throw_not_colon( Iter_type begin, Iter_type end )
7260 {
7261 throw_error( begin, "no colon in pair" );
7262 }
7263
7264 static void throw_not_string( Iter_type begin, Iter_type end )
7265 {
7266 throw_error( begin, "not a string" );
7267 }
7268
7269 template< typename ScannerT >
7270 class definition
7271 {
7272 public:
7273
7274 definition( const Json_grammer& self )
7275 {
7276 using namespace spirit_namespace;
7277
7278 typedef typename Value_type::String_type::value_type Char_type;
7279
7280 // first we convert the semantic action class methods to functors with the
7281 // parameter signature expected by spirit
7282
7283 typedef boost::function< void( Char_type ) > Char_action;
7284 typedef boost::function< void( Iter_type, Iter_type ) > Str_action;
7285 typedef boost::function< void( double ) > Real_action;
7286 typedef boost::function< void( boost::int64_t ) > Int_action;
7287 typedef boost::function< void( boost::uint64_t ) > Uint64_action;
7288
7289 Char_action begin_obj ( boost::bind( &Semantic_actions_t::begin_obj, &self.actions_, _1 ) );
7290 Char_action end_obj ( boost::bind( &Semantic_actions_t::end_obj, &self.actions_, _1 ) );
7291 Char_action begin_array( boost::bind( &Semantic_actions_t::begin_array, &self.actions_, _1 ) );
7292 Char_action end_array ( boost::bind( &Semantic_actions_t::end_array, &self.actions_, _1 ) );
7293 Str_action new_name ( boost::bind( &Semantic_actions_t::new_name, &self.actions_, _1, _2 ) );
7294 Str_action new_str ( boost::bind( &Semantic_actions_t::new_str, &self.actions_, _1, _2 ) );
7295 Str_action new_true ( boost::bind( &Semantic_actions_t::new_true, &self.actions_, _1, _2 ) );
7296 Str_action new_false ( boost::bind( &Semantic_actions_t::new_false, &self.actions_, _1, _2 ) );
7297 Str_action new_null ( boost::bind( &Semantic_actions_t::new_null, &self.actions_, _1, _2 ) );
7298 Real_action new_real ( boost::bind( &Semantic_actions_t::new_real, &self.actions_, _1 ) );
7299 Int_action new_int ( boost::bind( &Semantic_actions_t::new_int, &self.actions_, _1 ) );
7300 Uint64_action new_uint64 ( boost::bind( &Semantic_actions_t::new_uint64, &self.actions_, _1 ) );
7301
7302 // actual grammer
7303
7304 json_
7305 = value_ | eps_p[ &throw_not_value ]
7306 ;
7307
7308 value_
7309 = string_[ new_str ]
7310 | number_
7311 | object_
7312 | array_
7313 | str_p( "true" ) [ new_true ]
7314 | str_p( "false" )[ new_false ]
7315 | str_p( "null" ) [ new_null ]
7316 ;
7317
7318 object_
7319 = ch_p('{')[ begin_obj ]
7320 >> !members_
7321 >> ( ch_p('}')[ end_obj ] | eps_p[ &throw_not_object ] )
7322 ;
7323
7324 members_
7325 = pair_ >> *( ',' >> pair_ )
7326 ;
7327
7328 pair_
7329 = string_[ new_name ]
7330 >> ( ':' | eps_p[ &throw_not_colon ] )
7331 >> ( value_ | eps_p[ &throw_not_value ] )
7332 ;
7333
7334 array_
7335 = ch_p('[')[ begin_array ]
7336 >> !elements_
7337 >> ( ch_p(']')[ end_array ] | eps_p[ &throw_not_array ] )
7338 ;
7339
7340 elements_
7341 = value_ >> *( ',' >> value_ )
7342 ;
7343
7344 string_
7345 = lexeme_d // this causes white space inside a string to be retained
7346 [
7347 confix_p
7348 (
7349 '"',
7350 *lex_escape_ch_p,
7351 '"'
7352 )
7353 ]
7354 ;
7355
7356 number_
7357 = strict_real_p[ new_real ]
7358 | int64_p [ new_int ]
7359 | uint64_p [ new_uint64 ]
7360 ;
7361 }
7362
7363 spirit_namespace::rule< ScannerT > json_, object_, members_, pair_, array_, elements_, value_, string_, number_;
7364
7365 const spirit_namespace::rule< ScannerT >& start() const { return json_; }
7366 };
7367
7368 private:
7369
7370 Json_grammer& operator=( const Json_grammer& ); // to prevent "assignment operator could not be generated" warning
7371
7372 Semantic_actions_t& actions_;
7373 };
7374
7375 template< class Iter_type, class Value_type >
7376 Iter_type read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value )
7377 {
7378 Semantic_actions< Value_type, Iter_type > semantic_actions( value );
7379
7380 const spirit_namespace::parse_info< Iter_type > info =
7381 spirit_namespace::parse( begin, end,
7382 Json_grammer< Value_type, Iter_type >( semantic_actions ),
7383 spirit_namespace::space_p );
7384
7385 if( !info.hit )
7386 {
7387 assert( false ); // in theory exception should already have been thrown
7388 throw_error( info.stop, "error" );
7389 }
7390
7391 return info.stop;
7392 }
7393
7394 template< class Iter_type, class Value_type >
7395 void add_posn_iter_and_read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value )
7396 {
7397 typedef spirit_namespace::position_iterator< Iter_type > Posn_iter_t;
7398
7399 const Posn_iter_t posn_begin( begin, end );
7400 const Posn_iter_t posn_end( end, end );
7401
7402 read_range_or_throw( posn_begin, posn_end, value );
7403 }
7404
7405 template< class Iter_type, class Value_type >
7406 bool read_range( Iter_type& begin, Iter_type end, Value_type& value )
7407 {
7408 try
7409 {
7410 begin = read_range_or_throw( begin, end, value );
7411
7412 return true;
7413 }
7414 catch( ... )
7415 {
7416 return false;
7417 }
7418 }
7419
7420 template< class String_type, class Value_type >
7421 void read_string_or_throw( const String_type& s, Value_type& value )
7422 {
7423 add_posn_iter_and_read_range_or_throw( s.begin(), s.end(), value );
7424 }
7425
7426 template< class String_type, class Value_type >
7427 bool read_string( const String_type& s, Value_type& value )
7428 {
7429 typename String_type::const_iterator begin = s.begin();
7430
7431 return read_range( begin, s.end(), value );
7432 }
7433
7434 template< class Istream_type >
7435 struct Multi_pass_iters
7436 {
7437 typedef typename Istream_type::char_type Char_type;
7438 typedef std::istream_iterator< Char_type, Char_type > istream_iter;
7439 typedef spirit_namespace::multi_pass< istream_iter > Mp_iter;
7440
7441 Multi_pass_iters( Istream_type& is )
7442 {
7443 is.unsetf( std::ios::skipws );
7444
7445 begin_ = spirit_namespace::make_multi_pass( istream_iter( is ) );
7446 end_ = spirit_namespace::make_multi_pass( istream_iter() );
7447 }
7448
7449 Mp_iter begin_;
7450 Mp_iter end_;
7451 };
7452
7453 template< class Istream_type, class Value_type >
7454 bool read_stream( Istream_type& is, Value_type& value )
7455 {
7456 Multi_pass_iters< Istream_type > mp_iters( is );
7457
7458 return read_range( mp_iters.begin_, mp_iters.end_, value );
7459 }
7460
7461 template< class Istream_type, class Value_type >
7462 void read_stream_or_throw( Istream_type& is, Value_type& value )
7463 {
7464 const Multi_pass_iters< Istream_type > mp_iters( is );
7465
7466 add_posn_iter_and_read_range_or_throw( mp_iters.begin_, mp_iters.end_, value );
7467 }
7468 }
7469
7470 #endif
-
+ 42337F7690B2BD5E7267707385097A8D3B9358EC7650157E350994BED86613C6E39338C4CA50F8A145DE430DF19BC00890459F24B82EF703DEF7A21897D85269
bitcoin/src/json/json_spirit_stream_reader.h
(0 . 0)(1 . 70)
7475 #ifndef JSON_SPIRIT_READ_STREAM
7476 #define JSON_SPIRIT_READ_STREAM
7477
7478 // Copyright John W. Wilkinson 2007 - 2009.
7479 // Distributed under the MIT License, see accompanying file LICENSE.txt
7480
7481 // json spirit version 4.03
7482
7483 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
7484 # pragma once
7485 #endif
7486
7487 #include "json_spirit_reader_template.h"
7488
7489 namespace json_spirit
7490 {
7491 // these classes allows you to read multiple top level contiguous values from a stream,
7492 // the normal stream read functions have a bug that prevent multiple top level values
7493 // from being read unless they are separated by spaces
7494
7495 template< class Istream_type, class Value_type >
7496 class Stream_reader
7497 {
7498 public:
7499
7500 Stream_reader( Istream_type& is )
7501 : iters_( is )
7502 {
7503 }
7504
7505 bool read_next( Value_type& value )
7506 {
7507 return read_range( iters_.begin_, iters_.end_, value );
7508 }
7509
7510 private:
7511
7512 typedef Multi_pass_iters< Istream_type > Mp_iters;
7513
7514 Mp_iters iters_;
7515 };
7516
7517 template< class Istream_type, class Value_type >
7518 class Stream_reader_thrower
7519 {
7520 public:
7521
7522 Stream_reader_thrower( Istream_type& is )
7523 : iters_( is )
7524 , posn_begin_( iters_.begin_, iters_.end_ )
7525 , posn_end_( iters_.end_, iters_.end_ )
7526 {
7527 }
7528
7529 void read_next( Value_type& value )
7530 {
7531 posn_begin_ = read_range_or_throw( posn_begin_, posn_end_, value );
7532 }
7533
7534 private:
7535
7536 typedef Multi_pass_iters< Istream_type > Mp_iters;
7537 typedef spirit_namespace::position_iterator< typename Mp_iters::Mp_iter > Posn_iter_t;
7538
7539 Mp_iters iters_;
7540 Posn_iter_t posn_begin_, posn_end_;
7541 };
7542 }
7543
7544 #endif
-
+ 15120F9DC1C9B37D40991756AB600EB8737AF58C4D0C7A80879403C45B1A1935D71EDEC46A6CC5298D7AF4C2C93BAAC1AF00C80C4335F752E4D1F49D9E61B457
bitcoin/src/json/json_spirit_utils.h
(0 . 0)(1 . 61)
7549 #ifndef JSON_SPIRIT_UTILS
7550 #define JSON_SPIRIT_UTILS
7551
7552 // Copyright John W. Wilkinson 2007 - 2009.
7553 // Distributed under the MIT License, see accompanying file LICENSE.txt
7554
7555 // json spirit version 4.03
7556
7557 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
7558 # pragma once
7559 #endif
7560
7561 #include "json_spirit_value.h"
7562 #include <map>
7563
7564 namespace json_spirit
7565 {
7566 template< class Obj_t, class Map_t >
7567 void obj_to_map( const Obj_t& obj, Map_t& mp_obj )
7568 {
7569 mp_obj.clear();
7570
7571 for( typename Obj_t::const_iterator i = obj.begin(); i != obj.end(); ++i )
7572 {
7573 mp_obj[ i->name_ ] = i->value_;
7574 }
7575 }
7576
7577 template< class Obj_t, class Map_t >
7578 void map_to_obj( const Map_t& mp_obj, Obj_t& obj )
7579 {
7580 obj.clear();
7581
7582 for( typename Map_t::const_iterator i = mp_obj.begin(); i != mp_obj.end(); ++i )
7583 {
7584 obj.push_back( typename Obj_t::value_type( i->first, i->second ) );
7585 }
7586 }
7587
7588 typedef std::map< std::string, Value > Mapped_obj;
7589
7590 #ifndef BOOST_NO_STD_WSTRING
7591 typedef std::map< std::wstring, wValue > wMapped_obj;
7592 #endif
7593
7594 template< class Object_type, class String_type >
7595 const typename Object_type::value_type::Value_type& find_value( const Object_type& obj, const String_type& name )
7596 {
7597 for( typename Object_type::const_iterator i = obj.begin(); i != obj.end(); ++i )
7598 {
7599 if( i->name_ == name )
7600 {
7601 return i->value_;
7602 }
7603 }
7604
7605 return Object_type::value_type::Value_type::null;
7606 }
7607 }
7608
7609 #endif
-
+ 55D15E86A580497AAD840C165CB519A992238582A832AF2CE45D8EFE9903149690885F16F499D5B579ECBA6DA99099A210BF63F6250491DD2B0BE884F403D109
bitcoin/src/json/json_spirit_value.cpp
(0 . 0)(1 . 8)
7614 /* Copyright (c) 2007 John W Wilkinson
7615
7616 This source code can be used for any purpose as long as
7617 this comment is retained. */
7618
7619 // json spirit version 2.00
7620
7621 #include "json_spirit_value.h"
-
+ 4D05422B639B54A96DE46317599B34ECAA79B293E7462C44795BBB812E82A65CE291178ED381A6043751D2F72EAB282E694250875BCA47F60B9C9440D59DED8A
bitcoin/src/json/json_spirit_value.h
(0 . 0)(1 . 534)
7626 #ifndef JSON_SPIRIT_VALUE
7627 #define JSON_SPIRIT_VALUE
7628
7629 // Copyright John W. Wilkinson 2007 - 2009.
7630 // Distributed under the MIT License, see accompanying file LICENSE.txt
7631
7632 // json spirit version 4.03
7633
7634 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
7635 # pragma once
7636 #endif
7637
7638 #include <vector>
7639 #include <map>
7640 #include <string>
7641 #include <cassert>
7642 #include <sstream>
7643 #include <stdexcept>
7644 #include <boost/config.hpp>
7645 #include <boost/cstdint.hpp>
7646 #include <boost/shared_ptr.hpp>
7647 #include <boost/variant.hpp>
7648
7649 namespace json_spirit
7650 {
7651 enum Value_type{ obj_type, array_type, str_type, bool_type, int_type, real_type, null_type };
7652 static const char* Value_type_name[]={"obj", "array", "str", "bool", "int", "real", "null"};
7653
7654 template< class Config > // Config determines whether the value uses std::string or std::wstring and
7655 // whether JSON Objects are represented as vectors or maps
7656 class Value_impl
7657 {
7658 public:
7659
7660 typedef Config Config_type;
7661 typedef typename Config::String_type String_type;
7662 typedef typename Config::Object_type Object;
7663 typedef typename Config::Array_type Array;
7664 typedef typename String_type::const_pointer Const_str_ptr; // eg const char*
7665
7666 Value_impl(); // creates null value
7667 Value_impl( Const_str_ptr value );
7668 Value_impl( const String_type& value );
7669 Value_impl( const Object& value );
7670 Value_impl( const Array& value );
7671 Value_impl( bool value );
7672 Value_impl( int value );
7673 Value_impl( boost::int64_t value );
7674 Value_impl( boost::uint64_t value );
7675 Value_impl( double value );
7676
7677 Value_impl( const Value_impl& other );
7678
7679 bool operator==( const Value_impl& lhs ) const;
7680
7681 Value_impl& operator=( const Value_impl& lhs );
7682
7683 Value_type type() const;
7684
7685 bool is_uint64() const;
7686 bool is_null() const;
7687
7688 const String_type& get_str() const;
7689 const Object& get_obj() const;
7690 const Array& get_array() const;
7691 bool get_bool() const;
7692 int get_int() const;
7693 boost::int64_t get_int64() const;
7694 boost::uint64_t get_uint64() const;
7695 double get_real() const;
7696
7697 Object& get_obj();
7698 Array& get_array();
7699
7700 template< typename T > T get_value() const; // example usage: int i = value.get_value< int >();
7701 // or double d = value.get_value< double >();
7702
7703 static const Value_impl null;
7704
7705 private:
7706
7707 void check_type( const Value_type vtype ) const;
7708
7709 typedef boost::variant< String_type,
7710 boost::recursive_wrapper< Object >, boost::recursive_wrapper< Array >,
7711 bool, boost::int64_t, double > Variant;
7712
7713 Value_type type_;
7714 Variant v_;
7715 bool is_uint64_;
7716 };
7717
7718 // vector objects
7719
7720 template< class Config >
7721 struct Pair_impl
7722 {
7723 typedef typename Config::String_type String_type;
7724 typedef typename Config::Value_type Value_type;
7725
7726 Pair_impl( const String_type& name, const Value_type& value );
7727
7728 bool operator==( const Pair_impl& lhs ) const;
7729
7730 String_type name_;
7731 Value_type value_;
7732 };
7733
7734 template< class String >
7735 struct Config_vector
7736 {
7737 typedef String String_type;
7738 typedef Value_impl< Config_vector > Value_type;
7739 typedef Pair_impl < Config_vector > Pair_type;
7740 typedef std::vector< Value_type > Array_type;
7741 typedef std::vector< Pair_type > Object_type;
7742
7743 static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value )
7744 {
7745 obj.push_back( Pair_type( name , value ) );
7746
7747 return obj.back().value_;
7748 }
7749
7750 static String_type get_name( const Pair_type& pair )
7751 {
7752 return pair.name_;
7753 }
7754
7755 static Value_type get_value( const Pair_type& pair )
7756 {
7757 return pair.value_;
7758 }
7759 };
7760
7761 // typedefs for ASCII
7762
7763 typedef Config_vector< std::string > Config;
7764
7765 typedef Config::Value_type Value;
7766 typedef Config::Pair_type Pair;
7767 typedef Config::Object_type Object;
7768 typedef Config::Array_type Array;
7769
7770 // typedefs for Unicode
7771
7772 #ifndef BOOST_NO_STD_WSTRING
7773
7774 typedef Config_vector< std::wstring > wConfig;
7775
7776 typedef wConfig::Value_type wValue;
7777 typedef wConfig::Pair_type wPair;
7778 typedef wConfig::Object_type wObject;
7779 typedef wConfig::Array_type wArray;
7780 #endif
7781
7782 // map objects
7783
7784 template< class String >
7785 struct Config_map
7786 {
7787 typedef String String_type;
7788 typedef Value_impl< Config_map > Value_type;
7789 typedef std::vector< Value_type > Array_type;
7790 typedef std::map< String_type, Value_type > Object_type;
7791 typedef typename Object_type::value_type Pair_type;
7792
7793 static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value )
7794 {
7795 return obj[ name ] = value;
7796 }
7797
7798 static String_type get_name( const Pair_type& pair )
7799 {
7800 return pair.first;
7801 }
7802
7803 static Value_type get_value( const Pair_type& pair )
7804 {
7805 return pair.second;
7806 }
7807 };
7808
7809 // typedefs for ASCII
7810
7811 typedef Config_map< std::string > mConfig;
7812
7813 typedef mConfig::Value_type mValue;
7814 typedef mConfig::Object_type mObject;
7815 typedef mConfig::Array_type mArray;
7816
7817 // typedefs for Unicode
7818
7819 #ifndef BOOST_NO_STD_WSTRING
7820
7821 typedef Config_map< std::wstring > wmConfig;
7822
7823 typedef wmConfig::Value_type wmValue;
7824 typedef wmConfig::Object_type wmObject;
7825 typedef wmConfig::Array_type wmArray;
7826
7827 #endif
7828
7829 ///////////////////////////////////////////////////////////////////////////////////////////////
7830 //
7831 // implementation
7832
7833 template< class Config >
7834 const Value_impl< Config > Value_impl< Config >::null;
7835
7836 template< class Config >
7837 Value_impl< Config >::Value_impl()
7838 : type_( null_type )
7839 , is_uint64_( false )
7840 {
7841 }
7842
7843 template< class Config >
7844 Value_impl< Config >::Value_impl( const Const_str_ptr value )
7845 : type_( str_type )
7846 , v_( String_type( value ) )
7847 , is_uint64_( false )
7848 {
7849 }
7850
7851 template< class Config >
7852 Value_impl< Config >::Value_impl( const String_type& value )
7853 : type_( str_type )
7854 , v_( value )
7855 , is_uint64_( false )
7856 {
7857 }
7858
7859 template< class Config >
7860 Value_impl< Config >::Value_impl( const Object& value )
7861 : type_( obj_type )
7862 , v_( value )
7863 , is_uint64_( false )
7864 {
7865 }
7866
7867 template< class Config >
7868 Value_impl< Config >::Value_impl( const Array& value )
7869 : type_( array_type )
7870 , v_( value )
7871 , is_uint64_( false )
7872 {
7873 }
7874
7875 template< class Config >
7876 Value_impl< Config >::Value_impl( bool value )
7877 : type_( bool_type )
7878 , v_( value )
7879 , is_uint64_( false )
7880 {
7881 }
7882
7883 template< class Config >
7884 Value_impl< Config >::Value_impl( int value )
7885 : type_( int_type )
7886 , v_( static_cast< boost::int64_t >( value ) )
7887 , is_uint64_( false )
7888 {
7889 }
7890
7891 template< class Config >
7892 Value_impl< Config >::Value_impl( boost::int64_t value )
7893 : type_( int_type )
7894 , v_( value )
7895 , is_uint64_( false )
7896 {
7897 }
7898
7899 template< class Config >
7900 Value_impl< Config >::Value_impl( boost::uint64_t value )
7901 : type_( int_type )
7902 , v_( static_cast< boost::int64_t >( value ) )
7903 , is_uint64_( true )
7904 {
7905 }
7906
7907 template< class Config >
7908 Value_impl< Config >::Value_impl( double value )
7909 : type_( real_type )
7910 , v_( value )
7911 , is_uint64_( false )
7912 {
7913 }
7914
7915 template< class Config >
7916 Value_impl< Config >::Value_impl( const Value_impl< Config >& other )
7917 : type_( other.type() )
7918 , v_( other.v_ )
7919 , is_uint64_( other.is_uint64_ )
7920 {
7921 }
7922
7923 template< class Config >
7924 Value_impl< Config >& Value_impl< Config >::operator=( const Value_impl& lhs )
7925 {
7926 Value_impl tmp( lhs );
7927
7928 std::swap( type_, tmp.type_ );
7929 std::swap( v_, tmp.v_ );
7930 std::swap( is_uint64_, tmp.is_uint64_ );
7931
7932 return *this;
7933 }
7934
7935 template< class Config >
7936 bool Value_impl< Config >::operator==( const Value_impl& lhs ) const
7937 {
7938 if( this == &lhs ) return true;
7939
7940 if( type() != lhs.type() ) return false;
7941
7942 return v_ == lhs.v_;
7943 }
7944
7945 template< class Config >
7946 Value_type Value_impl< Config >::type() const
7947 {
7948 return type_;
7949 }
7950
7951 template< class Config >
7952 bool Value_impl< Config >::is_uint64() const
7953 {
7954 return is_uint64_;
7955 }
7956
7957 template< class Config >
7958 bool Value_impl< Config >::is_null() const
7959 {
7960 return type() == null_type;
7961 }
7962
7963 template< class Config >
7964 void Value_impl< Config >::check_type( const Value_type vtype ) const
7965 {
7966 if( type() != vtype )
7967 {
7968 std::ostringstream os;
7969
7970 ///// Bitcoin: Tell the types by name instead of by number
7971 os << "value is type " << Value_type_name[type()] << ", expected " << Value_type_name[vtype];
7972
7973 throw std::runtime_error( os.str() );
7974 }
7975 }
7976
7977 template< class Config >
7978 const typename Config::String_type& Value_impl< Config >::get_str() const
7979 {
7980 check_type( str_type );
7981
7982 return *boost::get< String_type >( &v_ );
7983 }
7984
7985 template< class Config >
7986 const typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() const
7987 {
7988 check_type( obj_type );
7989
7990 return *boost::get< Object >( &v_ );
7991 }
7992
7993 template< class Config >
7994 const typename Value_impl< Config >::Array& Value_impl< Config >::get_array() const
7995 {
7996 check_type( array_type );
7997
7998 return *boost::get< Array >( &v_ );
7999 }
8000
8001 template< class Config >
8002 bool Value_impl< Config >::get_bool() const
8003 {
8004 check_type( bool_type );
8005
8006 return boost::get< bool >( v_ );
8007 }
8008
8009 template< class Config >
8010 int Value_impl< Config >::get_int() const
8011 {
8012 check_type( int_type );
8013
8014 return static_cast< int >( get_int64() );
8015 }
8016
8017 template< class Config >
8018 boost::int64_t Value_impl< Config >::get_int64() const
8019 {
8020 check_type( int_type );
8021
8022 return boost::get< boost::int64_t >( v_ );
8023 }
8024
8025 template< class Config >
8026 boost::uint64_t Value_impl< Config >::get_uint64() const
8027 {
8028 check_type( int_type );
8029
8030 return static_cast< boost::uint64_t >( get_int64() );
8031 }
8032
8033 template< class Config >
8034 double Value_impl< Config >::get_real() const
8035 {
8036 if( type() == int_type )
8037 {
8038 return is_uint64() ? static_cast< double >( get_uint64() )
8039 : static_cast< double >( get_int64() );
8040 }
8041
8042 check_type( real_type );
8043
8044 return boost::get< double >( v_ );
8045 }
8046
8047 template< class Config >
8048 typename Value_impl< Config >::Object& Value_impl< Config >::get_obj()
8049 {
8050 check_type( obj_type );
8051
8052 return *boost::get< Object >( &v_ );
8053 }
8054
8055 template< class Config >
8056 typename Value_impl< Config >::Array& Value_impl< Config >::get_array()
8057 {
8058 check_type( array_type );
8059
8060 return *boost::get< Array >( &v_ );
8061 }
8062
8063 template< class Config >
8064 Pair_impl< Config >::Pair_impl( const String_type& name, const Value_type& value )
8065 : name_( name )
8066 , value_( value )
8067 {
8068 }
8069
8070 template< class Config >
8071 bool Pair_impl< Config >::operator==( const Pair_impl< Config >& lhs ) const
8072 {
8073 if( this == &lhs ) return true;
8074
8075 return ( name_ == lhs.name_ ) && ( value_ == lhs.value_ );
8076 }
8077
8078 // converts a C string, ie. 8 bit char array, to a string object
8079 //
8080 template < class String_type >
8081 String_type to_str( const char* c_str )
8082 {
8083 String_type result;
8084
8085 for( const char* p = c_str; *p != 0; ++p )
8086 {
8087 result += *p;
8088 }
8089
8090 return result;
8091 }
8092
8093 //
8094
8095 namespace internal_
8096 {
8097 template< typename T >
8098 struct Type_to_type
8099 {
8100 };
8101
8102 template< class Value >
8103 int get_value( const Value& value, Type_to_type< int > )
8104 {
8105 return value.get_int();
8106 }
8107
8108 template< class Value >
8109 boost::int64_t get_value( const Value& value, Type_to_type< boost::int64_t > )
8110 {
8111 return value.get_int64();
8112 }
8113
8114 template< class Value >
8115 boost::uint64_t get_value( const Value& value, Type_to_type< boost::uint64_t > )
8116 {
8117 return value.get_uint64();
8118 }
8119
8120 template< class Value >
8121 double get_value( const Value& value, Type_to_type< double > )
8122 {
8123 return value.get_real();
8124 }
8125
8126 template< class Value >
8127 typename Value::String_type get_value( const Value& value, Type_to_type< typename Value::String_type > )
8128 {
8129 return value.get_str();
8130 }
8131
8132 template< class Value >
8133 typename Value::Array get_value( const Value& value, Type_to_type< typename Value::Array > )
8134 {
8135 return value.get_array();
8136 }
8137
8138 template< class Value >
8139 typename Value::Object get_value( const Value& value, Type_to_type< typename Value::Object > )
8140 {
8141 return value.get_obj();
8142 }
8143
8144 template< class Value >
8145 bool get_value( const Value& value, Type_to_type< bool > )
8146 {
8147 return value.get_bool();
8148 }
8149 }
8150
8151 template< class Config >
8152 template< typename T >
8153 T Value_impl< Config >::get_value() const
8154 {
8155 return internal_::get_value( *this, internal_::Type_to_type< T >() );
8156 }
8157 }
8158
8159 #endif
-
+ EEBC0215F93FBBC671D6FE8615AB3738198070E60322E24597085FD87E635E99F2F90B5EB8DE46869C8B619E7565CEE5A22F199C42BBABDBB08EB71D5D86C0C5
bitcoin/src/json/json_spirit_writer.cpp
(0 . 0)(1 . 95)
8164 // Copyright John W. Wilkinson 2007 - 2009.
8165 // Distributed under the MIT License, see accompanying file LICENSE.txt
8166
8167 // json spirit version 4.03
8168
8169 #include "json_spirit_writer.h"
8170 #include "json_spirit_writer_template.h"
8171
8172 void json_spirit::write( const Value& value, std::ostream& os )
8173 {
8174 write_stream( value, os, false );
8175 }
8176
8177 void json_spirit::write_formatted( const Value& value, std::ostream& os )
8178 {
8179 write_stream( value, os, true );
8180 }
8181
8182 std::string json_spirit::write( const Value& value )
8183 {
8184 return write_string( value, false );
8185 }
8186
8187 std::string json_spirit::write_formatted( const Value& value )
8188 {
8189 return write_string( value, true );
8190 }
8191
8192 #ifndef BOOST_NO_STD_WSTRING
8193
8194 void json_spirit::write( const wValue& value, std::wostream& os )
8195 {
8196 write_stream( value, os, false );
8197 }
8198
8199 void json_spirit::write_formatted( const wValue& value, std::wostream& os )
8200 {
8201 write_stream( value, os, true );
8202 }
8203
8204 std::wstring json_spirit::write( const wValue& value )
8205 {
8206 return write_string( value, false );
8207 }
8208
8209 std::wstring json_spirit::write_formatted( const wValue& value )
8210 {
8211 return write_string( value, true );
8212 }
8213
8214 #endif
8215
8216 void json_spirit::write( const mValue& value, std::ostream& os )
8217 {
8218 write_stream( value, os, false );
8219 }
8220
8221 void json_spirit::write_formatted( const mValue& value, std::ostream& os )
8222 {
8223 write_stream( value, os, true );
8224 }
8225
8226 std::string json_spirit::write( const mValue& value )
8227 {
8228 return write_string( value, false );
8229 }
8230
8231 std::string json_spirit::write_formatted( const mValue& value )
8232 {
8233 return write_string( value, true );
8234 }
8235
8236 #ifndef BOOST_NO_STD_WSTRING
8237
8238 void json_spirit::write( const wmValue& value, std::wostream& os )
8239 {
8240 write_stream( value, os, false );
8241 }
8242
8243 void json_spirit::write_formatted( const wmValue& value, std::wostream& os )
8244 {
8245 write_stream( value, os, true );
8246 }
8247
8248 std::wstring json_spirit::write( const wmValue& value )
8249 {
8250 return write_string( value, false );
8251 }
8252
8253 std::wstring json_spirit::write_formatted( const wmValue& value )
8254 {
8255 return write_string( value, true );
8256 }
8257
8258 #endif
-
+ EC290CDE506F90BB24592F3439DBE87602665A63ED44C558C172ACCDD294059319D656A346F6BA68C8CBE90FB8B75158AD59A41EF2A690B18C018DAEC62ABDC0
bitcoin/src/json/json_spirit_writer.h
(0 . 0)(1 . 50)
8263 #ifndef JSON_SPIRIT_WRITER
8264 #define JSON_SPIRIT_WRITER
8265
8266 // Copyright John W. Wilkinson 2007 - 2009.
8267 // Distributed under the MIT License, see accompanying file LICENSE.txt
8268
8269 // json spirit version 4.03
8270
8271 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
8272 # pragma once
8273 #endif
8274
8275 #include "json_spirit_value.h"
8276 #include <iostream>
8277
8278 namespace json_spirit
8279 {
8280 // functions to convert JSON Values to text,
8281 // the "formatted" versions add whitespace to format the output nicely
8282
8283 void write ( const Value& value, std::ostream& os );
8284 void write_formatted( const Value& value, std::ostream& os );
8285 std::string write ( const Value& value );
8286 std::string write_formatted( const Value& value );
8287
8288 #ifndef BOOST_NO_STD_WSTRING
8289
8290 void write ( const wValue& value, std::wostream& os );
8291 void write_formatted( const wValue& value, std::wostream& os );
8292 std::wstring write ( const wValue& value );
8293 std::wstring write_formatted( const wValue& value );
8294
8295 #endif
8296
8297 void write ( const mValue& value, std::ostream& os );
8298 void write_formatted( const mValue& value, std::ostream& os );
8299 std::string write ( const mValue& value );
8300 std::string write_formatted( const mValue& value );
8301
8302 #ifndef BOOST_NO_STD_WSTRING
8303
8304 void write ( const wmValue& value, std::wostream& os );
8305 void write_formatted( const wmValue& value, std::wostream& os );
8306 std::wstring write ( const wmValue& value );
8307 std::wstring write_formatted( const wmValue& value );
8308
8309 #endif
8310 }
8311
8312 #endif
-
+ 075843B80107FE24C8100BA93C9ED3CE8EFF7D711064599A89AB8BF9F771A9A7B9A874960EAC98C36FA2E4D76A5D76BB630F03D651DDF4FF0391876066927E21
bitcoin/src/json/json_spirit_writer_template.h
(0 . 0)(1 . 248)
8317 #ifndef JSON_SPIRIT_WRITER_TEMPLATE
8318 #define JSON_SPIRIT_WRITER_TEMPLATE
8319
8320 // Copyright John W. Wilkinson 2007 - 2009.
8321 // Distributed under the MIT License, see accompanying file LICENSE.txt
8322
8323 // json spirit version 4.03
8324
8325 #include "json_spirit_value.h"
8326
8327 #include <cassert>
8328 #include <sstream>
8329 #include <iomanip>
8330
8331 namespace json_spirit
8332 {
8333 inline char to_hex_char( unsigned int c )
8334 {
8335 assert( c <= 0xF );
8336
8337 const char ch = static_cast< char >( c );
8338
8339 if( ch < 10 ) return '0' + ch;
8340
8341 return 'A' - 10 + ch;
8342 }
8343
8344 template< class String_type >
8345 String_type non_printable_to_string( unsigned int c )
8346 {
8347 typedef typename String_type::value_type Char_type;
8348
8349 String_type result( 6, '\\' );
8350
8351 result[1] = 'u';
8352
8353 result[ 5 ] = to_hex_char( c & 0x000F ); c >>= 4;
8354 result[ 4 ] = to_hex_char( c & 0x000F ); c >>= 4;
8355 result[ 3 ] = to_hex_char( c & 0x000F ); c >>= 4;
8356 result[ 2 ] = to_hex_char( c & 0x000F );
8357
8358 return result;
8359 }
8360
8361 template< typename Char_type, class String_type >
8362 bool add_esc_char( Char_type c, String_type& s )
8363 {
8364 switch( c )
8365 {
8366 case '"': s += to_str< String_type >( "\\\"" ); return true;
8367 case '\\': s += to_str< String_type >( "\\\\" ); return true;
8368 case '\b': s += to_str< String_type >( "\\b" ); return true;
8369 case '\f': s += to_str< String_type >( "\\f" ); return true;
8370 case '\n': s += to_str< String_type >( "\\n" ); return true;
8371 case '\r': s += to_str< String_type >( "\\r" ); return true;
8372 case '\t': s += to_str< String_type >( "\\t" ); return true;
8373 }
8374
8375 return false;
8376 }
8377
8378 template< class String_type >
8379 String_type add_esc_chars( const String_type& s )
8380 {
8381 typedef typename String_type::const_iterator Iter_type;
8382 typedef typename String_type::value_type Char_type;
8383
8384 String_type result;
8385
8386 const Iter_type end( s.end() );
8387
8388 for( Iter_type i = s.begin(); i != end; ++i )
8389 {
8390 const Char_type c( *i );
8391
8392 if( add_esc_char( c, result ) ) continue;
8393
8394 const wint_t unsigned_c( ( c >= 0 ) ? c : 256 + c );
8395
8396 if( iswprint( unsigned_c ) )
8397 {
8398 result += c;
8399 }
8400 else
8401 {
8402 result += non_printable_to_string< String_type >( unsigned_c );
8403 }
8404 }
8405
8406 return result;
8407 }
8408
8409 // this class generates the JSON text,
8410 // it keeps track of the indentation level etc.
8411 //
8412 template< class Value_type, class Ostream_type >
8413 class Generator
8414 {
8415 typedef typename Value_type::Config_type Config_type;
8416 typedef typename Config_type::String_type String_type;
8417 typedef typename Config_type::Object_type Object_type;
8418 typedef typename Config_type::Array_type Array_type;
8419 typedef typename String_type::value_type Char_type;
8420 typedef typename Object_type::value_type Obj_member_type;
8421
8422 public:
8423
8424 Generator( const Value_type& value, Ostream_type& os, bool pretty )
8425 : os_( os )
8426 , indentation_level_( 0 )
8427 , pretty_( pretty )
8428 {
8429 output( value );
8430 }
8431
8432 private:
8433
8434 void output( const Value_type& value )
8435 {
8436 switch( value.type() )
8437 {
8438 case obj_type: output( value.get_obj() ); break;
8439 case array_type: output( value.get_array() ); break;
8440 case str_type: output( value.get_str() ); break;
8441 case bool_type: output( value.get_bool() ); break;
8442 case int_type: output_int( value ); break;
8443
8444 /// Bitcoin: Added std::fixed and changed precision from 16 to 8
8445 case real_type: os_ << std::showpoint << std::fixed << std::setprecision(8)
8446 << value.get_real(); break;
8447
8448 case null_type: os_ << "null"; break;
8449 default: assert( false );
8450 }
8451 }
8452
8453 void output( const Object_type& obj )
8454 {
8455 output_array_or_obj( obj, '{', '}' );
8456 }
8457
8458 void output( const Array_type& arr )
8459 {
8460 output_array_or_obj( arr, '[', ']' );
8461 }
8462
8463 void output( const Obj_member_type& member )
8464 {
8465 output( Config_type::get_name( member ) ); space();
8466 os_ << ':'; space();
8467 output( Config_type::get_value( member ) );
8468 }
8469
8470 void output_int( const Value_type& value )
8471 {
8472 if( value.is_uint64() )
8473 {
8474 os_ << value.get_uint64();
8475 }
8476 else
8477 {
8478 os_ << value.get_int64();
8479 }
8480 }
8481
8482 void output( const String_type& s )
8483 {
8484 os_ << '"' << add_esc_chars( s ) << '"';
8485 }
8486
8487 void output( bool b )
8488 {
8489 os_ << to_str< String_type >( b ? "true" : "false" );
8490 }
8491
8492 template< class T >
8493 void output_array_or_obj( const T& t, Char_type start_char, Char_type end_char )
8494 {
8495 os_ << start_char; new_line();
8496
8497 ++indentation_level_;
8498
8499 for( typename T::const_iterator i = t.begin(); i != t.end(); ++i )
8500 {
8501 indent(); output( *i );
8502
8503 typename T::const_iterator next = i;
8504
8505 if( ++next != t.end())
8506 {
8507 os_ << ',';
8508 }
8509
8510 new_line();
8511 }
8512
8513 --indentation_level_;
8514
8515 indent(); os_ << end_char;
8516 }
8517
8518 void indent()
8519 {
8520 if( !pretty_ ) return;
8521
8522 for( int i = 0; i < indentation_level_; ++i )
8523 {
8524 os_ << " ";
8525 }
8526 }
8527
8528 void space()
8529 {
8530 if( pretty_ ) os_ << ' ';
8531 }
8532
8533 void new_line()
8534 {
8535 if( pretty_ ) os_ << '\n';
8536 }
8537
8538 Generator& operator=( const Generator& ); // to prevent "assignment operator could not be generated" warning
8539
8540 Ostream_type& os_;
8541 int indentation_level_;
8542 bool pretty_;
8543 };
8544
8545 template< class Value_type, class Ostream_type >
8546 void write_stream( const Value_type& value, Ostream_type& os, bool pretty )
8547 {
8548 Generator< Value_type, Ostream_type >( value, os, pretty );
8549 }
8550
8551 template< class Value_type >
8552 typename Value_type::String_type write_string( const Value_type& value, bool pretty )
8553 {
8554 typedef typename Value_type::String_type::value_type Char_type;
8555
8556 std::basic_ostringstream< Char_type > os;
8557
8558 write_stream( value, os, pretty );
8559
8560 return os.str();
8561 }
8562 }
8563
8564 #endif
-
+ 07093A81B0656609E0FA8066A5743D874C5DBDF148309DD6E9ED2050AC0CAC2B07D5AA64983E6BC71BD2BE2FD1D93DD581E66C32A0DA81904AA730E32D43CDD1
bitcoin/src/key.h
(0 . 0)(1 . 406)
8569 // Copyright (c) 2009-2010 Satoshi Nakamoto
8570 // Copyright (c) 2009-2012 The Bitcoin developers
8571 // Distributed under the MIT/X11 software license, see the accompanying
8572 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
8573 #ifndef BITCOIN_KEY_H
8574 #define BITCOIN_KEY_H
8575
8576 #include <stdexcept>
8577 #include <vector>
8578
8579 #include <openssl/ec.h>
8580 #include <openssl/ecdsa.h>
8581 #include <openssl/obj_mac.h>
8582
8583 #include "serialize.h"
8584 #include "uint256.h"
8585 #include "base58.h"
8586
8587 // secp160k1
8588 // const unsigned int PRIVATE_KEY_SIZE = 192;
8589 // const unsigned int PUBLIC_KEY_SIZE = 41;
8590 // const unsigned int SIGNATURE_SIZE = 48;
8591 //
8592 // secp192k1
8593 // const unsigned int PRIVATE_KEY_SIZE = 222;
8594 // const unsigned int PUBLIC_KEY_SIZE = 49;
8595 // const unsigned int SIGNATURE_SIZE = 57;
8596 //
8597 // secp224k1
8598 // const unsigned int PRIVATE_KEY_SIZE = 250;
8599 // const unsigned int PUBLIC_KEY_SIZE = 57;
8600 // const unsigned int SIGNATURE_SIZE = 66;
8601 //
8602 // secp256k1:
8603 // const unsigned int PRIVATE_KEY_SIZE = 279;
8604 // const unsigned int PUBLIC_KEY_SIZE = 65;
8605 // const unsigned int SIGNATURE_SIZE = 72;
8606 //
8607 // see www.keylength.com
8608 // script supports up to 75 for single byte push
8609
8610 // Generate a private key from just the secret parameter
8611 int static inline EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key)
8612 {
8613 int ok = 0;
8614 BN_CTX *ctx = NULL;
8615 EC_POINT *pub_key = NULL;
8616
8617 if (!eckey) return 0;
8618
8619 const EC_GROUP *group = EC_KEY_get0_group(eckey);
8620
8621 if ((ctx = BN_CTX_new()) == NULL)
8622 goto err;
8623
8624 pub_key = EC_POINT_new(group);
8625
8626 if (pub_key == NULL)
8627 goto err;
8628
8629 if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx))
8630 goto err;
8631
8632 EC_KEY_set_private_key(eckey,priv_key);
8633 EC_KEY_set_public_key(eckey,pub_key);
8634
8635 ok = 1;
8636
8637 err:
8638
8639 if (pub_key)
8640 EC_POINT_free(pub_key);
8641 if (ctx != NULL)
8642 BN_CTX_free(ctx);
8643
8644 return(ok);
8645 }
8646
8647 // Perform ECDSA key recovery (see SEC1 4.1.6) for curves over (mod p)-fields
8648 // recid selects which key is recovered
8649 // if check is nonzero, additional checks are performed
8650 int static inline ECDSA_SIG_recover_key_GFp(EC_KEY *eckey, ECDSA_SIG *ecsig, const unsigned char *msg, int msglen, int recid, int check)
8651 {
8652 if (!eckey) return 0;
8653
8654 int ret = 0;
8655 BN_CTX *ctx = NULL;
8656
8657 BIGNUM *x = NULL;
8658 BIGNUM *e = NULL;
8659 BIGNUM *order = NULL;
8660 BIGNUM *sor = NULL;
8661 BIGNUM *eor = NULL;
8662 BIGNUM *field = NULL;
8663 EC_POINT *R = NULL;
8664 EC_POINT *O = NULL;
8665 EC_POINT *Q = NULL;
8666 BIGNUM *rr = NULL;
8667 BIGNUM *zero = NULL;
8668 int n = 0;
8669 int i = recid / 2;
8670
8671 const EC_GROUP *group = EC_KEY_get0_group(eckey);
8672 if ((ctx = BN_CTX_new()) == NULL) { ret = -1; goto err; }
8673 BN_CTX_start(ctx);
8674 order = BN_CTX_get(ctx);
8675 if (!EC_GROUP_get_order(group, order, ctx)) { ret = -2; goto err; }
8676 x = BN_CTX_get(ctx);
8677 if (!BN_copy(x, order)) { ret=-1; goto err; }
8678 if (!BN_mul_word(x, i)) { ret=-1; goto err; }
8679 if (!BN_add(x, x, ecsig->r)) { ret=-1; goto err; }
8680 field = BN_CTX_get(ctx);
8681 if (!EC_GROUP_get_curve_GFp(group, field, NULL, NULL, ctx)) { ret=-2; goto err; }
8682 if (BN_cmp(x, field) >= 0) { ret=0; goto err; }
8683 if ((R = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
8684 if (!EC_POINT_set_compressed_coordinates_GFp(group, R, x, recid % 2, ctx)) { ret=0; goto err; }
8685 if (check)
8686 {
8687 if ((O = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
8688 if (!EC_POINT_mul(group, O, NULL, R, order, ctx)) { ret=-2; goto err; }
8689 if (!EC_POINT_is_at_infinity(group, O)) { ret = 0; goto err; }
8690 }
8691 if ((Q = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
8692 n = EC_GROUP_get_degree(group);
8693 e = BN_CTX_get(ctx);
8694 if (!BN_bin2bn(msg, msglen, e)) { ret=-1; goto err; }
8695 if (8*msglen > n) BN_rshift(e, e, 8-(n & 7));
8696 zero = BN_CTX_get(ctx);
8697 if (!BN_zero(zero)) { ret=-1; goto err; }
8698 if (!BN_mod_sub(e, zero, e, order, ctx)) { ret=-1; goto err; }
8699 rr = BN_CTX_get(ctx);
8700 if (!BN_mod_inverse(rr, ecsig->r, order, ctx)) { ret=-1; goto err; }
8701 sor = BN_CTX_get(ctx);
8702 if (!BN_mod_mul(sor, ecsig->s, rr, order, ctx)) { ret=-1; goto err; }
8703 eor = BN_CTX_get(ctx);
8704 if (!BN_mod_mul(eor, e, rr, order, ctx)) { ret=-1; goto err; }
8705 if (!EC_POINT_mul(group, Q, eor, R, sor, ctx)) { ret=-2; goto err; }
8706 if (!EC_KEY_set_public_key(eckey, Q)) { ret=-2; goto err; }
8707
8708 ret = 1;
8709
8710 err:
8711 if (ctx) {
8712 BN_CTX_end(ctx);
8713 BN_CTX_free(ctx);
8714 }
8715 if (R != NULL) EC_POINT_free(R);
8716 if (O != NULL) EC_POINT_free(O);
8717 if (Q != NULL) EC_POINT_free(Q);
8718 return ret;
8719 }
8720
8721 class key_error : public std::runtime_error
8722 {
8723 public:
8724 explicit key_error(const std::string& str) : std::runtime_error(str) {}
8725 };
8726
8727
8728 // secure_allocator is defined in serialize.h
8729 // CPrivKey is a serialized private key, with all parameters included (279 bytes)
8730 typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
8731 // CSecret is a serialization of just the secret parameter (32 bytes)
8732 typedef std::vector<unsigned char, secure_allocator<unsigned char> > CSecret;
8733
8734 class CKey
8735 {
8736 protected:
8737 EC_KEY* pkey;
8738 bool fSet;
8739
8740 public:
8741 CKey()
8742 {
8743 pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
8744 if (pkey == NULL)
8745 throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed");
8746 fSet = false;
8747 }
8748
8749 CKey(const CKey& b)
8750 {
8751 pkey = EC_KEY_dup(b.pkey);
8752 if (pkey == NULL)
8753 throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed");
8754 fSet = b.fSet;
8755 }
8756
8757 CKey& operator=(const CKey& b)
8758 {
8759 if (!EC_KEY_copy(pkey, b.pkey))
8760 throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed");
8761 fSet = b.fSet;
8762 return (*this);
8763 }
8764
8765 ~CKey()
8766 {
8767 EC_KEY_free(pkey);
8768 }
8769
8770 bool IsNull() const
8771 {
8772 return !fSet;
8773 }
8774
8775 void MakeNewKey()
8776 {
8777 if (!EC_KEY_generate_key(pkey))
8778 throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed");
8779 fSet = true;
8780 }
8781
8782 bool SetPrivKey(const CPrivKey& vchPrivKey)
8783 {
8784 const unsigned char* pbegin = &vchPrivKey[0];
8785 if (!d2i_ECPrivateKey(&pkey, &pbegin, vchPrivKey.size()))
8786 return false;
8787 fSet = true;
8788 return true;
8789 }
8790
8791 bool SetSecret(const CSecret& vchSecret)
8792 {
8793 EC_KEY_free(pkey);
8794 pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
8795 if (pkey == NULL)
8796 throw key_error("CKey::SetSecret() : EC_KEY_new_by_curve_name failed");
8797 if (vchSecret.size() != 32)
8798 throw key_error("CKey::SetSecret() : secret must be 32 bytes");
8799 BIGNUM *bn = BN_bin2bn(&vchSecret[0],32,BN_new());
8800 if (bn == NULL)
8801 throw key_error("CKey::SetSecret() : BN_bin2bn failed");
8802 if (!EC_KEY_regenerate_key(pkey,bn))
8803 {
8804 BN_clear_free(bn);
8805 throw key_error("CKey::SetSecret() : EC_KEY_regenerate_key failed");
8806 }
8807 BN_clear_free(bn);
8808 fSet = true;
8809 return true;
8810 }
8811
8812 CSecret GetSecret() const
8813 {
8814 CSecret vchRet;
8815 vchRet.resize(32);
8816 const BIGNUM *bn = EC_KEY_get0_private_key(pkey);
8817 int nBytes = BN_num_bytes(bn);
8818 if (bn == NULL)
8819 throw key_error("CKey::GetSecret() : EC_KEY_get0_private_key failed");
8820 int n=BN_bn2bin(bn,&vchRet[32 - nBytes]);
8821 if (n != nBytes)
8822 throw key_error("CKey::GetSecret(): BN_bn2bin failed");
8823 return vchRet;
8824 }
8825
8826 CPrivKey GetPrivKey() const
8827 {
8828 unsigned int nSize = i2d_ECPrivateKey(pkey, NULL);
8829 if (!nSize)
8830 throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey failed");
8831 CPrivKey vchPrivKey(nSize, 0);
8832 unsigned char* pbegin = &vchPrivKey[0];
8833 if (i2d_ECPrivateKey(pkey, &pbegin) != nSize)
8834 throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey returned unexpected size");
8835 return vchPrivKey;
8836 }
8837
8838 bool SetPubKey(const std::vector<unsigned char>& vchPubKey)
8839 {
8840 const unsigned char* pbegin = &vchPubKey[0];
8841 if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size()))
8842 return false;
8843 fSet = true;
8844 return true;
8845 }
8846
8847 std::vector<unsigned char> GetPubKey() const
8848 {
8849 unsigned int nSize = i2o_ECPublicKey(pkey, NULL);
8850 if (!nSize)
8851 throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed");
8852 std::vector<unsigned char> vchPubKey(nSize, 0);
8853 unsigned char* pbegin = &vchPubKey[0];
8854 if (i2o_ECPublicKey(pkey, &pbegin) != nSize)
8855 throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size");
8856 return vchPubKey;
8857 }
8858
8859 bool Sign(uint256 hash, std::vector<unsigned char>& vchSig)
8860 {
8861 vchSig.clear();
8862 unsigned char pchSig[10000];
8863 unsigned int nSize = 0;
8864 if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), pchSig, &nSize, pkey))
8865 return false;
8866 vchSig.resize(nSize);
8867 memcpy(&vchSig[0], pchSig, nSize);
8868 return true;
8869 }
8870
8871 // create a compact signature (65 bytes), which allows reconstructing the used public key
8872 // The format is one header byte, followed by two times 32 bytes for the serialized r and s values.
8873 // The header byte: 0x1B = first key with even y, 0x1C = first key with odd y,
8874 // 0x1D = second key with even y, 0x1E = second key with odd y
8875 bool SignCompact(uint256 hash, std::vector<unsigned char>& vchSig)
8876 {
8877 bool fOk = false;
8878 ECDSA_SIG *sig = ECDSA_do_sign((unsigned char*)&hash, sizeof(hash), pkey);
8879 if (sig==NULL)
8880 return false;
8881 vchSig.clear();
8882 vchSig.resize(65,0);
8883 int nBitsR = BN_num_bits(sig->r);
8884 int nBitsS = BN_num_bits(sig->s);
8885 if (nBitsR <= 256 && nBitsS <= 256)
8886 {
8887 int nRecId = -1;
8888 for (int i=0; i<4; i++)
8889 {
8890 CKey keyRec;
8891 keyRec.fSet = true;
8892 if (ECDSA_SIG_recover_key_GFp(keyRec.pkey, sig, (unsigned char*)&hash, sizeof(hash), i, 1) == 1)
8893 if (keyRec.GetPubKey() == this->GetPubKey())
8894 {
8895 nRecId = i;
8896 break;
8897 }
8898 }
8899
8900 if (nRecId == -1)
8901 throw key_error("CKey::SignCompact() : unable to construct recoverable key");
8902
8903 vchSig[0] = nRecId+27;
8904 BN_bn2bin(sig->r,&vchSig[33-(nBitsR+7)/8]);
8905 BN_bn2bin(sig->s,&vchSig[65-(nBitsS+7)/8]);
8906 fOk = true;
8907 }
8908 ECDSA_SIG_free(sig);
8909 return fOk;
8910 }
8911
8912 // reconstruct public key from a compact signature
8913 // This is only slightly more CPU intensive than just verifying it.
8914 // If this function succeeds, the recovered public key is guaranteed to be valid
8915 // (the signature is a valid signature of the given data for that key)
8916 bool SetCompactSignature(uint256 hash, const std::vector<unsigned char>& vchSig)
8917 {
8918 if (vchSig.size() != 65)
8919 return false;
8920 if (vchSig[0]<27 || vchSig[0]>=31)
8921 return false;
8922 ECDSA_SIG *sig = ECDSA_SIG_new();
8923 BN_bin2bn(&vchSig[1],32,sig->r);
8924 BN_bin2bn(&vchSig[33],32,sig->s);
8925
8926 EC_KEY_free(pkey);
8927 pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
8928 if (ECDSA_SIG_recover_key_GFp(pkey, sig, (unsigned char*)&hash, sizeof(hash), vchSig[0] - 27, 0) == 1)
8929 {
8930 fSet = true;
8931 ECDSA_SIG_free(sig);
8932 return true;
8933 }
8934 return false;
8935 }
8936
8937 bool Verify(uint256 hash, const std::vector<unsigned char>& vchSig)
8938 {
8939 // -1 = error, 0 = bad sig, 1 = good
8940 if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1)
8941 return false;
8942 return true;
8943 }
8944
8945 // Verify a compact signature
8946 bool VerifyCompact(uint256 hash, const std::vector<unsigned char>& vchSig)
8947 {
8948 CKey key;
8949 if (!key.SetCompactSignature(hash, vchSig))
8950 return false;
8951 if (GetPubKey() != key.GetPubKey())
8952 return false;
8953 return true;
8954 }
8955
8956 // Get the address corresponding to this key
8957 CBitcoinAddress GetAddress() const
8958 {
8959 return CBitcoinAddress(GetPubKey());
8960 }
8961
8962 bool IsValid()
8963 {
8964 if (!fSet)
8965 return false;
8966
8967 CSecret secret = GetSecret();
8968 CKey key2;
8969 key2.SetSecret(secret);
8970 return GetPubKey() == key2.GetPubKey();
8971 }
8972 };
8973
8974 #endif
-
+ 8E9AABB0569D092A6B1BFF5015211A38475530B28614A7163ADE52496314094BC00FD443EAFB66F1285EAA1C69A680233A3E6044058598D2E2CFFCF8797E0CC0
bitcoin/src/keystore.cpp
(0 . 0)(1 . 181)
8979 // Copyright (c) 2009-2010 Satoshi Nakamoto
8980 // Copyright (c) 2011 The Bitcoin developers
8981 // Distributed under the MIT/X11 software license, see the accompanying
8982 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
8983
8984 #include "headers.h"
8985 #include "db.h"
8986 #include "crypter.h"
8987
8988 std::vector<unsigned char> CKeyStore::GenerateNewKey()
8989 {
8990 RandAddSeedPerfmon();
8991 CKey key;
8992 key.MakeNewKey();
8993 if (!AddKey(key))
8994 throw std::runtime_error("CKeyStore::GenerateNewKey() : AddKey failed");
8995 return key.GetPubKey();
8996 }
8997
8998 bool CKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char> &vchPubKeyOut) const
8999 {
9000 CKey key;
9001 if (!GetKey(address, key))
9002 return false;
9003 vchPubKeyOut = key.GetPubKey();
9004 return true;
9005 }
9006
9007 bool CBasicKeyStore::AddKey(const CKey& key)
9008 {
9009 CRITICAL_BLOCK(cs_KeyStore)
9010 mapKeys[key.GetAddress()] = key.GetSecret();
9011 return true;
9012 }
9013
9014 bool CCryptoKeyStore::SetCrypted()
9015 {
9016 CRITICAL_BLOCK(cs_KeyStore)
9017 {
9018 if (fUseCrypto)
9019 return true;
9020 if (!mapKeys.empty())
9021 return false;
9022 fUseCrypto = true;
9023 }
9024 return true;
9025 }
9026
9027 std::vector<unsigned char> CCryptoKeyStore::GenerateNewKey()
9028 {
9029 RandAddSeedPerfmon();
9030 CKey key;
9031 key.MakeNewKey();
9032 if (!AddKey(key))
9033 throw std::runtime_error("CCryptoKeyStore::GenerateNewKey() : AddKey failed");
9034 return key.GetPubKey();
9035 }
9036
9037 bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
9038 {
9039 CRITICAL_BLOCK(cs_KeyStore)
9040 {
9041 if (!SetCrypted())
9042 return false;
9043
9044 CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
9045 for (; mi != mapCryptedKeys.end(); ++mi)
9046 {
9047 const std::vector<unsigned char> &vchPubKey = (*mi).second.first;
9048 const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
9049 CSecret vchSecret;
9050 if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret, Hash(vchPubKey.begin(), vchPubKey.end()), vchSecret))
9051 return false;
9052 CKey key;
9053 key.SetSecret(vchSecret);
9054 if (key.GetPubKey() == vchPubKey)
9055 break;
9056 return false;
9057 }
9058 vMasterKey = vMasterKeyIn;
9059 }
9060 return true;
9061 }
9062
9063 bool CCryptoKeyStore::AddKey(const CKey& key)
9064 {
9065 CRITICAL_BLOCK(cs_KeyStore)
9066 {
9067 if (!IsCrypted())
9068 return CBasicKeyStore::AddKey(key);
9069
9070 if (IsLocked())
9071 return false;
9072
9073 std::vector<unsigned char> vchCryptedSecret;
9074 std::vector<unsigned char> vchPubKey = key.GetPubKey();
9075 if (!EncryptSecret(vMasterKey, key.GetSecret(), Hash(vchPubKey.begin(), vchPubKey.end()), vchCryptedSecret))
9076 return false;
9077
9078 if (!AddCryptedKey(key.GetPubKey(), vchCryptedSecret))
9079 return false;
9080 }
9081 return true;
9082 }
9083
9084
9085 bool CCryptoKeyStore::AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
9086 {
9087 CRITICAL_BLOCK(cs_KeyStore)
9088 {
9089 if (!SetCrypted())
9090 return false;
9091
9092 mapCryptedKeys[CBitcoinAddress(vchPubKey)] = make_pair(vchPubKey, vchCryptedSecret);
9093 }
9094 return true;
9095 }
9096
9097 bool CCryptoKeyStore::GetKey(const CBitcoinAddress &address, CKey& keyOut) const
9098 {
9099 CRITICAL_BLOCK(cs_KeyStore)
9100 {
9101 if (!IsCrypted())
9102 return CBasicKeyStore::GetKey(address, keyOut);
9103
9104 CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
9105 if (mi != mapCryptedKeys.end())
9106 {
9107 const std::vector<unsigned char> &vchPubKey = (*mi).second.first;
9108 const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
9109 CSecret vchSecret;
9110 if (!DecryptSecret(vMasterKey, vchCryptedSecret, Hash(vchPubKey.begin(), vchPubKey.end()), vchSecret))
9111 return false;
9112 keyOut.SetSecret(vchSecret);
9113 return true;
9114 }
9115 }
9116 return false;
9117 }
9118
9119 bool CCryptoKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const
9120 {
9121 CRITICAL_BLOCK(cs_KeyStore)
9122 {
9123 if (!IsCrypted())
9124 return CKeyStore::GetPubKey(address, vchPubKeyOut);
9125
9126 CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
9127 if (mi != mapCryptedKeys.end())
9128 {
9129 vchPubKeyOut = (*mi).second.first;
9130 return true;
9131 }
9132 }
9133 return false;
9134 }
9135
9136 bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn)
9137 {
9138 CRITICAL_BLOCK(cs_KeyStore)
9139 {
9140 if (!mapCryptedKeys.empty() || IsCrypted())
9141 return false;
9142
9143 fUseCrypto = true;
9144 CKey key;
9145 BOOST_FOREACH(KeyMap::value_type& mKey, mapKeys)
9146 {
9147 if (!key.SetSecret(mKey.second))
9148 return false;
9149 const std::vector<unsigned char> vchPubKey = key.GetPubKey();
9150 std::vector<unsigned char> vchCryptedSecret;
9151 if (!EncryptSecret(vMasterKeyIn, key.GetSecret(), Hash(vchPubKey.begin(), vchPubKey.end()), vchCryptedSecret))
9152 return false;
9153 if (!AddCryptedKey(vchPubKey, vchCryptedSecret))
9154 return false;
9155 }
9156 mapKeys.clear();
9157 }
9158 return true;
9159 }
-
+ 5E302C824B6802E5AC88277F9DCCA66B645A2E6932713EF817B6E3352CEF123BB4492FDB19ACAE7236A090715770D9D623C209218BCD2745C1277D3172EF30D5
bitcoin/src/keystore.h
(0 . 0)(1 . 138)
9164 // Copyright (c) 2009-2010 Satoshi Nakamoto
9165 // Copyright (c) 2011 The Bitcoin developers
9166 // Distributed under the MIT/X11 software license, see the accompanying
9167 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
9168 #ifndef BITCOIN_KEYSTORE_H
9169 #define BITCOIN_KEYSTORE_H
9170
9171 #include "crypter.h"
9172
9173 // A virtual base class for key stores
9174 class CKeyStore
9175 {
9176 protected:
9177 mutable CCriticalSection cs_KeyStore;
9178
9179 public:
9180 // Add a key to the store.
9181 virtual bool AddKey(const CKey& key) =0;
9182
9183 // Check whether a key corresponding to a given address is present in the store.
9184 virtual bool HaveKey(const CBitcoinAddress &address) const =0;
9185
9186 // Retrieve a key corresponding to a given address from the store.
9187 // Return true if succesful.
9188 virtual bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const =0;
9189
9190 // Retrieve only the public key corresponding to a given address.
9191 // This may succeed even if GetKey fails (e.g., encrypted wallets)
9192 virtual bool GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const;
9193
9194 // Generate a new key, and add it to the store
9195 virtual std::vector<unsigned char> GenerateNewKey();
9196 };
9197
9198 typedef std::map<CBitcoinAddress, CSecret> KeyMap;
9199
9200 // Basic key store, that keeps keys in an address->secret map
9201 class CBasicKeyStore : public CKeyStore
9202 {
9203 protected:
9204 KeyMap mapKeys;
9205
9206 public:
9207 bool AddKey(const CKey& key);
9208 bool HaveKey(const CBitcoinAddress &address) const
9209 {
9210 bool result;
9211 CRITICAL_BLOCK(cs_KeyStore)
9212 result = (mapKeys.count(address) > 0);
9213 return result;
9214 }
9215 bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const
9216 {
9217 CRITICAL_BLOCK(cs_KeyStore)
9218 {
9219 KeyMap::const_iterator mi = mapKeys.find(address);
9220 if (mi != mapKeys.end())
9221 {
9222 keyOut.SetSecret((*mi).second);
9223 return true;
9224 }
9225 }
9226 return false;
9227 }
9228 };
9229
9230 typedef std::map<CBitcoinAddress, std::pair<std::vector<unsigned char>, std::vector<unsigned char> > > CryptedKeyMap;
9231
9232 // Keystore which keeps the private keys encrypted
9233 // It derives from the basic key store, which is used if no encryption is active.
9234 class CCryptoKeyStore : public CBasicKeyStore
9235 {
9236 private:
9237 CryptedKeyMap mapCryptedKeys;
9238
9239 CKeyingMaterial vMasterKey;
9240
9241 // if fUseCrypto is true, mapKeys must be empty
9242 // if fUseCrypto is false, vMasterKey must be empty
9243 bool fUseCrypto;
9244
9245 protected:
9246 bool SetCrypted();
9247
9248 // will encrypt previously unencrypted keys
9249 bool EncryptKeys(CKeyingMaterial& vMasterKeyIn);
9250
9251 bool Unlock(const CKeyingMaterial& vMasterKeyIn);
9252
9253 public:
9254 CCryptoKeyStore() : fUseCrypto(false)
9255 {
9256 }
9257
9258 bool IsCrypted() const
9259 {
9260 return fUseCrypto;
9261 }
9262
9263 bool IsLocked() const
9264 {
9265 if (!IsCrypted())
9266 return false;
9267 bool result;
9268 CRITICAL_BLOCK(cs_KeyStore)
9269 result = vMasterKey.empty();
9270 return result;
9271 }
9272
9273 bool Lock()
9274 {
9275 if (!SetCrypted())
9276 return false;
9277
9278 CRITICAL_BLOCK(cs_KeyStore)
9279 vMasterKey.clear();
9280
9281 return true;
9282 }
9283
9284 virtual bool AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
9285 std::vector<unsigned char> GenerateNewKey();
9286 bool AddKey(const CKey& key);
9287 bool HaveKey(const CBitcoinAddress &address) const
9288 {
9289 CRITICAL_BLOCK(cs_KeyStore)
9290 {
9291 if (!IsCrypted())
9292 return CBasicKeyStore::HaveKey(address);
9293 return mapCryptedKeys.count(address) > 0;
9294 }
9295 return false;
9296 }
9297 bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const;
9298 bool GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const;
9299 };
9300
9301 #endif
-
+ 7E326DCBF51E51C301521358CF2E684840D4FC5C977F0EA8476C3DEDD8E91E90548D8240608B76C1FD90F832EC11C1D3F57626948EEFC43F244DAF869475FE31
bitcoin/src/main.cpp
(0 . 0)(1 . 3250)
9306 // Copyright (c) 2009-2010 Satoshi Nakamoto
9307 // Copyright (c) 2009-2012 The Bitcoin developers
9308 // Distributed under the MIT/X11 software license, see the accompanying
9309 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
9310 #include "headers.h"
9311 #include "checkpoints.h"
9312 #include "db.h"
9313 #include "net.h"
9314 #include "init.h"
9315 #include <boost/filesystem.hpp>
9316 #include <boost/filesystem/fstream.hpp>
9317
9318 using namespace std;
9319 using namespace boost;
9320
9321 //
9322 // Global state
9323 //
9324
9325 CCriticalSection cs_setpwalletRegistered;
9326 set<CWallet*> setpwalletRegistered;
9327
9328 CCriticalSection cs_main;
9329
9330 static map<uint256, CTransaction> mapTransactions;
9331 CCriticalSection cs_mapTransactions;
9332 unsigned int nTransactionsUpdated = 0;
9333 map<COutPoint, CInPoint> mapNextTx;
9334
9335 map<uint256, CBlockIndex*> mapBlockIndex;
9336 uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f");
9337 static CBigNum bnProofOfWorkLimit(~uint256(0) >> 32);
9338 CBlockIndex* pindexGenesisBlock = NULL;
9339 int nBestHeight = -1;
9340 CBigNum bnBestChainWork = 0;
9341 CBigNum bnBestInvalidWork = 0;
9342 uint256 hashBestChain = 0;
9343 CBlockIndex* pindexBest = NULL;
9344 int64 nTimeBestReceived = 0;
9345
9346 CMedianFilter<int> cPeerBlockCounts(5, 0); // Amount of blocks that other nodes claim to have
9347
9348 map<uint256, CBlock*> mapOrphanBlocks;
9349 multimap<uint256, CBlock*> mapOrphanBlocksByPrev;
9350
9351 map<uint256, CDataStream*> mapOrphanTransactions;
9352 multimap<uint256, CDataStream*> mapOrphanTransactionsByPrev;
9353
9354
9355 double dHashesPerSec;
9356 int64 nHPSTimerStart;
9357
9358 // Settings
9359 int fGenerateBitcoins = false;
9360 int64 nTransactionFee = 0;
9361 int fLimitProcessors = false;
9362 int nLimitProcessors = 1;
9363 int fMinimizeToTray = true;
9364 int fMinimizeOnClose = true;
9365 #if USE_UPNP
9366 int fUseUPnP = true;
9367 #else
9368 int fUseUPnP = false;
9369 #endif
9370
9371
9372 //////////////////////////////////////////////////////////////////////////////
9373 //
9374 // dispatching functions
9375 //
9376
9377 // These functions dispatch to one or all registered wallets
9378
9379
9380 void RegisterWallet(CWallet* pwalletIn)
9381 {
9382 CRITICAL_BLOCK(cs_setpwalletRegistered)
9383 {
9384 setpwalletRegistered.insert(pwalletIn);
9385 }
9386 }
9387
9388 void UnregisterWallet(CWallet* pwalletIn)
9389 {
9390 CRITICAL_BLOCK(cs_setpwalletRegistered)
9391 {
9392 setpwalletRegistered.erase(pwalletIn);
9393 }
9394 }
9395
9396 // check whether the passed transaction is from us
9397 bool static IsFromMe(CTransaction& tx)
9398 {
9399 BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
9400 if (pwallet->IsFromMe(tx))
9401 return true;
9402 return false;
9403 }
9404
9405 // get the wallet transaction with the given hash (if it exists)
9406 bool static GetTransaction(const uint256& hashTx, CWalletTx& wtx)
9407 {
9408 BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
9409 if (pwallet->GetTransaction(hashTx,wtx))
9410 return true;
9411 return false;
9412 }
9413
9414 // erases transaction with the given hash from all wallets
9415 void static EraseFromWallets(uint256 hash)
9416 {
9417 BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
9418 pwallet->EraseFromWallet(hash);
9419 }
9420
9421 // make sure all wallets know about the given transaction, in the given block
9422 void static SyncWithWallets(const CTransaction& tx, const CBlock* pblock = NULL, bool fUpdate = false)
9423 {
9424 BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
9425 pwallet->AddToWalletIfInvolvingMe(tx, pblock, fUpdate);
9426 }
9427
9428 // notify wallets about a new best chain
9429 void static SetBestChain(const CBlockLocator& loc)
9430 {
9431 BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
9432 pwallet->SetBestChain(loc);
9433 }
9434
9435 // notify wallets about an updated transaction
9436 void static UpdatedTransaction(const uint256& hashTx)
9437 {
9438 BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
9439 pwallet->UpdatedTransaction(hashTx);
9440 }
9441
9442 // dump all wallets
9443 void static PrintWallets(const CBlock& block)
9444 {
9445 BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
9446 pwallet->PrintWallet(block);
9447 }
9448
9449 // notify wallets about an incoming inventory (for request counts)
9450 void static Inventory(const uint256& hash)
9451 {
9452 BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
9453 pwallet->Inventory(hash);
9454 }
9455
9456 // ask wallets to resend their transactions
9457 void static ResendWalletTransactions()
9458 {
9459 BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
9460 pwallet->ResendWalletTransactions();
9461 }
9462
9463
9464
9465
9466
9467
9468
9469 //////////////////////////////////////////////////////////////////////////////
9470 //
9471 // mapOrphanTransactions
9472 //
9473
9474 void AddOrphanTx(const CDataStream& vMsg)
9475 {
9476 CTransaction tx;
9477 CDataStream(vMsg) >> tx;
9478 uint256 hash = tx.GetHash();
9479 if (mapOrphanTransactions.count(hash))
9480 return;
9481
9482 CDataStream* pvMsg = mapOrphanTransactions[hash] = new CDataStream(vMsg);
9483 BOOST_FOREACH(const CTxIn& txin, tx.vin)
9484 mapOrphanTransactionsByPrev.insert(make_pair(txin.prevout.hash, pvMsg));
9485 }
9486
9487 void static EraseOrphanTx(uint256 hash)
9488 {
9489 if (!mapOrphanTransactions.count(hash))
9490 return;
9491 const CDataStream* pvMsg = mapOrphanTransactions[hash];
9492 CTransaction tx;
9493 CDataStream(*pvMsg) >> tx;
9494 BOOST_FOREACH(const CTxIn& txin, tx.vin)
9495 {
9496 for (multimap<uint256, CDataStream*>::iterator mi = mapOrphanTransactionsByPrev.lower_bound(txin.prevout.hash);
9497 mi != mapOrphanTransactionsByPrev.upper_bound(txin.prevout.hash);)
9498 {
9499 if ((*mi).second == pvMsg)
9500 mapOrphanTransactionsByPrev.erase(mi++);
9501 else
9502 mi++;
9503 }
9504 }
9505 delete pvMsg;
9506 mapOrphanTransactions.erase(hash);
9507 }
9508
9509 int LimitOrphanTxSize(int nMaxOrphans)
9510 {
9511 int nEvicted = 0;
9512 while (mapOrphanTransactions.size() > nMaxOrphans)
9513 {
9514 // Evict a random orphan:
9515 std::vector<unsigned char> randbytes(32);
9516 RAND_bytes(&randbytes[0], 32);
9517 uint256 randomhash(randbytes);
9518 map<uint256, CDataStream*>::iterator it = mapOrphanTransactions.lower_bound(randomhash);
9519 if (it == mapOrphanTransactions.end())
9520 it = mapOrphanTransactions.begin();
9521 EraseOrphanTx(it->first);
9522 ++nEvicted;
9523 }
9524 return nEvicted;
9525 }
9526
9527
9528
9529
9530
9531
9532
9533 //////////////////////////////////////////////////////////////////////////////
9534 //
9535 // CTransaction and CTxIndex
9536 //
9537
9538 bool CTransaction::ReadFromDisk(CTxDB& txdb, COutPoint prevout, CTxIndex& txindexRet)
9539 {
9540 SetNull();
9541 if (!txdb.ReadTxIndex(prevout.hash, txindexRet))
9542 return false;
9543 if (!ReadFromDisk(txindexRet.pos))
9544 return false;
9545 if (prevout.n >= vout.size())
9546 {
9547 SetNull();
9548 return false;
9549 }
9550 return true;
9551 }
9552
9553 bool CTransaction::ReadFromDisk(CTxDB& txdb, COutPoint prevout)
9554 {
9555 CTxIndex txindex;
9556 return ReadFromDisk(txdb, prevout, txindex);
9557 }
9558
9559 bool CTransaction::ReadFromDisk(COutPoint prevout)
9560 {
9561 CTxDB txdb("r");
9562 CTxIndex txindex;
9563 return ReadFromDisk(txdb, prevout, txindex);
9564 }
9565
9566
9567
9568 int CMerkleTx::SetMerkleBranch(const CBlock* pblock)
9569 {
9570 if (fClient)
9571 {
9572 if (hashBlock == 0)
9573 return 0;
9574 }
9575 else
9576 {
9577 CBlock blockTmp;
9578 if (pblock == NULL)
9579 {
9580 // Load the block this tx is in
9581 CTxIndex txindex;
9582 if (!CTxDB("r").ReadTxIndex(GetHash(), txindex))
9583 return 0;
9584 if (!blockTmp.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos))
9585 return 0;
9586 pblock = &blockTmp;
9587 }
9588
9589 // Update the tx's hashBlock
9590 hashBlock = pblock->GetHash();
9591
9592 // Locate the transaction
9593 for (nIndex = 0; nIndex < pblock->vtx.size(); nIndex++)
9594 if (pblock->vtx[nIndex] == *(CTransaction*)this)
9595 break;
9596 if (nIndex == pblock->vtx.size())
9597 {
9598 vMerkleBranch.clear();
9599 nIndex = -1;
9600 printf("ERROR: SetMerkleBranch() : couldn't find tx in block\n");
9601 return 0;
9602 }
9603
9604 // Fill in merkle branch
9605 vMerkleBranch = pblock->GetMerkleBranch(nIndex);
9606 }
9607
9608 // Is the tx in a block that's in the main chain
9609 map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
9610 if (mi == mapBlockIndex.end())
9611 return 0;
9612 CBlockIndex* pindex = (*mi).second;
9613 if (!pindex || !pindex->IsInMainChain())
9614 return 0;
9615
9616 return pindexBest->nHeight - pindex->nHeight + 1;
9617 }
9618
9619
9620
9621
9622
9623
9624
9625 bool CTransaction::CheckTransaction() const
9626 {
9627 // Basic checks that don't depend on any context
9628 if (vin.empty())
9629 return DoS(10, error("CTransaction::CheckTransaction() : vin empty"));
9630 if (vout.empty())
9631 return DoS(10, error("CTransaction::CheckTransaction() : vout empty"));
9632 // Size limits
9633 if (::GetSerializeSize(*this, SER_NETWORK) > MAX_BLOCK_SIZE)
9634 return DoS(100, error("CTransaction::CheckTransaction() : size limits failed"));
9635
9636 // Check for negative or overflow output values
9637 int64 nValueOut = 0;
9638 BOOST_FOREACH(const CTxOut& txout, vout)
9639 {
9640 if (txout.nValue < 0)
9641 return DoS(100, error("CTransaction::CheckTransaction() : txout.nValue negative"));
9642 if (txout.nValue > MAX_MONEY)
9643 return DoS(100, error("CTransaction::CheckTransaction() : txout.nValue too high"));
9644 nValueOut += txout.nValue;
9645 if (!MoneyRange(nValueOut))
9646 return DoS(100, error("CTransaction::CheckTransaction() : txout total out of range"));
9647 }
9648
9649 // Check for duplicate inputs
9650 set<COutPoint> vInOutPoints;
9651 BOOST_FOREACH(const CTxIn& txin, vin)
9652 {
9653 if (vInOutPoints.count(txin.prevout))
9654 return false;
9655 vInOutPoints.insert(txin.prevout);
9656 }
9657
9658 if (IsCoinBase())
9659 {
9660 if (vin[0].scriptSig.size() < 2 || vin[0].scriptSig.size() > 100)
9661 return DoS(100, error("CTransaction::CheckTransaction() : coinbase script size"));
9662 }
9663 else
9664 {
9665 BOOST_FOREACH(const CTxIn& txin, vin)
9666 if (txin.prevout.IsNull())
9667 return DoS(10, error("CTransaction::CheckTransaction() : prevout is null"));
9668 }
9669
9670 return true;
9671 }
9672
9673 bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMissingInputs)
9674 {
9675 if (pfMissingInputs)
9676 *pfMissingInputs = false;
9677
9678 if (!CheckTransaction())
9679 return error("AcceptToMemoryPool() : CheckTransaction failed");
9680
9681 // Coinbase is only valid in a block, not as a loose transaction
9682 if (IsCoinBase())
9683 return DoS(100, error("AcceptToMemoryPool() : coinbase as individual tx"));
9684
9685 // To help v0.1.5 clients who would see it as a negative number
9686 if ((int64)nLockTime > INT_MAX)
9687 return error("AcceptToMemoryPool() : not accepting nLockTime beyond 2038 yet");
9688
9689 // Safety limits
9690 unsigned int nSize = ::GetSerializeSize(*this, SER_NETWORK);
9691 // Checking ECDSA signatures is a CPU bottleneck, so to avoid denial-of-service
9692 // attacks disallow transactions with more than one SigOp per 34 bytes.
9693 // 34 bytes because a TxOut is:
9694 // 20-byte address + 8 byte bitcoin amount + 5 bytes of ops + 1 byte script length
9695 if (GetSigOpCount() > nSize / 34 || nSize < 100)
9696 return error("AcceptToMemoryPool() : transaction with out-of-bounds SigOpCount");
9697
9698 // Rather not work on nonstandard transactions (unless -testnet)
9699 if (!fTestNet && !IsStandard())
9700 return error("AcceptToMemoryPool() : nonstandard transaction type");
9701
9702 // Do we already have it?
9703 uint256 hash = GetHash();
9704 CRITICAL_BLOCK(cs_mapTransactions)
9705 if (mapTransactions.count(hash))
9706 return false;
9707 if (fCheckInputs)
9708 if (txdb.ContainsTx(hash))
9709 return false;
9710
9711 // Check for conflicts with in-memory transactions
9712 CTransaction* ptxOld = NULL;
9713 for (int i = 0; i < vin.size(); i++)
9714 {
9715 COutPoint outpoint = vin[i].prevout;
9716 if (mapNextTx.count(outpoint))
9717 {
9718 // Disable replacement feature for now
9719 return false;
9720
9721 // Allow replacing with a newer version of the same transaction
9722 if (i != 0)
9723 return false;
9724 ptxOld = mapNextTx[outpoint].ptx;
9725 if (ptxOld->IsFinal())
9726 return false;
9727 if (!IsNewerThan(*ptxOld))
9728 return false;
9729 for (int i = 0; i < vin.size(); i++)
9730 {
9731 COutPoint outpoint = vin[i].prevout;
9732 if (!mapNextTx.count(outpoint) || mapNextTx[outpoint].ptx != ptxOld)
9733 return false;
9734 }
9735 break;
9736 }
9737 }
9738
9739 if (fCheckInputs)
9740 {
9741 // Check against previous transactions
9742 map<uint256, CTxIndex> mapUnused;
9743 int64 nFees = 0;
9744 bool fInvalid = false;
9745 if (!ConnectInputs(txdb, mapUnused, CDiskTxPos(1,1,1), pindexBest, nFees, false, false, 0, fInvalid))
9746 {
9747 if (fInvalid)
9748 return error("AcceptToMemoryPool() : FetchInputs found invalid tx %s", hash.ToString().substr(0,10).c_str());
9749 return error("AcceptToMemoryPool() : ConnectInputs failed %s", hash.ToString().substr(0,10).c_str());
9750 }
9751
9752 // Don't accept it if it can't get into a block
9753 if (nFees < GetMinFee(1000, true, true))
9754 return error("AcceptToMemoryPool() : not enough fees");
9755
9756 // Continuously rate-limit free transactions
9757 // This mitigates 'penny-flooding' -- sending thousands of free transactions just to
9758 // be annoying or make other's transactions take longer to confirm.
9759 if (nFees < MIN_RELAY_TX_FEE)
9760 {
9761 static CCriticalSection cs;
9762 static double dFreeCount;
9763 static int64 nLastTime;
9764 int64 nNow = GetTime();
9765
9766 CRITICAL_BLOCK(cs)
9767 {
9768 // Use an exponentially decaying ~10-minute window:
9769 dFreeCount *= pow(1.0 - 1.0/600.0, (double)(nNow - nLastTime));
9770 nLastTime = nNow;
9771 // -limitfreerelay unit is thousand-bytes-per-minute
9772 // At default rate it would take over a month to fill 1GB
9773 if (dFreeCount > GetArg("-limitfreerelay", 15)*10*1000 && !IsFromMe(*this))
9774 return error("AcceptToMemoryPool() : free transaction rejected by rate limiter");
9775 if (fDebug)
9776 printf("Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize);
9777 dFreeCount += nSize;
9778 }
9779 }
9780 }
9781
9782 // Store transaction in memory
9783 CRITICAL_BLOCK(cs_mapTransactions)
9784 {
9785 if (ptxOld)
9786 {
9787 printf("AcceptToMemoryPool() : replacing tx %s with new version\n", ptxOld->GetHash().ToString().c_str());
9788 ptxOld->RemoveFromMemoryPool();
9789 }
9790 AddToMemoryPoolUnchecked();
9791 }
9792
9793 ///// are we sure this is ok when loading transactions or restoring block txes
9794 // If updated, erase old tx from wallet
9795 if (ptxOld)
9796 EraseFromWallets(ptxOld->GetHash());
9797
9798 printf("AcceptToMemoryPool(): accepted %s\n", hash.ToString().substr(0,10).c_str());
9799 return true;
9800 }
9801
9802 bool CTransaction::AcceptToMemoryPool(bool fCheckInputs, bool* pfMissingInputs)
9803 {
9804 CTxDB txdb("r");
9805 return AcceptToMemoryPool(txdb, fCheckInputs, pfMissingInputs);
9806 }
9807
9808 bool CTransaction::AddToMemoryPoolUnchecked()
9809 {
9810 // Add to memory pool without checking anything. Don't call this directly,
9811 // call AcceptToMemoryPool to properly check the transaction first.
9812 CRITICAL_BLOCK(cs_mapTransactions)
9813 {
9814 uint256 hash = GetHash();
9815 mapTransactions[hash] = *this;
9816 for (int i = 0; i < vin.size(); i++)
9817 mapNextTx[vin[i].prevout] = CInPoint(&mapTransactions[hash], i);
9818 nTransactionsUpdated++;
9819 }
9820 return true;
9821 }
9822
9823
9824 bool CTransaction::RemoveFromMemoryPool()
9825 {
9826 // Remove transaction from memory pool
9827 CRITICAL_BLOCK(cs_mapTransactions)
9828 {
9829 BOOST_FOREACH(const CTxIn& txin, vin)
9830 mapNextTx.erase(txin.prevout);
9831 mapTransactions.erase(GetHash());
9832 nTransactionsUpdated++;
9833 }
9834 return true;
9835 }
9836
9837
9838
9839
9840
9841
9842 int CMerkleTx::GetDepthInMainChain(int& nHeightRet) const
9843 {
9844 if (hashBlock == 0 || nIndex == -1)
9845 return 0;
9846
9847 // Find the block it claims to be in
9848 map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
9849 if (mi == mapBlockIndex.end())
9850 return 0;
9851 CBlockIndex* pindex = (*mi).second;
9852 if (!pindex || !pindex->IsInMainChain())
9853 return 0;
9854
9855 // Make sure the merkle branch connects to this block
9856 if (!fMerkleVerified)
9857 {
9858 if (CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex) != pindex->hashMerkleRoot)
9859 return 0;
9860 fMerkleVerified = true;
9861 }
9862
9863 nHeightRet = pindex->nHeight;
9864 return pindexBest->nHeight - pindex->nHeight + 1;
9865 }
9866
9867
9868 int CMerkleTx::GetBlocksToMaturity() const
9869 {
9870 if (!IsCoinBase())
9871 return 0;
9872 return max(0, (COINBASE_MATURITY+20) - GetDepthInMainChain());
9873 }
9874
9875
9876 bool CMerkleTx::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs)
9877 {
9878 if (fClient)
9879 {
9880 if (!IsInMainChain() && !ClientConnectInputs())
9881 return false;
9882 return CTransaction::AcceptToMemoryPool(txdb, false);
9883 }
9884 else
9885 {
9886 return CTransaction::AcceptToMemoryPool(txdb, fCheckInputs);
9887 }
9888 }
9889
9890 bool CMerkleTx::AcceptToMemoryPool()
9891 {
9892 CTxDB txdb("r");
9893 return AcceptToMemoryPool(txdb);
9894 }
9895
9896
9897
9898 bool CWalletTx::AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs)
9899 {
9900 CRITICAL_BLOCK(cs_mapTransactions)
9901 {
9902 // Add previous supporting transactions first
9903 BOOST_FOREACH(CMerkleTx& tx, vtxPrev)
9904 {
9905 if (!tx.IsCoinBase())
9906 {
9907 uint256 hash = tx.GetHash();
9908 if (!mapTransactions.count(hash) && !txdb.ContainsTx(hash))
9909 tx.AcceptToMemoryPool(txdb, fCheckInputs);
9910 }
9911 }
9912 return AcceptToMemoryPool(txdb, fCheckInputs);
9913 }
9914 return false;
9915 }
9916
9917 bool CWalletTx::AcceptWalletTransaction()
9918 {
9919 CTxDB txdb("r");
9920 return AcceptWalletTransaction(txdb);
9921 }
9922
9923 int CTxIndex::GetDepthInMainChain() const
9924 {
9925 // Read block header
9926 CBlock block;
9927 if (!block.ReadFromDisk(pos.nFile, pos.nBlockPos, false))
9928 return 0;
9929 // Find the block in the index
9930 map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(block.GetHash());
9931 if (mi == mapBlockIndex.end())
9932 return 0;
9933 CBlockIndex* pindex = (*mi).second;
9934 if (!pindex || !pindex->IsInMainChain())
9935 return 0;
9936 return 1 + nBestHeight - pindex->nHeight;
9937 }
9938
9939
9940
9941
9942
9943
9944
9945
9946
9947
9948 //////////////////////////////////////////////////////////////////////////////
9949 //
9950 // CBlock and CBlockIndex
9951 //
9952
9953 bool CBlock::ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions)
9954 {
9955 if (!fReadTransactions)
9956 {
9957 *this = pindex->GetBlockHeader();
9958 return true;
9959 }
9960 if (!ReadFromDisk(pindex->nFile, pindex->nBlockPos, fReadTransactions))
9961 return false;
9962 if (GetHash() != pindex->GetBlockHash())
9963 return error("CBlock::ReadFromDisk() : GetHash() doesn't match index");
9964 return true;
9965 }
9966
9967 uint256 static GetOrphanRoot(const CBlock* pblock)
9968 {
9969 // Work back to the first block in the orphan chain
9970 while (mapOrphanBlocks.count(pblock->hashPrevBlock))
9971 pblock = mapOrphanBlocks[pblock->hashPrevBlock];
9972 return pblock->GetHash();
9973 }
9974
9975 int64 static GetBlockValue(int nHeight, int64 nFees)
9976 {
9977 int64 nSubsidy = 50 * COIN;
9978
9979 // Subsidy is cut in half every 4 years
9980 nSubsidy >>= (nHeight / 210000);
9981
9982 return nSubsidy + nFees;
9983 }
9984
9985 static const int64 nTargetTimespan = 14 * 24 * 60 * 60; // two weeks
9986 static const int64 nTargetSpacing = 10 * 60;
9987 static const int64 nInterval = nTargetTimespan / nTargetSpacing;
9988
9989 //
9990 // minimum amount of work that could possibly be required nTime after
9991 // minimum work required was nBase
9992 //
9993 unsigned int ComputeMinWork(unsigned int nBase, int64 nTime)
9994 {
9995 // Testnet has min-difficulty blocks
9996 // after nTargetSpacing*2 time between blocks:
9997 if (fTestNet && nTime > nTargetSpacing*2)
9998 return bnProofOfWorkLimit.GetCompact();
9999
10000 CBigNum bnResult;
10001 bnResult.SetCompact(nBase);
10002 while (nTime > 0 && bnResult < bnProofOfWorkLimit)
10003 {
10004 // Maximum 400% adjustment...
10005 bnResult *= 4;
10006 // ... in best-case exactly 4-times-normal target time
10007 nTime -= nTargetTimespan*4;
10008 }
10009 if (bnResult > bnProofOfWorkLimit)
10010 bnResult = bnProofOfWorkLimit;
10011 return bnResult.GetCompact();
10012 }
10013
10014 unsigned int static GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlock *pblock)
10015 {
10016 unsigned int nProofOfWorkLimit = bnProofOfWorkLimit.GetCompact();
10017
10018 // Genesis block
10019 if (pindexLast == NULL)
10020 return nProofOfWorkLimit;
10021
10022 // Only change once per interval
10023 if ((pindexLast->nHeight+1) % nInterval != 0)
10024 {
10025 // Special rules for testnet after 15 Feb 2012:
10026 if (fTestNet && pblock->nTime > 1329264000)
10027 {
10028 // If the new block's timestamp is more than 2* 10 minutes
10029 // then allow mining of a min-difficulty block.
10030 if (pblock->nTime - pindexLast->nTime > nTargetSpacing*2)
10031 return nProofOfWorkLimit;
10032 else
10033 {
10034 // Return the last non-special-min-difficulty-rules-block
10035 const CBlockIndex* pindex = pindexLast;
10036 while (pindex->pprev && pindex->nHeight % nInterval != 0 && pindex->nBits == nProofOfWorkLimit)
10037 pindex = pindex->pprev;
10038 return pindex->nBits;
10039 }
10040 }
10041
10042 return pindexLast->nBits;
10043 }
10044
10045 // Go back by what we want to be 14 days worth of blocks
10046 const CBlockIndex* pindexFirst = pindexLast;
10047 for (int i = 0; pindexFirst && i < nInterval-1; i++)
10048 pindexFirst = pindexFirst->pprev;
10049 assert(pindexFirst);
10050
10051 // Limit adjustment step
10052 int64 nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime();
10053 printf(" nActualTimespan = %"PRI64d" before bounds\n", nActualTimespan);
10054 if (nActualTimespan < nTargetTimespan/4)
10055 nActualTimespan = nTargetTimespan/4;
10056 if (nActualTimespan > nTargetTimespan*4)
10057 nActualTimespan = nTargetTimespan*4;
10058
10059 // Retarget
10060 CBigNum bnNew;
10061 bnNew.SetCompact(pindexLast->nBits);
10062 bnNew *= nActualTimespan;
10063 bnNew /= nTargetTimespan;
10064
10065 if (bnNew > bnProofOfWorkLimit)
10066 bnNew = bnProofOfWorkLimit;
10067
10068 /// debug print
10069 printf("GetNextWorkRequired RETARGET\n");
10070 printf("nTargetTimespan = %"PRI64d" nActualTimespan = %"PRI64d"\n", nTargetTimespan, nActualTimespan);
10071 printf("Before: %08x %s\n", pindexLast->nBits, CBigNum().SetCompact(pindexLast->nBits).getuint256().ToString().c_str());
10072 printf("After: %08x %s\n", bnNew.GetCompact(), bnNew.getuint256().ToString().c_str());
10073
10074 return bnNew.GetCompact();
10075 }
10076
10077 bool CheckProofOfWork(uint256 hash, unsigned int nBits)
10078 {
10079 CBigNum bnTarget;
10080 bnTarget.SetCompact(nBits);
10081
10082 // Check range
10083 if (bnTarget <= 0 || bnTarget > bnProofOfWorkLimit)
10084 return error("CheckProofOfWork() : nBits below minimum work");
10085
10086 // Check proof of work matches claimed amount
10087 if (hash > bnTarget.getuint256())
10088 return error("CheckProofOfWork() : hash doesn't match nBits");
10089
10090 return true;
10091 }
10092
10093 // Return maximum amount of blocks that other nodes claim to have
10094 int GetNumBlocksOfPeers()
10095 {
10096 return std::max(cPeerBlockCounts.median(), Checkpoints::GetTotalBlocksEstimate());
10097 }
10098
10099 bool IsInitialBlockDownload()
10100 {
10101 if (pindexBest == NULL || nBestHeight < Checkpoints::GetTotalBlocksEstimate())
10102 return true;
10103 static int64 nLastUpdate;
10104 static CBlockIndex* pindexLastBest;
10105 if (pindexBest != pindexLastBest)
10106 {
10107 pindexLastBest = pindexBest;
10108 nLastUpdate = GetTime();
10109 }
10110 return (GetTime() - nLastUpdate < 10 &&
10111 pindexBest->GetBlockTime() < GetTime() - 24 * 60 * 60);
10112 }
10113
10114 void static InvalidChainFound(CBlockIndex* pindexNew)
10115 {
10116 if (pindexNew->bnChainWork > bnBestInvalidWork)
10117 {
10118 bnBestInvalidWork = pindexNew->bnChainWork;
10119 CTxDB().WriteBestInvalidWork(bnBestInvalidWork);
10120 MainFrameRepaint();
10121 }
10122 printf("InvalidChainFound: invalid block=%s height=%d work=%s\n", pindexNew->GetBlockHash().ToString().substr(0,20).c_str(), pindexNew->nHeight, pindexNew->bnChainWork.ToString().c_str());
10123 printf("InvalidChainFound: current best=%s height=%d work=%s\n", hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, bnBestChainWork.ToString().c_str());
10124 if (pindexBest && bnBestInvalidWork > bnBestChainWork + pindexBest->GetBlockWork() * 6)
10125 printf("InvalidChainFound: WARNING: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade.\n");
10126 }
10127
10128
10129
10130
10131
10132
10133
10134
10135
10136
10137
10138 bool CTransaction::DisconnectInputs(CTxDB& txdb)
10139 {
10140 // Relinquish previous transactions' spent pointers
10141 if (!IsCoinBase())
10142 {
10143 BOOST_FOREACH(const CTxIn& txin, vin)
10144 {
10145 COutPoint prevout = txin.prevout;
10146
10147 // Get prev txindex from disk
10148 CTxIndex txindex;
10149 if (!txdb.ReadTxIndex(prevout.hash, txindex))
10150 return error("DisconnectInputs() : ReadTxIndex failed");
10151
10152 if (prevout.n >= txindex.vSpent.size())
10153 return error("DisconnectInputs() : prevout.n out of range");
10154
10155 // Mark outpoint as not spent
10156 txindex.vSpent[prevout.n].SetNull();
10157
10158 // Write back
10159 if (!txdb.UpdateTxIndex(prevout.hash, txindex))
10160 return error("DisconnectInputs() : UpdateTxIndex failed");
10161 }
10162 }
10163
10164 // Remove transaction from index
10165 // This can fail if a duplicate of this transaction was in a chain that got
10166 // reorganized away. This is only possible if this transaction was completely
10167 // spent, so erasing it would be a no-op anway.
10168 txdb.EraseTxIndex(*this);
10169
10170 return true;
10171 }
10172
10173
10174 bool CTransaction::ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPool, CDiskTxPos posThisTx,
10175 CBlockIndex* pindexBlock, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee,
10176 bool& fInvalid)
10177 {
10178 // FetchInputs can return false either because we just haven't seen some inputs
10179 // (in which case the transaction should be stored as an orphan)
10180 // or because the transaction is malformed (in which case the transaction should
10181 // be dropped). If tx is definitely invalid, fInvalid will be set to true.
10182 fInvalid = false;
10183
10184 // Take over previous transactions' spent pointers
10185 // fBlock is true when this is called from AcceptBlock when a new best-block is added to the blockchain
10186 // fMiner is true when called from the internal bitcoin miner
10187 // ... both are false when called from CTransaction::AcceptToMemoryPool
10188 if (!IsCoinBase())
10189 {
10190 int64 nValueIn = 0;
10191 for (int i = 0; i < vin.size(); i++)
10192 {
10193 COutPoint prevout = vin[i].prevout;
10194
10195 // Read txindex
10196 CTxIndex txindex;
10197 bool fFound = true;
10198 if ((fBlock || fMiner) && mapTestPool.count(prevout.hash))
10199 {
10200 // Get txindex from current proposed changes
10201 txindex = mapTestPool[prevout.hash];
10202 }
10203 else
10204 {
10205 // Read txindex from txdb
10206 fFound = txdb.ReadTxIndex(prevout.hash, txindex);
10207 }
10208 if (!fFound && (fBlock || fMiner))
10209 return fMiner ? false : error("ConnectInputs() : %s prev tx %s index entry not found", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str());
10210
10211 // Read txPrev
10212 CTransaction txPrev;
10213 if (!fFound || txindex.pos == CDiskTxPos(1,1,1))
10214 {
10215 // Get prev tx from single transactions in memory
10216 CRITICAL_BLOCK(cs_mapTransactions)
10217 {
10218 if (!mapTransactions.count(prevout.hash))
10219 return error("ConnectInputs() : %s mapTransactions prev not found %s", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str());
10220 txPrev = mapTransactions[prevout.hash];
10221 }
10222 if (!fFound)
10223 txindex.vSpent.resize(txPrev.vout.size());
10224 }
10225 else
10226 {
10227 // Get prev tx from disk
10228 if (!txPrev.ReadFromDisk(txindex.pos))
10229 return error("ConnectInputs() : %s ReadFromDisk prev tx %s failed", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str());
10230 }
10231
10232 if (prevout.n >= txPrev.vout.size() || prevout.n >= txindex.vSpent.size())
10233 {
10234 // Revisit this if/when transaction replacement is implemented and allows
10235 // adding inputs:
10236 fInvalid = true;
10237 return DoS(100, error("ConnectInputs() : %s prevout.n out of range %d %d %d prev tx %s\n%s", GetHash().ToString().substr(0,10).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size(), prevout.hash.ToString().substr(0,10).c_str(), txPrev.ToString().c_str()));
10238 }
10239
10240 // If prev is coinbase, check that it's matured
10241 if (txPrev.IsCoinBase())
10242 for (CBlockIndex* pindex = pindexBlock; pindex && pindexBlock->nHeight - pindex->nHeight < COINBASE_MATURITY; pindex = pindex->pprev)
10243 if (pindex->nBlockPos == txindex.pos.nBlockPos && pindex->nFile == txindex.pos.nFile)
10244 return error("ConnectInputs() : tried to spend coinbase at depth %d", pindexBlock->nHeight - pindex->nHeight);
10245
10246 // Skip ECDSA signature verification when connecting blocks (fBlock=true)
10247 // before the last blockchain checkpoint. This is safe because block merkle hashes are
10248 // still computed and checked, and any change will be caught at the next checkpoint.
10249 if (!(fBlock && (nBestHeight < Checkpoints::GetTotalBlocksEstimate())))
10250 // Verify signature
10251 if (!VerifySignature(txPrev, *this, i))
10252 return DoS(100,error("ConnectInputs() : %s VerifySignature failed", GetHash().ToString().substr(0,10).c_str()));
10253
10254 // Check for conflicts (double-spend)
10255 // This doesn't trigger the DoS code on purpose; if it did, it would make it easier
10256 // for an attacker to attempt to split the network.
10257 if (!txindex.vSpent[prevout.n].IsNull())
10258 return fMiner ? false : error("ConnectInputs() : %s prev tx already used at %s", GetHash().ToString().substr(0,10).c_str(), txindex.vSpent[prevout.n].ToString().c_str());
10259
10260 // Check for negative or overflow input values
10261 nValueIn += txPrev.vout[prevout.n].nValue;
10262 if (!MoneyRange(txPrev.vout[prevout.n].nValue) || !MoneyRange(nValueIn))
10263 return DoS(100, error("ConnectInputs() : txin values out of range"));
10264
10265 // Mark outpoints as spent
10266 txindex.vSpent[prevout.n] = posThisTx;
10267
10268 // Write back
10269 if (fBlock || fMiner)
10270 {
10271 mapTestPool[prevout.hash] = txindex;
10272 }
10273 }
10274
10275 if (nValueIn < GetValueOut())
10276 return DoS(100, error("ConnectInputs() : %s value in < value out", GetHash().ToString().substr(0,10).c_str()));
10277
10278 // Tally transaction fees
10279 int64 nTxFee = nValueIn - GetValueOut();
10280 if (nTxFee < 0)
10281 return DoS(100, error("ConnectInputs() : %s nTxFee < 0", GetHash().ToString().substr(0,10).c_str()));
10282 if (nTxFee < nMinFee)
10283 return false;
10284 nFees += nTxFee;
10285 if (!MoneyRange(nFees))
10286 return DoS(100, error("ConnectInputs() : nFees out of range"));
10287 }
10288
10289 if (fBlock)
10290 {
10291 // Add transaction to changes
10292 mapTestPool[GetHash()] = CTxIndex(posThisTx, vout.size());
10293 }
10294 else if (fMiner)
10295 {
10296 // Add transaction to test pool
10297 mapTestPool[GetHash()] = CTxIndex(CDiskTxPos(1,1,1), vout.size());
10298 }
10299
10300 return true;
10301 }
10302
10303
10304 bool CTransaction::ClientConnectInputs()
10305 {
10306 if (IsCoinBase())
10307 return false;
10308
10309 // Take over previous transactions' spent pointers
10310 CRITICAL_BLOCK(cs_mapTransactions)
10311 {
10312 int64 nValueIn = 0;
10313 for (int i = 0; i < vin.size(); i++)
10314 {
10315 // Get prev tx from single transactions in memory
10316 COutPoint prevout = vin[i].prevout;
10317 if (!mapTransactions.count(prevout.hash))
10318 return false;
10319 CTransaction& txPrev = mapTransactions[prevout.hash];
10320
10321 if (prevout.n >= txPrev.vout.size())
10322 return false;
10323
10324 // Verify signature
10325 if (!VerifySignature(txPrev, *this, i))
10326 return error("ConnectInputs() : VerifySignature failed");
10327
10328 ///// this is redundant with the mapNextTx stuff, not sure which I want to get rid of
10329 ///// this has to go away now that posNext is gone
10330 // // Check for conflicts
10331 // if (!txPrev.vout[prevout.n].posNext.IsNull())
10332 // return error("ConnectInputs() : prev tx already used");
10333 //
10334 // // Flag outpoints as used
10335 // txPrev.vout[prevout.n].posNext = posThisTx;
10336
10337 nValueIn += txPrev.vout[prevout.n].nValue;
10338
10339 if (!MoneyRange(txPrev.vout[prevout.n].nValue) || !MoneyRange(nValueIn))
10340 return error("ClientConnectInputs() : txin values out of range");
10341 }
10342 if (GetValueOut() > nValueIn)
10343 return false;
10344 }
10345
10346 return true;
10347 }
10348
10349
10350
10351
10352 bool CBlock::DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex)
10353 {
10354 // Disconnect in reverse order
10355 for (int i = vtx.size()-1; i >= 0; i--)
10356 if (!vtx[i].DisconnectInputs(txdb))
10357 return false;
10358
10359 // Update block index on disk without changing it in memory.
10360 // The memory index structure will be changed after the db commits.
10361 if (pindex->pprev)
10362 {
10363 CDiskBlockIndex blockindexPrev(pindex->pprev);
10364 blockindexPrev.hashNext = 0;
10365 if (!txdb.WriteBlockIndex(blockindexPrev))
10366 return error("DisconnectBlock() : WriteBlockIndex failed");
10367 }
10368
10369 return true;
10370 }
10371
10372 bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex)
10373 {
10374 // Check it again in case a previous version let a bad block in
10375 if (!CheckBlock())
10376 return false;
10377
10378 // Do not allow blocks that contain transactions which 'overwrite' older transactions,
10379 // unless those are already completely spent.
10380 // If such overwrites are allowed, coinbases and transactions depending upon those
10381 // can be duplicated to remove the ability to spend the first instance -- even after
10382 // being sent to another address.
10383 // See BIP30 and http://r6.ca/blog/20120206T005236Z.html for more information.
10384 // This logic is not necessary for memory pool transactions, as AcceptToMemoryPool
10385 // already refuses previously-known transaction id's entirely.
10386 // This rule applies to all blocks whose timestamp is after March 15, 2012, 0:00 UTC.
10387 // On testnet it is enabled as of februari 20, 2012, 0:00 UTC.
10388 if (pindex->nTime > 1331769600 || (fTestNet && pindex->nTime > 1329696000))
10389 BOOST_FOREACH(CTransaction& tx, vtx)
10390 {
10391 CTxIndex txindexOld;
10392 if (txdb.ReadTxIndex(tx.GetHash(), txindexOld))
10393 BOOST_FOREACH(CDiskTxPos &pos, txindexOld.vSpent)
10394 if (pos.IsNull())
10395 return false;
10396 }
10397
10398 //// issue here: it doesn't know the version
10399 unsigned int nTxPos = pindex->nBlockPos + ::GetSerializeSize(CBlock(), SER_DISK) - 1 + GetSizeOfCompactSize(vtx.size());
10400
10401 map<uint256, CTxIndex> mapQueuedChanges;
10402 int64 nFees = 0;
10403 BOOST_FOREACH(CTransaction& tx, vtx)
10404 {
10405 CDiskTxPos posThisTx(pindex->nFile, pindex->nBlockPos, nTxPos);
10406 nTxPos += ::GetSerializeSize(tx, SER_DISK);
10407
10408 bool fInvalid;
10409 if (!tx.ConnectInputs(txdb, mapQueuedChanges, posThisTx, pindex, nFees, true, false, 0, fInvalid))
10410 return false;
10411 }
10412 // Write queued txindex changes
10413 for (map<uint256, CTxIndex>::iterator mi = mapQueuedChanges.begin(); mi != mapQueuedChanges.end(); ++mi)
10414 {
10415 if (!txdb.UpdateTxIndex((*mi).first, (*mi).second))
10416 return error("ConnectBlock() : UpdateTxIndex failed");
10417 }
10418
10419 if (vtx[0].GetValueOut() > GetBlockValue(pindex->nHeight, nFees))
10420 return false;
10421
10422 // Update block index on disk without changing it in memory.
10423 // The memory index structure will be changed after the db commits.
10424 if (pindex->pprev)
10425 {
10426 CDiskBlockIndex blockindexPrev(pindex->pprev);
10427 blockindexPrev.hashNext = pindex->GetBlockHash();
10428 if (!txdb.WriteBlockIndex(blockindexPrev))
10429 return error("ConnectBlock() : WriteBlockIndex failed");
10430 }
10431
10432 // Watch for transactions paying to me
10433 BOOST_FOREACH(CTransaction& tx, vtx)
10434 SyncWithWallets(tx, this, true);
10435
10436 return true;
10437 }
10438
10439 bool static Reorganize(CTxDB& txdb, CBlockIndex* pindexNew)
10440 {
10441 printf("REORGANIZE\n");
10442
10443 // Find the fork
10444 CBlockIndex* pfork = pindexBest;
10445 CBlockIndex* plonger = pindexNew;
10446 while (pfork != plonger)
10447 {
10448 while (plonger->nHeight > pfork->nHeight)
10449 if (!(plonger = plonger->pprev))
10450 return error("Reorganize() : plonger->pprev is null");
10451 if (pfork == plonger)
10452 break;
10453 if (!(pfork = pfork->pprev))
10454 return error("Reorganize() : pfork->pprev is null");
10455 }
10456
10457 // List of what to disconnect
10458 vector<CBlockIndex*> vDisconnect;
10459 for (CBlockIndex* pindex = pindexBest; pindex != pfork; pindex = pindex->pprev)
10460 vDisconnect.push_back(pindex);
10461
10462 // List of what to connect
10463 vector<CBlockIndex*> vConnect;
10464 for (CBlockIndex* pindex = pindexNew; pindex != pfork; pindex = pindex->pprev)
10465 vConnect.push_back(pindex);
10466 reverse(vConnect.begin(), vConnect.end());
10467
10468 // Disconnect shorter branch
10469 vector<CTransaction> vResurrect;
10470 BOOST_FOREACH(CBlockIndex* pindex, vDisconnect)
10471 {
10472 CBlock block;
10473 if (!block.ReadFromDisk(pindex))
10474 return error("Reorganize() : ReadFromDisk for disconnect failed");
10475 if (!block.DisconnectBlock(txdb, pindex))
10476 return error("Reorganize() : DisconnectBlock failed");
10477
10478 // Queue memory transactions to resurrect
10479 BOOST_FOREACH(const CTransaction& tx, block.vtx)
10480 if (!tx.IsCoinBase())
10481 vResurrect.push_back(tx);
10482 }
10483
10484 // Connect longer branch
10485 vector<CTransaction> vDelete;
10486 for (int i = 0; i < vConnect.size(); i++)
10487 {
10488 CBlockIndex* pindex = vConnect[i];
10489 CBlock block;
10490 if (!block.ReadFromDisk(pindex))
10491 return error("Reorganize() : ReadFromDisk for connect failed");
10492 if (!block.ConnectBlock(txdb, pindex))
10493 {
10494 // Invalid block
10495 txdb.TxnAbort();
10496 return error("Reorganize() : ConnectBlock failed");
10497 }
10498
10499 // Queue memory transactions to delete
10500 BOOST_FOREACH(const CTransaction& tx, block.vtx)
10501 vDelete.push_back(tx);
10502 }
10503 if (!txdb.WriteHashBestChain(pindexNew->GetBlockHash()))
10504 return error("Reorganize() : WriteHashBestChain failed");
10505
10506 // Make sure it's successfully written to disk before changing memory structure
10507 if (!txdb.TxnCommit())
10508 return error("Reorganize() : TxnCommit failed");
10509
10510 // Disconnect shorter branch
10511 BOOST_FOREACH(CBlockIndex* pindex, vDisconnect)
10512 if (pindex->pprev)
10513 pindex->pprev->pnext = NULL;
10514
10515 // Connect longer branch
10516 BOOST_FOREACH(CBlockIndex* pindex, vConnect)
10517 if (pindex->pprev)
10518 pindex->pprev->pnext = pindex;
10519
10520 // Resurrect memory transactions that were in the disconnected branch
10521 BOOST_FOREACH(CTransaction& tx, vResurrect)
10522 tx.AcceptToMemoryPool(txdb, false);
10523
10524 // Delete redundant memory transactions that are in the connected branch
10525 BOOST_FOREACH(CTransaction& tx, vDelete)
10526 tx.RemoveFromMemoryPool();
10527
10528 return true;
10529 }
10530
10531
10532 bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew)
10533 {
10534 uint256 hash = GetHash();
10535
10536 txdb.TxnBegin();
10537 if (pindexGenesisBlock == NULL && hash == hashGenesisBlock)
10538 {
10539 txdb.WriteHashBestChain(hash);
10540 if (!txdb.TxnCommit())
10541 return error("SetBestChain() : TxnCommit failed");
10542 pindexGenesisBlock = pindexNew;
10543 }
10544 else if (hashPrevBlock == hashBestChain)
10545 {
10546 // Adding to current best branch
10547 if (!ConnectBlock(txdb, pindexNew) || !txdb.WriteHashBestChain(hash))
10548 {
10549 txdb.TxnAbort();
10550 InvalidChainFound(pindexNew);
10551 return error("SetBestChain() : ConnectBlock failed");
10552 }
10553 if (!txdb.TxnCommit())
10554 return error("SetBestChain() : TxnCommit failed");
10555
10556 // Add to current best branch
10557 pindexNew->pprev->pnext = pindexNew;
10558
10559 // Delete redundant memory transactions
10560 BOOST_FOREACH(CTransaction& tx, vtx)
10561 tx.RemoveFromMemoryPool();
10562 }
10563 else
10564 {
10565 // New best branch
10566 if (!Reorganize(txdb, pindexNew))
10567 {
10568 txdb.TxnAbort();
10569 InvalidChainFound(pindexNew);
10570 return error("SetBestChain() : Reorganize failed");
10571 }
10572 }
10573
10574 // Update best block in wallet (so we can detect restored wallets)
10575 if (!IsInitialBlockDownload())
10576 {
10577 const CBlockLocator locator(pindexNew);
10578 ::SetBestChain(locator);
10579 }
10580
10581 // New best block
10582 hashBestChain = hash;
10583 pindexBest = pindexNew;
10584 nBestHeight = pindexBest->nHeight;
10585 bnBestChainWork = pindexNew->bnChainWork;
10586 nTimeBestReceived = GetTime();
10587 nTransactionsUpdated++;
10588 printf("SetBestChain: new best=%s height=%d work=%s\n", hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, bnBestChainWork.ToString().c_str());
10589
10590 return true;
10591 }
10592
10593
10594 bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
10595 {
10596 // Check for duplicate
10597 uint256 hash = GetHash();
10598 if (mapBlockIndex.count(hash))
10599 return error("AddToBlockIndex() : %s already exists", hash.ToString().substr(0,20).c_str());
10600
10601 // Construct new block index object
10602 CBlockIndex* pindexNew = new CBlockIndex(nFile, nBlockPos, *this);
10603 if (!pindexNew)
10604 return error("AddToBlockIndex() : new CBlockIndex failed");
10605 map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
10606 pindexNew->phashBlock = &((*mi).first);
10607 map<uint256, CBlockIndex*>::iterator miPrev = mapBlockIndex.find(hashPrevBlock);
10608 if (miPrev != mapBlockIndex.end())
10609 {
10610 pindexNew->pprev = (*miPrev).second;
10611 pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
10612 }
10613 pindexNew->bnChainWork = (pindexNew->pprev ? pindexNew->pprev->bnChainWork : 0) + pindexNew->GetBlockWork();
10614
10615 CTxDB txdb;
10616 txdb.TxnBegin();
10617 txdb.WriteBlockIndex(CDiskBlockIndex(pindexNew));
10618 if (!txdb.TxnCommit())
10619 return false;
10620
10621 // New best
10622 if (pindexNew->bnChainWork > bnBestChainWork)
10623 if (!SetBestChain(txdb, pindexNew))
10624 return false;
10625
10626 txdb.Close();
10627
10628 if (pindexNew == pindexBest)
10629 {
10630 // Notify UI to display prev block's coinbase if it was ours
10631 static uint256 hashPrevBestCoinBase;
10632 UpdatedTransaction(hashPrevBestCoinBase);
10633 hashPrevBestCoinBase = vtx[0].GetHash();
10634 }
10635
10636 MainFrameRepaint();
10637 return true;
10638 }
10639
10640
10641
10642
10643 bool CBlock::CheckBlock() const
10644 {
10645 // These are checks that are independent of context
10646 // that can be verified before saving an orphan block.
10647
10648 // Size limits
10649 if (vtx.empty() || vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(*this, SER_NETWORK) > MAX_BLOCK_SIZE)
10650 return DoS(100, error("CheckBlock() : size limits failed"));
10651
10652 // Check proof of work matches claimed amount
10653 if (!CheckProofOfWork(GetHash(), nBits))
10654 return DoS(50, error("CheckBlock() : proof of work failed"));
10655
10656 // Check timestamp
10657 if (GetBlockTime() > GetAdjustedTime() + 2 * 60 * 60)
10658 return error("CheckBlock() : block timestamp too far in the future");
10659
10660 // First transaction must be coinbase, the rest must not be
10661 if (vtx.empty() || !vtx[0].IsCoinBase())
10662 return DoS(100, error("CheckBlock() : first tx is not coinbase"));
10663 for (int i = 1; i < vtx.size(); i++)
10664 if (vtx[i].IsCoinBase())
10665 return DoS(100, error("CheckBlock() : more than one coinbase"));
10666
10667 // Check transactions
10668 BOOST_FOREACH(const CTransaction& tx, vtx)
10669 if (!tx.CheckTransaction())
10670 return DoS(tx.nDoS, error("CheckBlock() : CheckTransaction failed"));
10671
10672 // Check that it's not full of nonstandard transactions
10673 if (GetSigOpCount() > MAX_BLOCK_SIGOPS)
10674 return DoS(100, error("CheckBlock() : out-of-bounds SigOpCount"));
10675
10676 // Check merkleroot
10677 if (hashMerkleRoot != BuildMerkleTree())
10678 return DoS(100, error("CheckBlock() : hashMerkleRoot mismatch"));
10679
10680 return true;
10681 }
10682
10683 bool CBlock::AcceptBlock()
10684 {
10685 // Check for duplicate
10686 uint256 hash = GetHash();
10687 if (mapBlockIndex.count(hash))
10688 return error("AcceptBlock() : block already in mapBlockIndex");
10689
10690 // Get prev block index
10691 map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashPrevBlock);
10692 if (mi == mapBlockIndex.end())
10693 return DoS(10, error("AcceptBlock() : prev block not found"));
10694 CBlockIndex* pindexPrev = (*mi).second;
10695 int nHeight = pindexPrev->nHeight+1;
10696
10697 // Check proof of work
10698 if (nBits != GetNextWorkRequired(pindexPrev, this))
10699 return DoS(100, error("AcceptBlock() : incorrect proof of work"));
10700
10701 // Check timestamp against prev
10702 if (GetBlockTime() <= pindexPrev->GetMedianTimePast())
10703 return error("AcceptBlock() : block's timestamp is too early");
10704
10705 // Check that all transactions are finalized
10706 BOOST_FOREACH(const CTransaction& tx, vtx)
10707 if (!tx.IsFinal(nHeight, GetBlockTime()))
10708 return DoS(10, error("AcceptBlock() : contains a non-final transaction"));
10709
10710 // Check that the block chain matches the known block chain up to a checkpoint
10711 if (!Checkpoints::CheckBlock(nHeight, hash))
10712 return DoS(100, error("AcceptBlock() : rejected by checkpoint lockin at %d", nHeight));
10713
10714 // Write block to history file
10715 if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK)))
10716 return error("AcceptBlock() : out of disk space");
10717 unsigned int nFile = -1;
10718 unsigned int nBlockPos = 0;
10719 if (!WriteToDisk(nFile, nBlockPos))
10720 return error("AcceptBlock() : WriteToDisk failed");
10721 if (!AddToBlockIndex(nFile, nBlockPos))
10722 return error("AcceptBlock() : AddToBlockIndex failed");
10723
10724 // Relay inventory, but don't relay old inventory during initial block download
10725 if (hashBestChain == hash)
10726 CRITICAL_BLOCK(cs_vNodes)
10727 BOOST_FOREACH(CNode* pnode, vNodes)
10728 if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : 140700))
10729 pnode->PushInventory(CInv(MSG_BLOCK, hash));
10730
10731 return true;
10732 }
10733
10734 bool ProcessBlock(CNode* pfrom, CBlock* pblock)
10735 {
10736 // Check for duplicate
10737 uint256 hash = pblock->GetHash();
10738 if (mapBlockIndex.count(hash))
10739 return error("ProcessBlock() : already have block %d %s", mapBlockIndex[hash]->nHeight, hash.ToString().substr(0,20).c_str());
10740 if (mapOrphanBlocks.count(hash))
10741 return error("ProcessBlock() : already have block (orphan) %s", hash.ToString().substr(0,20).c_str());
10742
10743 // Preliminary checks
10744 if (!pblock->CheckBlock())
10745 return error("ProcessBlock() : CheckBlock FAILED");
10746
10747 CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(mapBlockIndex);
10748 if (pcheckpoint && pblock->hashPrevBlock != hashBestChain)
10749 {
10750 // Extra checks to prevent "fill up memory by spamming with bogus blocks"
10751 int64 deltaTime = pblock->GetBlockTime() - pcheckpoint->nTime;
10752 if (deltaTime < 0)
10753 {
10754 if (pfrom)
10755 pfrom->Misbehaving(100);
10756 return error("ProcessBlock() : block with timestamp before last checkpoint");
10757 }
10758 CBigNum bnNewBlock;
10759 bnNewBlock.SetCompact(pblock->nBits);
10760 CBigNum bnRequired;
10761 bnRequired.SetCompact(ComputeMinWork(pcheckpoint->nBits, deltaTime));
10762 if (bnNewBlock > bnRequired)
10763 {
10764 if (pfrom)
10765 pfrom->Misbehaving(100);
10766 return error("ProcessBlock() : block with too little proof-of-work");
10767 }
10768 }
10769
10770
10771 // If don't already have its previous block, shunt it off to holding area until we get it
10772 if (!mapBlockIndex.count(pblock->hashPrevBlock))
10773 {
10774 printf("ProcessBlock: ORPHAN BLOCK, prev=%s\n", pblock->hashPrevBlock.ToString().substr(0,20).c_str());
10775 CBlock* pblock2 = new CBlock(*pblock);
10776 mapOrphanBlocks.insert(make_pair(hash, pblock2));
10777 mapOrphanBlocksByPrev.insert(make_pair(pblock2->hashPrevBlock, pblock2));
10778
10779 // Ask this guy to fill in what we're missing
10780 if (pfrom)
10781 pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(pblock2));
10782 return true;
10783 }
10784
10785 // Store to disk
10786 if (!pblock->AcceptBlock())
10787 return error("ProcessBlock() : AcceptBlock FAILED");
10788
10789 // Recursively process any orphan blocks that depended on this one
10790 vector<uint256> vWorkQueue;
10791 vWorkQueue.push_back(hash);
10792 for (int i = 0; i < vWorkQueue.size(); i++)
10793 {
10794 uint256 hashPrev = vWorkQueue[i];
10795 for (multimap<uint256, CBlock*>::iterator mi = mapOrphanBlocksByPrev.lower_bound(hashPrev);
10796 mi != mapOrphanBlocksByPrev.upper_bound(hashPrev);
10797 ++mi)
10798 {
10799 CBlock* pblockOrphan = (*mi).second;
10800 if (pblockOrphan->AcceptBlock())
10801 vWorkQueue.push_back(pblockOrphan->GetHash());
10802 mapOrphanBlocks.erase(pblockOrphan->GetHash());
10803 delete pblockOrphan;
10804 }
10805 mapOrphanBlocksByPrev.erase(hashPrev);
10806 }
10807
10808 printf("ProcessBlock: ACCEPTED\n");
10809 return true;
10810 }
10811
10812
10813
10814
10815
10816
10817
10818
10819 bool CheckDiskSpace(uint64 nAdditionalBytes)
10820 {
10821 uint64 nFreeBytesAvailable = filesystem::space(GetDataDir()).available;
10822
10823 // Check for 15MB because database could create another 10MB log file at any time
10824 if (nFreeBytesAvailable < (uint64)15000000 + nAdditionalBytes)
10825 {
10826 fShutdown = true;
10827 string strMessage = _("Warning: Disk space is low ");
10828 strMiscWarning = strMessage;
10829 printf("*** %s\n", strMessage.c_str());
10830 ThreadSafeMessageBox(strMessage, "Bitcoin", wxOK | wxICON_EXCLAMATION);
10831 CreateThread(Shutdown, NULL);
10832 return false;
10833 }
10834 return true;
10835 }
10836
10837 FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode)
10838 {
10839 if (nFile == -1)
10840 return NULL;
10841 FILE* file = fopen(strprintf("%s/blk%04d.dat", GetDataDir().c_str(), nFile).c_str(), pszMode);
10842 if (!file)
10843 return NULL;
10844 if (nBlockPos != 0 && !strchr(pszMode, 'a') && !strchr(pszMode, 'w'))
10845 {
10846 if (fseek(file, nBlockPos, SEEK_SET) != 0)
10847 {
10848 fclose(file);
10849 return NULL;
10850 }
10851 }
10852 return file;
10853 }
10854
10855 static unsigned int nCurrentBlockFile = 1;
10856
10857 FILE* AppendBlockFile(unsigned int& nFileRet)
10858 {
10859 nFileRet = 0;
10860 loop
10861 {
10862 FILE* file = OpenBlockFile(nCurrentBlockFile, 0, "ab");
10863 if (!file)
10864 return NULL;
10865 if (fseek(file, 0, SEEK_END) != 0)
10866 return NULL;
10867 // FAT32 filesize max 4GB, fseek and ftell max 2GB, so we must stay under 2GB
10868 if (ftell(file) < 0x7F000000 - MAX_SIZE)
10869 {
10870 nFileRet = nCurrentBlockFile;
10871 return file;
10872 }
10873 fclose(file);
10874 nCurrentBlockFile++;
10875 }
10876 }
10877
10878 bool LoadBlockIndex(bool fAllowNew)
10879 {
10880 if (fTestNet)
10881 {
10882 hashGenesisBlock = uint256("0x00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008");
10883 bnProofOfWorkLimit = CBigNum(~uint256(0) >> 28);
10884 pchMessageStart[0] = 0xfa;
10885 pchMessageStart[1] = 0xbf;
10886 pchMessageStart[2] = 0xb5;
10887 pchMessageStart[3] = 0xda;
10888 }
10889
10890 //
10891 // Load block index
10892 //
10893 CTxDB txdb("cr");
10894 if (!txdb.LoadBlockIndex())
10895 return false;
10896 txdb.Close();
10897
10898 //
10899 // Init with genesis block
10900 //
10901 if (mapBlockIndex.empty())
10902 {
10903 if (!fAllowNew)
10904 return false;
10905
10906 // Genesis Block:
10907 // CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=2083236893, vtx=1)
10908 // CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0)
10909 // CTxIn(COutPoint(000000, -1), coinbase 04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73)
10910 // CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B)
10911 // vMerkleTree: 4a5e1e
10912
10913 // Genesis block
10914 const char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks";
10915 CTransaction txNew;
10916 txNew.vin.resize(1);
10917 txNew.vout.resize(1);
10918 txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
10919 txNew.vout[0].nValue = 50 * COIN;
10920 txNew.vout[0].scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG;
10921 CBlock block;
10922 block.vtx.push_back(txNew);
10923 block.hashPrevBlock = 0;
10924 block.hashMerkleRoot = block.BuildMerkleTree();
10925 block.nVersion = 1;
10926 block.nTime = 1231006505;
10927 block.nBits = 0x1d00ffff;
10928 block.nNonce = 2083236893;
10929
10930 if (fTestNet)
10931 {
10932 block.nTime = 1296688602;
10933 block.nBits = 0x1d07fff8;
10934 block.nNonce = 384568319;
10935 }
10936
10937 //// debug print
10938 printf("%s\n", block.GetHash().ToString().c_str());
10939 printf("%s\n", hashGenesisBlock.ToString().c_str());
10940 printf("%s\n", block.hashMerkleRoot.ToString().c_str());
10941 assert(block.hashMerkleRoot == uint256("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
10942 block.print();
10943 assert(block.GetHash() == hashGenesisBlock);
10944
10945 // Start new block file
10946 unsigned int nFile;
10947 unsigned int nBlockPos;
10948 if (!block.WriteToDisk(nFile, nBlockPos))
10949 return error("LoadBlockIndex() : writing genesis block to disk failed");
10950 if (!block.AddToBlockIndex(nFile, nBlockPos))
10951 return error("LoadBlockIndex() : genesis block not accepted");
10952 }
10953
10954 return true;
10955 }
10956
10957
10958
10959 void PrintBlockTree()
10960 {
10961 // precompute tree structure
10962 map<CBlockIndex*, vector<CBlockIndex*> > mapNext;
10963 for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi)
10964 {
10965 CBlockIndex* pindex = (*mi).second;
10966 mapNext[pindex->pprev].push_back(pindex);
10967 // test
10968 //while (rand() % 3 == 0)
10969 // mapNext[pindex->pprev].push_back(pindex);
10970 }
10971
10972 vector<pair<int, CBlockIndex*> > vStack;
10973 vStack.push_back(make_pair(0, pindexGenesisBlock));
10974
10975 int nPrevCol = 0;
10976 while (!vStack.empty())
10977 {
10978 int nCol = vStack.back().first;
10979 CBlockIndex* pindex = vStack.back().second;
10980 vStack.pop_back();
10981
10982 // print split or gap
10983 if (nCol > nPrevCol)
10984 {
10985 for (int i = 0; i < nCol-1; i++)
10986 printf("| ");
10987 printf("|\\\n");
10988 }
10989 else if (nCol < nPrevCol)
10990 {
10991 for (int i = 0; i < nCol; i++)
10992 printf("| ");
10993 printf("|\n");
10994 }
10995 nPrevCol = nCol;
10996
10997 // print columns
10998 for (int i = 0; i < nCol; i++)
10999 printf("| ");
11000
11001 // print item
11002 CBlock block;
11003 block.ReadFromDisk(pindex);
11004 printf("%d (%u,%u) %s %s tx %d",
11005 pindex->nHeight,
11006 pindex->nFile,
11007 pindex->nBlockPos,
11008 block.GetHash().ToString().substr(0,20).c_str(),
11009 DateTimeStrFormat("%x %H:%M:%S", block.GetBlockTime()).c_str(),
11010 block.vtx.size());
11011
11012 PrintWallets(block);
11013
11014 // put the main timechain first
11015 vector<CBlockIndex*>& vNext = mapNext[pindex];
11016 for (int i = 0; i < vNext.size(); i++)
11017 {
11018 if (vNext[i]->pnext)
11019 {
11020 swap(vNext[0], vNext[i]);
11021 break;
11022 }
11023 }
11024
11025 // iterate children
11026 for (int i = 0; i < vNext.size(); i++)
11027 vStack.push_back(make_pair(nCol+i, vNext[i]));
11028 }
11029 }
11030
11031
11032
11033
11034
11035
11036
11037
11038
11039
11040 //////////////////////////////////////////////////////////////////////////////
11041 //
11042 // CAlert
11043 //
11044
11045 map<uint256, CAlert> mapAlerts;
11046 CCriticalSection cs_mapAlerts;
11047
11048 string GetWarnings(string strFor)
11049 {
11050 int nPriority = 0;
11051 string strStatusBar;
11052 string strRPC;
11053 if (GetBoolArg("-testsafemode"))
11054 strRPC = "test";
11055
11056 // Misc warnings like out of disk space and clock is wrong
11057 if (strMiscWarning != "")
11058 {
11059 nPriority = 1000;
11060 strStatusBar = strMiscWarning;
11061 }
11062
11063 // Longer invalid proof-of-work chain
11064 if (pindexBest && bnBestInvalidWork > bnBestChainWork + pindexBest->GetBlockWork() * 6)
11065 {
11066 nPriority = 2000;
11067 strStatusBar = strRPC = "WARNING: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade.";
11068 }
11069
11070 // Alerts
11071 CRITICAL_BLOCK(cs_mapAlerts)
11072 {
11073 BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
11074 {
11075 const CAlert& alert = item.second;
11076 if (alert.AppliesToMe() && alert.nPriority > nPriority)
11077 {
11078 nPriority = alert.nPriority;
11079 strStatusBar = alert.strStatusBar;
11080 }
11081 }
11082 }
11083
11084 if (strFor == "statusbar")
11085 return strStatusBar;
11086 else if (strFor == "rpc")
11087 return strRPC;
11088 assert(!"GetWarnings() : invalid parameter");
11089 return "error";
11090 }
11091
11092 bool CAlert::ProcessAlert()
11093 {
11094 if (!CheckSignature())
11095 return false;
11096 if (!IsInEffect())
11097 return false;
11098
11099 CRITICAL_BLOCK(cs_mapAlerts)
11100 {
11101 // Cancel previous alerts
11102 for (map<uint256, CAlert>::iterator mi = mapAlerts.begin(); mi != mapAlerts.end();)
11103 {
11104 const CAlert& alert = (*mi).second;
11105 if (Cancels(alert))
11106 {
11107 printf("cancelling alert %d\n", alert.nID);
11108 mapAlerts.erase(mi++);
11109 }
11110 else if (!alert.IsInEffect())
11111 {
11112 printf("expiring alert %d\n", alert.nID);
11113 mapAlerts.erase(mi++);
11114 }
11115 else
11116 mi++;
11117 }
11118
11119 // Check if this alert has been cancelled
11120 BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
11121 {
11122 const CAlert& alert = item.second;
11123 if (alert.Cancels(*this))
11124 {
11125 printf("alert already cancelled by %d\n", alert.nID);
11126 return false;
11127 }
11128 }
11129
11130 // Add to mapAlerts
11131 mapAlerts.insert(make_pair(GetHash(), *this));
11132 }
11133
11134 printf("accepted alert %d, AppliesToMe()=%d\n", nID, AppliesToMe());
11135 MainFrameRepaint();
11136 return true;
11137 }
11138
11139
11140
11141
11142
11143
11144
11145
11146 //////////////////////////////////////////////////////////////////////////////
11147 //
11148 // Messages
11149 //
11150
11151
11152 bool static AlreadyHave(CTxDB& txdb, const CInv& inv)
11153 {
11154 switch (inv.type)
11155 {
11156 case MSG_TX: return mapTransactions.count(inv.hash) || mapOrphanTransactions.count(inv.hash) || txdb.ContainsTx(inv.hash);
11157 case MSG_BLOCK: return mapBlockIndex.count(inv.hash) || mapOrphanBlocks.count(inv.hash);
11158 }
11159 // Don't know what it is, just say we already got one
11160 return true;
11161 }
11162
11163
11164
11165
11166 // The message start string is designed to be unlikely to occur in normal data.
11167 // The characters are rarely used upper ascii, not valid as UTF-8, and produce
11168 // a large 4-byte int at any alignment.
11169 unsigned char pchMessageStart[4] = { 0xf9, 0xbe, 0xb4, 0xd9 };
11170
11171
11172 bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
11173 {
11174 static map<unsigned int, vector<unsigned char> > mapReuseKey;
11175 RandAddSeedPerfmon();
11176 if (fDebug) {
11177 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
11178 printf("received: %s (%d bytes)\n", strCommand.c_str(), vRecv.size());
11179 }
11180 if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
11181 {
11182 printf("dropmessagestest DROPPING RECV MESSAGE\n");
11183 return true;
11184 }
11185
11186
11187
11188
11189
11190 if (strCommand == "version")
11191 {
11192 // Each connection can only send one version message
11193 if (pfrom->nVersion != 0)
11194 {
11195 pfrom->Misbehaving(1);
11196 return false;
11197 }
11198
11199 int64 nTime;
11200 CAddress addrMe;
11201 CAddress addrFrom;
11202 uint64 nNonce = 1;
11203 vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe;
11204 if (pfrom->nVersion == 10300)
11205 pfrom->nVersion = 300;
11206 if (pfrom->nVersion >= 106 && !vRecv.empty())
11207 vRecv >> addrFrom >> nNonce;
11208 if (pfrom->nVersion >= 106 && !vRecv.empty())
11209 vRecv >> pfrom->strSubVer;
11210 if (pfrom->nVersion >= 209 && !vRecv.empty())
11211 vRecv >> pfrom->nStartingHeight;
11212
11213 if (pfrom->nVersion == 0)
11214 return false;
11215
11216 // Disconnect if we connected to ourself
11217 if (nNonce == nLocalHostNonce && nNonce > 1)
11218 {
11219 printf("connected to self at %s, disconnecting\n", pfrom->addr.ToString().c_str());
11220 pfrom->fDisconnect = true;
11221 return true;
11222 }
11223
11224 // Be shy and don't send version until we hear
11225 if (pfrom->fInbound)
11226 pfrom->PushVersion();
11227
11228 pfrom->fClient = !(pfrom->nServices & NODE_NETWORK);
11229
11230 AddTimeData(pfrom->addr.ip, nTime);
11231
11232 // Change version
11233 if (pfrom->nVersion >= 209)
11234 pfrom->PushMessage("verack");
11235 pfrom->vSend.SetVersion(min(pfrom->nVersion, VERSION));
11236 if (pfrom->nVersion < 209)
11237 pfrom->vRecv.SetVersion(min(pfrom->nVersion, VERSION));
11238
11239 if (!pfrom->fInbound)
11240 {
11241 // Advertise our address
11242 if (addrLocalHost.IsRoutable() && !fUseProxy)
11243 {
11244 CAddress addr(addrLocalHost);
11245 addr.nTime = GetAdjustedTime();
11246 pfrom->PushAddress(addr);
11247 }
11248
11249 // Get recent addresses
11250 if (pfrom->nVersion >= 31402 || mapAddresses.size() < 1000)
11251 {
11252 pfrom->PushMessage("getaddr");
11253 pfrom->fGetAddr = true;
11254 }
11255 }
11256
11257 // Ask the first connected node for block updates
11258 static int nAskedForBlocks;
11259 if (!pfrom->fClient &&
11260 (pfrom->nVersion < 32000 || pfrom->nVersion >= 32400) &&
11261 (nAskedForBlocks < 1 || vNodes.size() <= 1))
11262 {
11263 nAskedForBlocks++;
11264 pfrom->PushGetBlocks(pindexBest, uint256(0));
11265 }
11266
11267 // Relay alerts
11268 CRITICAL_BLOCK(cs_mapAlerts)
11269 BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
11270 item.second.RelayTo(pfrom);
11271
11272 pfrom->fSuccessfullyConnected = true;
11273
11274 printf("version message: version %d, blocks=%d\n", pfrom->nVersion, pfrom->nStartingHeight);
11275
11276 cPeerBlockCounts.input(pfrom->nStartingHeight);
11277 }
11278
11279
11280 else if (pfrom->nVersion == 0)
11281 {
11282 // Must have a version message before anything else
11283 pfrom->Misbehaving(1);
11284 return false;
11285 }
11286
11287
11288 else if (strCommand == "verack")
11289 {
11290 pfrom->vRecv.SetVersion(min(pfrom->nVersion, VERSION));
11291 }
11292
11293
11294 else if (strCommand == "addr")
11295 {
11296 vector<CAddress> vAddr;
11297 vRecv >> vAddr;
11298
11299 // Don't want addr from older versions unless seeding
11300 if (pfrom->nVersion < 209)
11301 return true;
11302 if (pfrom->nVersion < 31402 && mapAddresses.size() > 1000)
11303 return true;
11304 if (vAddr.size() > 1000)
11305 {
11306 pfrom->Misbehaving(20);
11307 return error("message addr size() = %d", vAddr.size());
11308 }
11309
11310 // Store the new addresses
11311 CAddrDB addrDB;
11312 addrDB.TxnBegin();
11313 int64 nNow = GetAdjustedTime();
11314 int64 nSince = nNow - 10 * 60;
11315 BOOST_FOREACH(CAddress& addr, vAddr)
11316 {
11317 if (fShutdown)
11318 return true;
11319 // ignore IPv6 for now, since it isn't implemented anyway
11320 if (!addr.IsIPv4())
11321 continue;
11322 if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60)
11323 addr.nTime = nNow - 5 * 24 * 60 * 60;
11324 AddAddress(addr, 2 * 60 * 60, &addrDB);
11325 pfrom->AddAddressKnown(addr);
11326 if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable())
11327 {
11328 // Relay to a limited number of other nodes
11329 CRITICAL_BLOCK(cs_vNodes)
11330 {
11331 // Use deterministic randomness to send to the same nodes for 24 hours
11332 // at a time so the setAddrKnowns of the chosen nodes prevent repeats
11333 static uint256 hashSalt;
11334 if (hashSalt == 0)
11335 RAND_bytes((unsigned char*)&hashSalt, sizeof(hashSalt));
11336 uint256 hashRand = hashSalt ^ (((int64)addr.ip)<<32) ^ ((GetTime()+addr.ip)/(24*60*60));
11337 hashRand = Hash(BEGIN(hashRand), END(hashRand));
11338 multimap<uint256, CNode*> mapMix;
11339 BOOST_FOREACH(CNode* pnode, vNodes)
11340 {
11341 if (pnode->nVersion < 31402)
11342 continue;
11343 unsigned int nPointer;
11344 memcpy(&nPointer, &pnode, sizeof(nPointer));
11345 uint256 hashKey = hashRand ^ nPointer;
11346 hashKey = Hash(BEGIN(hashKey), END(hashKey));
11347 mapMix.insert(make_pair(hashKey, pnode));
11348 }
11349 int nRelayNodes = 2;
11350 for (multimap<uint256, CNode*>::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi)
11351 ((*mi).second)->PushAddress(addr);
11352 }
11353 }
11354 }
11355 addrDB.TxnCommit(); // Save addresses (it's ok if this fails)
11356 if (vAddr.size() < 1000)
11357 pfrom->fGetAddr = false;
11358 }
11359
11360
11361 else if (strCommand == "inv")
11362 {
11363 vector<CInv> vInv;
11364 vRecv >> vInv;
11365 if (vInv.size() > 50000)
11366 {
11367 pfrom->Misbehaving(20);
11368 return error("message inv size() = %d", vInv.size());
11369 }
11370
11371 CTxDB txdb("r");
11372 BOOST_FOREACH(const CInv& inv, vInv)
11373 {
11374 if (fShutdown)
11375 return true;
11376 pfrom->AddInventoryKnown(inv);
11377
11378 bool fAlreadyHave = AlreadyHave(txdb, inv);
11379 if (fDebug)
11380 printf(" got inventory: %s %s\n", inv.ToString().c_str(), fAlreadyHave ? "have" : "new");
11381
11382 if (!fAlreadyHave)
11383 pfrom->AskFor(inv);
11384 else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash))
11385 pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(mapOrphanBlocks[inv.hash]));
11386
11387 // Track requests for our stuff
11388 Inventory(inv.hash);
11389 }
11390 }
11391
11392
11393 else if (strCommand == "getdata")
11394 {
11395 vector<CInv> vInv;
11396 vRecv >> vInv;
11397 if (vInv.size() > 50000)
11398 {
11399 pfrom->Misbehaving(20);
11400 return error("message getdata size() = %d", vInv.size());
11401 }
11402
11403 BOOST_FOREACH(const CInv& inv, vInv)
11404 {
11405 if (fShutdown)
11406 return true;
11407 printf("received getdata for: %s\n", inv.ToString().c_str());
11408
11409 if (inv.type == MSG_BLOCK)
11410 {
11411 // Send block from disk
11412 map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(inv.hash);
11413 if (mi != mapBlockIndex.end())
11414 {
11415 CBlock block;
11416 block.ReadFromDisk((*mi).second);
11417 pfrom->PushMessage("block", block);
11418
11419 // Trigger them to send a getblocks request for the next batch of inventory
11420 if (inv.hash == pfrom->hashContinue)
11421 {
11422 // Bypass PushInventory, this must send even if redundant,
11423 // and we want it right after the last block so they don't
11424 // wait for other stuff first.
11425 vector<CInv> vInv;
11426 vInv.push_back(CInv(MSG_BLOCK, hashBestChain));
11427 pfrom->PushMessage("inv", vInv);
11428 pfrom->hashContinue = 0;
11429 }
11430 }
11431 }
11432 else if (inv.IsKnownType())
11433 {
11434 // Send stream from relay memory
11435 CRITICAL_BLOCK(cs_mapRelay)
11436 {
11437 map<CInv, CDataStream>::iterator mi = mapRelay.find(inv);
11438 if (mi != mapRelay.end())
11439 pfrom->PushMessage(inv.GetCommand(), (*mi).second);
11440 }
11441 }
11442
11443 // Track requests for our stuff
11444 Inventory(inv.hash);
11445 }
11446 }
11447
11448
11449 else if (strCommand == "getblocks")
11450 {
11451 CBlockLocator locator;
11452 uint256 hashStop;
11453 vRecv >> locator >> hashStop;
11454
11455 // Find the last block the caller has in the main chain
11456 CBlockIndex* pindex = locator.GetBlockIndex();
11457
11458 // Send the rest of the chain
11459 if (pindex)
11460 pindex = pindex->pnext;
11461 int nLimit = 500 + locator.GetDistanceBack();
11462 unsigned int nBytes = 0;
11463 printf("getblocks %d to %s limit %d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,20).c_str(), nLimit);
11464 for (; pindex; pindex = pindex->pnext)
11465 {
11466 if (pindex->GetBlockHash() == hashStop)
11467 {
11468 printf(" getblocks stopping at %d %s (%u bytes)\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,20).c_str(), nBytes);
11469 break;
11470 }
11471 pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash()));
11472 CBlock block;
11473 block.ReadFromDisk(pindex, true);
11474 nBytes += block.GetSerializeSize(SER_NETWORK);
11475 if (--nLimit <= 0 || nBytes >= SendBufferSize()/2)
11476 {
11477 // When this block is requested, we'll send an inv that'll make them
11478 // getblocks the next batch of inventory.
11479 printf(" getblocks stopping at limit %d %s (%u bytes)\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,20).c_str(), nBytes);
11480 pfrom->hashContinue = pindex->GetBlockHash();
11481 break;
11482 }
11483 }
11484 }
11485
11486
11487 else if (strCommand == "getheaders")
11488 {
11489 CBlockLocator locator;
11490 uint256 hashStop;
11491 vRecv >> locator >> hashStop;
11492
11493 CBlockIndex* pindex = NULL;
11494 if (locator.IsNull())
11495 {
11496 // If locator is null, return the hashStop block
11497 map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashStop);
11498 if (mi == mapBlockIndex.end())
11499 return true;
11500 pindex = (*mi).second;
11501 }
11502 else
11503 {
11504 // Find the last block the caller has in the main chain
11505 pindex = locator.GetBlockIndex();
11506 if (pindex)
11507 pindex = pindex->pnext;
11508 }
11509
11510 vector<CBlock> vHeaders;
11511 int nLimit = 2000 + locator.GetDistanceBack();
11512 printf("getheaders %d to %s limit %d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,20).c_str(), nLimit);
11513 for (; pindex; pindex = pindex->pnext)
11514 {
11515 vHeaders.push_back(pindex->GetBlockHeader());
11516 if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
11517 break;
11518 }
11519 pfrom->PushMessage("headers", vHeaders);
11520 }
11521
11522
11523 else if (strCommand == "tx")
11524 {
11525 vector<uint256> vWorkQueue;
11526 CDataStream vMsg(vRecv);
11527 CTransaction tx;
11528 vRecv >> tx;
11529
11530 CInv inv(MSG_TX, tx.GetHash());
11531 pfrom->AddInventoryKnown(inv);
11532
11533 bool fMissingInputs = false;
11534 if (tx.AcceptToMemoryPool(true, &fMissingInputs))
11535 {
11536 SyncWithWallets(tx, NULL, true);
11537 RelayMessage(inv, vMsg);
11538 mapAlreadyAskedFor.erase(inv);
11539 vWorkQueue.push_back(inv.hash);
11540
11541 // Recursively process any orphan transactions that depended on this one
11542 for (int i = 0; i < vWorkQueue.size(); i++)
11543 {
11544 uint256 hashPrev = vWorkQueue[i];
11545 for (multimap<uint256, CDataStream*>::iterator mi = mapOrphanTransactionsByPrev.lower_bound(hashPrev);
11546 mi != mapOrphanTransactionsByPrev.upper_bound(hashPrev);
11547 ++mi)
11548 {
11549 const CDataStream& vMsg = *((*mi).second);
11550 CTransaction tx;
11551 CDataStream(vMsg) >> tx;
11552 CInv inv(MSG_TX, tx.GetHash());
11553
11554 if (tx.AcceptToMemoryPool(true))
11555 {
11556 printf(" accepted orphan tx %s\n", inv.hash.ToString().substr(0,10).c_str());
11557 SyncWithWallets(tx, NULL, true);
11558 RelayMessage(inv, vMsg);
11559 mapAlreadyAskedFor.erase(inv);
11560 vWorkQueue.push_back(inv.hash);
11561 }
11562 }
11563 }
11564
11565 BOOST_FOREACH(uint256 hash, vWorkQueue)
11566 EraseOrphanTx(hash);
11567 }
11568 else if (fMissingInputs)
11569 {
11570 printf("storing orphan tx %s\n", inv.hash.ToString().substr(0,10).c_str());
11571 AddOrphanTx(vMsg);
11572
11573 // DoS prevention: do not allow mapOrphanTransactions to grow unbounded
11574 int nEvicted = LimitOrphanTxSize(MAX_ORPHAN_TRANSACTIONS);
11575 if (nEvicted > 0)
11576 printf("mapOrphan overflow, removed %d tx\n", nEvicted);
11577 }
11578 if (tx.nDoS) pfrom->Misbehaving(tx.nDoS);
11579 }
11580
11581
11582 else if (strCommand == "block")
11583 {
11584 CBlock block;
11585 vRecv >> block;
11586
11587 printf("received block %s\n", block.GetHash().ToString().substr(0,20).c_str());
11588 // block.print();
11589
11590 CInv inv(MSG_BLOCK, block.GetHash());
11591 pfrom->AddInventoryKnown(inv);
11592
11593 if (ProcessBlock(pfrom, &block))
11594 mapAlreadyAskedFor.erase(inv);
11595 if (block.nDoS) pfrom->Misbehaving(block.nDoS);
11596 }
11597
11598
11599 else if (strCommand == "getaddr")
11600 {
11601 // Nodes rebroadcast an addr every 24 hours
11602 pfrom->vAddrToSend.clear();
11603 int64 nSince = GetAdjustedTime() - 3 * 60 * 60; // in the last 3 hours
11604 CRITICAL_BLOCK(cs_mapAddresses)
11605 {
11606 unsigned int nCount = 0;
11607 BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
11608 {
11609 const CAddress& addr = item.second;
11610 if (addr.nTime > nSince)
11611 nCount++;
11612 }
11613 BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
11614 {
11615 const CAddress& addr = item.second;
11616 if (addr.nTime > nSince && GetRand(nCount) < 2500)
11617 pfrom->PushAddress(addr);
11618 }
11619 }
11620 }
11621
11622
11623 else if (strCommand == "checkorder")
11624 {
11625 uint256 hashReply;
11626 vRecv >> hashReply;
11627
11628 if (!GetBoolArg("-allowreceivebyip"))
11629 {
11630 pfrom->PushMessage("reply", hashReply, (int)2, string(""));
11631 return true;
11632 }
11633
11634 CWalletTx order;
11635 vRecv >> order;
11636
11637 /// we have a chance to check the order here
11638
11639 // Keep giving the same key to the same ip until they use it
11640 if (!mapReuseKey.count(pfrom->addr.ip))
11641 pwalletMain->GetKeyFromPool(mapReuseKey[pfrom->addr.ip], true);
11642
11643 // Send back approval of order and pubkey to use
11644 CScript scriptPubKey;
11645 scriptPubKey << mapReuseKey[pfrom->addr.ip] << OP_CHECKSIG;
11646 pfrom->PushMessage("reply", hashReply, (int)0, scriptPubKey);
11647 }
11648
11649
11650 else if (strCommand == "reply")
11651 {
11652 uint256 hashReply;
11653 vRecv >> hashReply;
11654
11655 CRequestTracker tracker;
11656 CRITICAL_BLOCK(pfrom->cs_mapRequests)
11657 {
11658 map<uint256, CRequestTracker>::iterator mi = pfrom->mapRequests.find(hashReply);
11659 if (mi != pfrom->mapRequests.end())
11660 {
11661 tracker = (*mi).second;
11662 pfrom->mapRequests.erase(mi);
11663 }
11664 }
11665 if (!tracker.IsNull())
11666 tracker.fn(tracker.param1, vRecv);
11667 }
11668
11669
11670 else if (strCommand == "ping")
11671 {
11672 }
11673
11674
11675 else if (strCommand == "alert")
11676 {
11677 CAlert alert;
11678 vRecv >> alert;
11679
11680 if (alert.ProcessAlert())
11681 {
11682 // Relay
11683 pfrom->setKnown.insert(alert.GetHash());
11684 CRITICAL_BLOCK(cs_vNodes)
11685 BOOST_FOREACH(CNode* pnode, vNodes)
11686 alert.RelayTo(pnode);
11687 }
11688 }
11689
11690
11691 else
11692 {
11693 // Ignore unknown commands for extensibility
11694 }
11695
11696
11697 // Update the last seen time for this node's address
11698 if (pfrom->fNetworkNode)
11699 if (strCommand == "version" || strCommand == "addr" || strCommand == "inv" || strCommand == "getdata" || strCommand == "ping")
11700 AddressCurrentlyConnected(pfrom->addr);
11701
11702
11703 return true;
11704 }
11705
11706 bool ProcessMessages(CNode* pfrom)
11707 {
11708 CDataStream& vRecv = pfrom->vRecv;
11709 if (vRecv.empty())
11710 return true;
11711 //if (fDebug)
11712 // printf("ProcessMessages(%u bytes)\n", vRecv.size());
11713
11714 //
11715 // Message format
11716 // (4) message start
11717 // (12) command
11718 // (4) size
11719 // (4) checksum
11720 // (x) data
11721 //
11722
11723 loop
11724 {
11725 // Scan for message start
11726 CDataStream::iterator pstart = search(vRecv.begin(), vRecv.end(), BEGIN(pchMessageStart), END(pchMessageStart));
11727 int nHeaderSize = vRecv.GetSerializeSize(CMessageHeader());
11728 if (vRecv.end() - pstart < nHeaderSize)
11729 {
11730 if (vRecv.size() > nHeaderSize)
11731 {
11732 printf("\n\nPROCESSMESSAGE MESSAGESTART NOT FOUND\n\n");
11733 vRecv.erase(vRecv.begin(), vRecv.end() - nHeaderSize);
11734 }
11735 break;
11736 }
11737 if (pstart - vRecv.begin() > 0)
11738 printf("\n\nPROCESSMESSAGE SKIPPED %d BYTES\n\n", pstart - vRecv.begin());
11739 vRecv.erase(vRecv.begin(), pstart);
11740
11741 // Read header
11742 vector<char> vHeaderSave(vRecv.begin(), vRecv.begin() + nHeaderSize);
11743 CMessageHeader hdr;
11744 vRecv >> hdr;
11745 if (!hdr.IsValid())
11746 {
11747 printf("\n\nPROCESSMESSAGE: ERRORS IN HEADER %s\n\n\n", hdr.GetCommand().c_str());
11748 continue;
11749 }
11750 string strCommand = hdr.GetCommand();
11751
11752 // Message size
11753 unsigned int nMessageSize = hdr.nMessageSize;
11754 if (nMessageSize > MAX_SIZE)
11755 {
11756 printf("ProcessMessage(%s, %u bytes) : nMessageSize > MAX_SIZE\n", strCommand.c_str(), nMessageSize);
11757 continue;
11758 }
11759 if (nMessageSize > vRecv.size())
11760 {
11761 // Rewind and wait for rest of message
11762 vRecv.insert(vRecv.begin(), vHeaderSave.begin(), vHeaderSave.end());
11763 break;
11764 }
11765
11766 // Checksum
11767 if (vRecv.GetVersion() >= 209)
11768 {
11769 uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize);
11770 unsigned int nChecksum = 0;
11771 memcpy(&nChecksum, &hash, sizeof(nChecksum));
11772 if (nChecksum != hdr.nChecksum)
11773 {
11774 printf("ProcessMessage(%s, %u bytes) : CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n",
11775 strCommand.c_str(), nMessageSize, nChecksum, hdr.nChecksum);
11776 continue;
11777 }
11778 }
11779
11780 // Copy message to its own buffer
11781 CDataStream vMsg(vRecv.begin(), vRecv.begin() + nMessageSize, vRecv.nType, vRecv.nVersion);
11782 vRecv.ignore(nMessageSize);
11783
11784 // Process message
11785 bool fRet = false;
11786 try
11787 {
11788 CRITICAL_BLOCK(cs_main)
11789 fRet = ProcessMessage(pfrom, strCommand, vMsg);
11790 if (fShutdown)
11791 return true;
11792 }
11793 catch (std::ios_base::failure& e)
11794 {
11795 if (strstr(e.what(), "end of data"))
11796 {
11797 // Allow exceptions from underlength message on vRecv
11798 printf("ProcessMessage(%s, %u bytes) : Exception '%s' caught, normally caused by a message being shorter than its stated length\n", strCommand.c_str(), nMessageSize, e.what());
11799 }
11800 else if (strstr(e.what(), "size too large"))
11801 {
11802 // Allow exceptions from overlong size
11803 printf("ProcessMessage(%s, %u bytes) : Exception '%s' caught\n", strCommand.c_str(), nMessageSize, e.what());
11804 }
11805 else
11806 {
11807 PrintExceptionContinue(&e, "ProcessMessage()");
11808 }
11809 }
11810 catch (std::exception& e) {
11811 PrintExceptionContinue(&e, "ProcessMessage()");
11812 } catch (...) {
11813 PrintExceptionContinue(NULL, "ProcessMessage()");
11814 }
11815
11816 if (!fRet)
11817 printf("ProcessMessage(%s, %u bytes) FAILED\n", strCommand.c_str(), nMessageSize);
11818 }
11819
11820 vRecv.Compact();
11821 return true;
11822 }
11823
11824
11825 bool SendMessages(CNode* pto, bool fSendTrickle)
11826 {
11827 CRITICAL_BLOCK(cs_main)
11828 {
11829 // Don't send anything until we get their version message
11830 if (pto->nVersion == 0)
11831 return true;
11832
11833 // Keep-alive ping
11834 if (pto->nLastSend && GetTime() - pto->nLastSend > 30 * 60 && pto->vSend.empty())
11835 pto->PushMessage("ping");
11836
11837 // Resend wallet transactions that haven't gotten in a block yet
11838 ResendWalletTransactions();
11839
11840 // Address refresh broadcast
11841 static int64 nLastRebroadcast;
11842 if (GetTime() - nLastRebroadcast > 24 * 60 * 60)
11843 {
11844 nLastRebroadcast = GetTime();
11845 CRITICAL_BLOCK(cs_vNodes)
11846 {
11847 BOOST_FOREACH(CNode* pnode, vNodes)
11848 {
11849 // Periodically clear setAddrKnown to allow refresh broadcasts
11850 pnode->setAddrKnown.clear();
11851
11852 // Rebroadcast our address
11853 if (addrLocalHost.IsRoutable() && !fUseProxy)
11854 {
11855 CAddress addr(addrLocalHost);
11856 addr.nTime = GetAdjustedTime();
11857 pnode->PushAddress(addr);
11858 }
11859 }
11860 }
11861 }
11862
11863 // Clear out old addresses periodically so it's not too much work at once
11864 static int64 nLastClear;
11865 if (nLastClear == 0)
11866 nLastClear = GetTime();
11867 if (GetTime() - nLastClear > 10 * 60 && vNodes.size() >= 3)
11868 {
11869 nLastClear = GetTime();
11870 CRITICAL_BLOCK(cs_mapAddresses)
11871 {
11872 CAddrDB addrdb;
11873 int64 nSince = GetAdjustedTime() - 14 * 24 * 60 * 60;
11874 for (map<vector<unsigned char>, CAddress>::iterator mi = mapAddresses.begin();
11875 mi != mapAddresses.end();)
11876 {
11877 const CAddress& addr = (*mi).second;
11878 if (addr.nTime < nSince)
11879 {
11880 if (mapAddresses.size() < 1000 || GetTime() > nLastClear + 20)
11881 break;
11882 addrdb.EraseAddress(addr);
11883 mapAddresses.erase(mi++);
11884 }
11885 else
11886 mi++;
11887 }
11888 }
11889 }
11890
11891
11892 //
11893 // Message: addr
11894 //
11895 if (fSendTrickle)
11896 {
11897 vector<CAddress> vAddr;
11898 vAddr.reserve(pto->vAddrToSend.size());
11899 BOOST_FOREACH(const CAddress& addr, pto->vAddrToSend)
11900 {
11901 // returns true if wasn't already contained in the set
11902 if (pto->setAddrKnown.insert(addr).second)
11903 {
11904 vAddr.push_back(addr);
11905 // receiver rejects addr messages larger than 1000
11906 if (vAddr.size() >= 1000)
11907 {
11908 pto->PushMessage("addr", vAddr);
11909 vAddr.clear();
11910 }
11911 }
11912 }
11913 pto->vAddrToSend.clear();
11914 if (!vAddr.empty())
11915 pto->PushMessage("addr", vAddr);
11916 }
11917
11918
11919 //
11920 // Message: inventory
11921 //
11922 vector<CInv> vInv;
11923 vector<CInv> vInvWait;
11924 CRITICAL_BLOCK(pto->cs_inventory)
11925 {
11926 vInv.reserve(pto->vInventoryToSend.size());
11927 vInvWait.reserve(pto->vInventoryToSend.size());
11928 BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend)
11929 {
11930 if (pto->setInventoryKnown.count(inv))
11931 continue;
11932
11933 // trickle out tx inv to protect privacy
11934 if (inv.type == MSG_TX && !fSendTrickle)
11935 {
11936 // 1/4 of tx invs blast to all immediately
11937 static uint256 hashSalt;
11938 if (hashSalt == 0)
11939 RAND_bytes((unsigned char*)&hashSalt, sizeof(hashSalt));
11940 uint256 hashRand = inv.hash ^ hashSalt;
11941 hashRand = Hash(BEGIN(hashRand), END(hashRand));
11942 bool fTrickleWait = ((hashRand & 3) != 0);
11943
11944 // always trickle our own transactions
11945 if (!fTrickleWait)
11946 {
11947 CWalletTx wtx;
11948 if (GetTransaction(inv.hash, wtx))
11949 if (wtx.fFromMe)
11950 fTrickleWait = true;
11951 }
11952
11953 if (fTrickleWait)
11954 {
11955 vInvWait.push_back(inv);
11956 continue;
11957 }
11958 }
11959
11960 // returns true if wasn't already contained in the set
11961 if (pto->setInventoryKnown.insert(inv).second)
11962 {
11963 vInv.push_back(inv);
11964 if (vInv.size() >= 1000)
11965 {
11966 pto->PushMessage("inv", vInv);
11967 vInv.clear();
11968 }
11969 }
11970 }
11971 pto->vInventoryToSend = vInvWait;
11972 }
11973 if (!vInv.empty())
11974 pto->PushMessage("inv", vInv);
11975
11976
11977 //
11978 // Message: getdata
11979 //
11980 vector<CInv> vGetData;
11981 int64 nNow = GetTime() * 1000000;
11982 CTxDB txdb("r");
11983 while (!pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow)
11984 {
11985 const CInv& inv = (*pto->mapAskFor.begin()).second;
11986 if (!AlreadyHave(txdb, inv))
11987 {
11988 printf("sending getdata: %s\n", inv.ToString().c_str());
11989 vGetData.push_back(inv);
11990 if (vGetData.size() >= 1000)
11991 {
11992 pto->PushMessage("getdata", vGetData);
11993 vGetData.clear();
11994 }
11995 }
11996 mapAlreadyAskedFor[inv] = nNow;
11997 pto->mapAskFor.erase(pto->mapAskFor.begin());
11998 }
11999 if (!vGetData.empty())
12000 pto->PushMessage("getdata", vGetData);
12001
12002 }
12003 return true;
12004 }
12005
12006
12007
12008
12009
12010
12011
12012
12013
12014
12015
12016
12017
12018
12019 //////////////////////////////////////////////////////////////////////////////
12020 //
12021 // BitcoinMiner
12022 //
12023
12024 int static FormatHashBlocks(void* pbuffer, unsigned int len)
12025 {
12026 unsigned char* pdata = (unsigned char*)pbuffer;
12027 unsigned int blocks = 1 + ((len + 8) / 64);
12028 unsigned char* pend = pdata + 64 * blocks;
12029 memset(pdata + len, 0, 64 * blocks - len);
12030 pdata[len] = 0x80;
12031 unsigned int bits = len * 8;
12032 pend[-1] = (bits >> 0) & 0xff;
12033 pend[-2] = (bits >> 8) & 0xff;
12034 pend[-3] = (bits >> 16) & 0xff;
12035 pend[-4] = (bits >> 24) & 0xff;
12036 return blocks;
12037 }
12038
12039 static const unsigned int pSHA256InitState[8] =
12040 {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
12041
12042 void SHA256Transform(void* pstate, void* pinput, const void* pinit)
12043 {
12044 SHA256_CTX ctx;
12045 unsigned char data[64];
12046
12047 SHA256_Init(&ctx);
12048
12049 for (int i = 0; i < 16; i++)
12050 ((uint32_t*)data)[i] = ByteReverse(((uint32_t*)pinput)[i]);
12051
12052 for (int i = 0; i < 8; i++)
12053 ctx.h[i] = ((uint32_t*)pinit)[i];
12054
12055 SHA256_Update(&ctx, data, sizeof(data));
12056 for (int i = 0; i < 8; i++)
12057 ((uint32_t*)pstate)[i] = ctx.h[i];
12058 }
12059
12060 //
12061 // ScanHash scans nonces looking for a hash with at least some zero bits.
12062 // It operates on big endian data. Caller does the byte reversing.
12063 // All input buffers are 16-byte aligned. nNonce is usually preserved
12064 // between calls, but periodically or if nNonce is 0xffff0000 or above,
12065 // the block is rebuilt and nNonce starts over at zero.
12066 //
12067 unsigned int static ScanHash_CryptoPP(char* pmidstate, char* pdata, char* phash1, char* phash, unsigned int& nHashesDone)
12068 {
12069 unsigned int& nNonce = *(unsigned int*)(pdata + 12);
12070 for (;;)
12071 {
12072 // Crypto++ SHA-256
12073 // Hash pdata using pmidstate as the starting state into
12074 // preformatted buffer phash1, then hash phash1 into phash
12075 nNonce++;
12076 SHA256Transform(phash1, pdata, pmidstate);
12077 SHA256Transform(phash, phash1, pSHA256InitState);
12078
12079 // Return the nonce if the hash has at least some zero bits,
12080 // caller will check if it has enough to reach the target
12081 if (((unsigned short*)phash)[14] == 0)
12082 return nNonce;
12083
12084 // If nothing found after trying for a while, return -1
12085 if ((nNonce & 0xffff) == 0)
12086 {
12087 nHashesDone = 0xffff+1;
12088 return -1;
12089 }
12090 }
12091 }
12092
12093 // Some explaining would be appreciated
12094 class COrphan
12095 {
12096 public:
12097 CTransaction* ptx;
12098 set<uint256> setDependsOn;
12099 double dPriority;
12100
12101 COrphan(CTransaction* ptxIn)
12102 {
12103 ptx = ptxIn;
12104 dPriority = 0;
12105 }
12106
12107 void print() const
12108 {
12109 printf("COrphan(hash=%s, dPriority=%.1f)\n", ptx->GetHash().ToString().substr(0,10).c_str(), dPriority);
12110 BOOST_FOREACH(uint256 hash, setDependsOn)
12111 printf(" setDependsOn %s\n", hash.ToString().substr(0,10).c_str());
12112 }
12113 };
12114
12115
12116 CBlock* CreateNewBlock(CReserveKey& reservekey)
12117 {
12118 CBlockIndex* pindexPrev = pindexBest;
12119
12120 // Create new block
12121 auto_ptr<CBlock> pblock(new CBlock());
12122 if (!pblock.get())
12123 return NULL;
12124
12125 // Create coinbase tx
12126 CTransaction txNew;
12127 txNew.vin.resize(1);
12128 txNew.vin[0].prevout.SetNull();
12129 txNew.vout.resize(1);
12130 txNew.vout[0].scriptPubKey << reservekey.GetReservedKey() << OP_CHECKSIG;
12131
12132 // Add our coinbase tx as first transaction
12133 pblock->vtx.push_back(txNew);
12134
12135 // Collect memory pool transactions into the block
12136 int64 nFees = 0;
12137 CRITICAL_BLOCK(cs_main)
12138 CRITICAL_BLOCK(cs_mapTransactions)
12139 {
12140 CTxDB txdb("r");
12141
12142 // Priority order to process transactions
12143 list<COrphan> vOrphan; // list memory doesn't move
12144 map<uint256, vector<COrphan*> > mapDependers;
12145 multimap<double, CTransaction*> mapPriority;
12146 for (map<uint256, CTransaction>::iterator mi = mapTransactions.begin(); mi != mapTransactions.end(); ++mi)
12147 {
12148 CTransaction& tx = (*mi).second;
12149 if (tx.IsCoinBase() || !tx.IsFinal())
12150 continue;
12151
12152 COrphan* porphan = NULL;
12153 double dPriority = 0;
12154 BOOST_FOREACH(const CTxIn& txin, tx.vin)
12155 {
12156 // Read prev transaction
12157 CTransaction txPrev;
12158 CTxIndex txindex;
12159 if (!txPrev.ReadFromDisk(txdb, txin.prevout, txindex))
12160 {
12161 // Has to wait for dependencies
12162 if (!porphan)
12163 {
12164 // Use list for automatic deletion
12165 vOrphan.push_back(COrphan(&tx));
12166 porphan = &vOrphan.back();
12167 }
12168 mapDependers[txin.prevout.hash].push_back(porphan);
12169 porphan->setDependsOn.insert(txin.prevout.hash);
12170 continue;
12171 }
12172 int64 nValueIn = txPrev.vout[txin.prevout.n].nValue;
12173
12174 // Read block header
12175 int nConf = txindex.GetDepthInMainChain();
12176
12177 dPriority += (double)nValueIn * nConf;
12178
12179 if (fDebug && GetBoolArg("-printpriority"))
12180 printf("priority nValueIn=%-12I64d nConf=%-5d dPriority=%-20.1f\n", nValueIn, nConf, dPriority);
12181 }
12182
12183 // Priority is sum(valuein * age) / txsize
12184 dPriority /= ::GetSerializeSize(tx, SER_NETWORK);
12185
12186 if (porphan)
12187 porphan->dPriority = dPriority;
12188 else
12189 mapPriority.insert(make_pair(-dPriority, &(*mi).second));
12190
12191 if (fDebug && GetBoolArg("-printpriority"))
12192 {
12193 printf("priority %-20.1f %s\n%s", dPriority, tx.GetHash().ToString().substr(0,10).c_str(), tx.ToString().c_str());
12194 if (porphan)
12195 porphan->print();
12196 printf("\n");
12197 }
12198 }
12199
12200 // Collect transactions into block
12201 map<uint256, CTxIndex> mapTestPool;
12202 uint64 nBlockSize = 1000;
12203 int nBlockSigOps = 100;
12204 while (!mapPriority.empty())
12205 {
12206 // Take highest priority transaction off priority queue
12207 double dPriority = -(*mapPriority.begin()).first;
12208 CTransaction& tx = *(*mapPriority.begin()).second;
12209 mapPriority.erase(mapPriority.begin());
12210
12211 // Size limits
12212 unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK);
12213 if (nBlockSize + nTxSize >= MAX_BLOCK_SIZE_GEN)
12214 continue;
12215 int nTxSigOps = tx.GetSigOpCount();
12216 if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
12217 continue;
12218
12219 // Transaction fee required depends on block size
12220 bool fAllowFree = (nBlockSize + nTxSize < 4000 || CTransaction::AllowFree(dPriority));
12221 int64 nMinFee = tx.GetMinFee(nBlockSize, fAllowFree);
12222
12223 // Connecting shouldn't fail due to dependency on other memory pool transactions
12224 // because we're already processing them in order of dependency
12225 map<uint256, CTxIndex> mapTestPoolTmp(mapTestPool);
12226 bool fInvalid;
12227 if (!tx.ConnectInputs(txdb, mapTestPoolTmp, CDiskTxPos(1,1,1), pindexPrev, nFees, false, true, nMinFee, fInvalid))
12228 continue;
12229 swap(mapTestPool, mapTestPoolTmp);
12230
12231 // Added
12232 pblock->vtx.push_back(tx);
12233 nBlockSize += nTxSize;
12234 nBlockSigOps += nTxSigOps;
12235
12236 // Add transactions that depend on this one to the priority queue
12237 uint256 hash = tx.GetHash();
12238 if (mapDependers.count(hash))
12239 {
12240 BOOST_FOREACH(COrphan* porphan, mapDependers[hash])
12241 {
12242 if (!porphan->setDependsOn.empty())
12243 {
12244 porphan->setDependsOn.erase(hash);
12245 if (porphan->setDependsOn.empty())
12246 mapPriority.insert(make_pair(-porphan->dPriority, porphan->ptx));
12247 }
12248 }
12249 }
12250 }
12251 }
12252 pblock->vtx[0].vout[0].nValue = GetBlockValue(pindexPrev->nHeight+1, nFees);
12253
12254 // Fill in header
12255 pblock->hashPrevBlock = pindexPrev->GetBlockHash();
12256 pblock->hashMerkleRoot = pblock->BuildMerkleTree();
12257 pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
12258 pblock->nBits = GetNextWorkRequired(pindexPrev, pblock.get());
12259 pblock->nNonce = 0;
12260
12261 return pblock.release();
12262 }
12263
12264
12265 void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce)
12266 {
12267 // Update nExtraNonce
12268 static uint256 hashPrevBlock;
12269 if (hashPrevBlock != pblock->hashPrevBlock)
12270 {
12271 nExtraNonce = 0;
12272 hashPrevBlock = pblock->hashPrevBlock;
12273 }
12274 ++nExtraNonce;
12275 pblock->vtx[0].vin[0].scriptSig = CScript() << pblock->nTime << CBigNum(nExtraNonce);
12276 pblock->hashMerkleRoot = pblock->BuildMerkleTree();
12277 }
12278
12279
12280 void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1)
12281 {
12282 //
12283 // Prebuild hash buffers
12284 //
12285 struct
12286 {
12287 struct unnamed2
12288 {
12289 int nVersion;
12290 uint256 hashPrevBlock;
12291 uint256 hashMerkleRoot;
12292 unsigned int nTime;
12293 unsigned int nBits;
12294 unsigned int nNonce;
12295 }
12296 block;
12297 unsigned char pchPadding0[64];
12298 uint256 hash1;
12299 unsigned char pchPadding1[64];
12300 }
12301 tmp;
12302 memset(&tmp, 0, sizeof(tmp));
12303
12304 tmp.block.nVersion = pblock->nVersion;
12305 tmp.block.hashPrevBlock = pblock->hashPrevBlock;
12306 tmp.block.hashMerkleRoot = pblock->hashMerkleRoot;
12307 tmp.block.nTime = pblock->nTime;
12308 tmp.block.nBits = pblock->nBits;
12309 tmp.block.nNonce = pblock->nNonce;
12310
12311 FormatHashBlocks(&tmp.block, sizeof(tmp.block));
12312 FormatHashBlocks(&tmp.hash1, sizeof(tmp.hash1));
12313
12314 // Byte swap all the input buffer
12315 for (int i = 0; i < sizeof(tmp)/4; i++)
12316 ((unsigned int*)&tmp)[i] = ByteReverse(((unsigned int*)&tmp)[i]);
12317
12318 // Precalc the first half of the first hash, which stays constant
12319 SHA256Transform(pmidstate, &tmp.block, pSHA256InitState);
12320
12321 memcpy(pdata, &tmp.block, 128);
12322 memcpy(phash1, &tmp.hash1, 64);
12323 }
12324
12325
12326 bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
12327 {
12328 uint256 hash = pblock->GetHash();
12329 uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
12330
12331 if (hash > hashTarget)
12332 return false;
12333
12334 //// debug print
12335 printf("BitcoinMiner:\n");
12336 printf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str());
12337 pblock->print();
12338 printf("%s ", DateTimeStrFormat("%x %H:%M", GetTime()).c_str());
12339 printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str());
12340
12341 // Found a solution
12342 CRITICAL_BLOCK(cs_main)
12343 {
12344 if (pblock->hashPrevBlock != hashBestChain)
12345 return error("BitcoinMiner : generated block is stale");
12346
12347 // Remove key from key pool
12348 reservekey.KeepKey();
12349
12350 // Track how many getdata requests this block gets
12351 CRITICAL_BLOCK(wallet.cs_wallet)
12352 wallet.mapRequestCount[pblock->GetHash()] = 0;
12353
12354 // Process this block the same as if we had received it from another node
12355 if (!ProcessBlock(NULL, pblock))
12356 return error("BitcoinMiner : ProcessBlock, block not accepted");
12357 }
12358
12359 return true;
12360 }
12361
12362 void static ThreadBitcoinMiner(void* parg);
12363
12364 void static BitcoinMiner(CWallet *pwallet)
12365 {
12366 printf("BitcoinMiner started\n");
12367 SetThreadPriority(THREAD_PRIORITY_LOWEST);
12368
12369 // Each thread has its own key and counter
12370 CReserveKey reservekey(pwallet);
12371 unsigned int nExtraNonce = 0;
12372
12373 while (fGenerateBitcoins)
12374 {
12375 if (AffinityBugWorkaround(ThreadBitcoinMiner))
12376 return;
12377 if (fShutdown)
12378 return;
12379 while (vNodes.empty() || IsInitialBlockDownload())
12380 {
12381 Sleep(1000);
12382 if (fShutdown)
12383 return;
12384 if (!fGenerateBitcoins)
12385 return;
12386 }
12387
12388
12389 //
12390 // Create new block
12391 //
12392 unsigned int nTransactionsUpdatedLast = nTransactionsUpdated;
12393 CBlockIndex* pindexPrev = pindexBest;
12394
12395 auto_ptr<CBlock> pblock(CreateNewBlock(reservekey));
12396 if (!pblock.get())
12397 return;
12398 IncrementExtraNonce(pblock.get(), pindexPrev, nExtraNonce);
12399
12400 printf("Running BitcoinMiner with %d transactions in block\n", pblock->vtx.size());
12401
12402
12403 //
12404 // Prebuild hash buffers
12405 //
12406 char pmidstatebuf[32+16]; char* pmidstate = alignup<16>(pmidstatebuf);
12407 char pdatabuf[128+16]; char* pdata = alignup<16>(pdatabuf);
12408 char phash1buf[64+16]; char* phash1 = alignup<16>(phash1buf);
12409
12410 FormatHashBuffers(pblock.get(), pmidstate, pdata, phash1);
12411
12412 unsigned int& nBlockTime = *(unsigned int*)(pdata + 64 + 4);
12413 unsigned int& nBlockNonce = *(unsigned int*)(pdata + 64 + 12);
12414
12415
12416 //
12417 // Search
12418 //
12419 int64 nStart = GetTime();
12420 uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
12421 uint256 hashbuf[2];
12422 uint256& hash = *alignup<16>(hashbuf);
12423 loop
12424 {
12425 unsigned int nHashesDone = 0;
12426 unsigned int nNonceFound;
12427
12428 // Crypto++ SHA-256
12429 nNonceFound = ScanHash_CryptoPP(pmidstate, pdata + 64, phash1,
12430 (char*)&hash, nHashesDone);
12431
12432 // Check if something found
12433 if (nNonceFound != -1)
12434 {
12435 for (int i = 0; i < sizeof(hash)/4; i++)
12436 ((unsigned int*)&hash)[i] = ByteReverse(((unsigned int*)&hash)[i]);
12437
12438 if (hash <= hashTarget)
12439 {
12440 // Found a solution
12441 pblock->nNonce = ByteReverse(nNonceFound);
12442 assert(hash == pblock->GetHash());
12443
12444 SetThreadPriority(THREAD_PRIORITY_NORMAL);
12445 CheckWork(pblock.get(), *pwalletMain, reservekey);
12446 SetThreadPriority(THREAD_PRIORITY_LOWEST);
12447 break;
12448 }
12449 }
12450
12451 // Meter hashes/sec
12452 static int64 nHashCounter;
12453 if (nHPSTimerStart == 0)
12454 {
12455 nHPSTimerStart = GetTimeMillis();
12456 nHashCounter = 0;
12457 }
12458 else
12459 nHashCounter += nHashesDone;
12460 if (GetTimeMillis() - nHPSTimerStart > 4000)
12461 {
12462 static CCriticalSection cs;
12463 CRITICAL_BLOCK(cs)
12464 {
12465 if (GetTimeMillis() - nHPSTimerStart > 4000)
12466 {
12467 dHashesPerSec = 1000.0 * nHashCounter / (GetTimeMillis() - nHPSTimerStart);
12468 nHPSTimerStart = GetTimeMillis();
12469 nHashCounter = 0;
12470 string strStatus = strprintf(" %.0f khash/s", dHashesPerSec/1000.0);
12471 UIThreadCall(boost::bind(CalledSetStatusBar, strStatus, 0));
12472 static int64 nLogTime;
12473 if (GetTime() - nLogTime > 30 * 60)
12474 {
12475 nLogTime = GetTime();
12476 printf("%s ", DateTimeStrFormat("%x %H:%M", GetTime()).c_str());
12477 printf("hashmeter %3d CPUs %6.0f khash/s\n", vnThreadsRunning[3], dHashesPerSec/1000.0);
12478 }
12479 }
12480 }
12481 }
12482
12483 // Check for stop or if block needs to be rebuilt
12484 if (fShutdown)
12485 return;
12486 if (!fGenerateBitcoins)
12487 return;
12488 if (fLimitProcessors && vnThreadsRunning[3] > nLimitProcessors)
12489 return;
12490 if (vNodes.empty())
12491 break;
12492 if (nBlockNonce >= 0xffff0000)
12493 break;
12494 if (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60)
12495 break;
12496 if (pindexPrev != pindexBest)
12497 break;
12498
12499 // Update nTime every few seconds
12500 pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
12501 nBlockTime = ByteReverse(pblock->nTime);
12502 }
12503 }
12504 }
12505
12506 void static ThreadBitcoinMiner(void* parg)
12507 {
12508 CWallet* pwallet = (CWallet*)parg;
12509 try
12510 {
12511 vnThreadsRunning[3]++;
12512 BitcoinMiner(pwallet);
12513 vnThreadsRunning[3]--;
12514 }
12515 catch (std::exception& e) {
12516 vnThreadsRunning[3]--;
12517 PrintException(&e, "ThreadBitcoinMiner()");
12518 } catch (...) {
12519 vnThreadsRunning[3]--;
12520 PrintException(NULL, "ThreadBitcoinMiner()");
12521 }
12522 UIThreadCall(boost::bind(CalledSetStatusBar, "", 0));
12523 nHPSTimerStart = 0;
12524 if (vnThreadsRunning[3] == 0)
12525 dHashesPerSec = 0;
12526 printf("ThreadBitcoinMiner exiting, %d threads remaining\n", vnThreadsRunning[3]);
12527 }
12528
12529
12530 void GenerateBitcoins(bool fGenerate, CWallet* pwallet)
12531 {
12532 if (fGenerateBitcoins != fGenerate)
12533 {
12534 fGenerateBitcoins = fGenerate;
12535 WriteSetting("fGenerateBitcoins", fGenerateBitcoins);
12536 MainFrameRepaint();
12537 }
12538 if (fGenerateBitcoins)
12539 {
12540 int nProcessors = boost::thread::hardware_concurrency();
12541 printf("%d processors\n", nProcessors);
12542 if (nProcessors < 1)
12543 nProcessors = 1;
12544 if (fLimitProcessors && nProcessors > nLimitProcessors)
12545 nProcessors = nLimitProcessors;
12546 int nAddThreads = nProcessors - vnThreadsRunning[3];
12547 printf("Starting %d BitcoinMiner threads\n", nAddThreads);
12548 for (int i = 0; i < nAddThreads; i++)
12549 {
12550 if (!CreateThread(ThreadBitcoinMiner, pwallet))
12551 printf("Error: CreateThread(ThreadBitcoinMiner) failed\n");
12552 Sleep(10);
12553 }
12554 }
12555 }
-
+ 67B6643036F41A20FEE9D90D36EE22EEC8B153BAD6EFB2342C3AD887523385F089945FDAC74E73C5973D04AE1C748BCA15B3D7F5B9D1243B8F87A4E6BDA5F3C2
bitcoin/src/main.h
(0 . 0)(1 . 1571)
12560 // Copyright (c) 2009-2010 Satoshi Nakamoto
12561 // Copyright (c) 2009-2012 The Bitcoin developers
12562 // Distributed under the MIT/X11 software license, see the accompanying
12563 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
12564 #ifndef BITCOIN_MAIN_H
12565 #define BITCOIN_MAIN_H
12566
12567 #include "bignum.h"
12568 #include "net.h"
12569 #include "key.h"
12570 #include "script.h"
12571 #include "db.h"
12572
12573 #include <list>
12574
12575 class CBlock;
12576 class CBlockIndex;
12577 class CWalletTx;
12578 class CWallet;
12579 class CKeyItem;
12580 class CReserveKey;
12581 class CWalletDB;
12582
12583 class CAddress;
12584 class CInv;
12585 class CRequestTracker;
12586 class CNode;
12587 class CBlockIndex;
12588
12589 static const unsigned int MAX_BLOCK_SIZE = 1000000;
12590 static const unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE/2;
12591 static const int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
12592 static const int MAX_ORPHAN_TRANSACTIONS = MAX_BLOCK_SIZE/100;
12593 static const int64 COIN = 100000000;
12594 static const int64 CENT = 1000000;
12595 static const int64 MIN_TX_FEE = 50000;
12596 static const int64 MIN_RELAY_TX_FEE = 10000;
12597 static const int64 MAX_MONEY = 21000000 * COIN;
12598 inline bool MoneyRange(int64 nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); }
12599 static const int COINBASE_MATURITY = 100;
12600 // Threshold for nLockTime: below this value it is interpreted as block number, otherwise as UNIX timestamp.
12601 static const int LOCKTIME_THRESHOLD = 500000000; // Tue Nov 5 00:53:20 1985 UTC
12602 #ifdef USE_UPNP
12603 static const int fHaveUPnP = true;
12604 #else
12605 static const int fHaveUPnP = false;
12606 #endif
12607
12608
12609
12610
12611
12612
12613 extern CCriticalSection cs_main;
12614 extern std::map<uint256, CBlockIndex*> mapBlockIndex;
12615 extern uint256 hashGenesisBlock;
12616 extern CBlockIndex* pindexGenesisBlock;
12617 extern int nBestHeight;
12618 extern CBigNum bnBestChainWork;
12619 extern CBigNum bnBestInvalidWork;
12620 extern uint256 hashBestChain;
12621 extern CBlockIndex* pindexBest;
12622 extern unsigned int nTransactionsUpdated;
12623 extern double dHashesPerSec;
12624 extern int64 nHPSTimerStart;
12625 extern int64 nTimeBestReceived;
12626 extern CCriticalSection cs_setpwalletRegistered;
12627 extern std::set<CWallet*> setpwalletRegistered;
12628
12629 // Settings
12630 extern int fGenerateBitcoins;
12631 extern int64 nTransactionFee;
12632 extern int fLimitProcessors;
12633 extern int nLimitProcessors;
12634 extern int fMinimizeToTray;
12635 extern int fMinimizeOnClose;
12636 extern int fUseUPnP;
12637
12638
12639
12640
12641
12642 class CReserveKey;
12643 class CTxDB;
12644 class CTxIndex;
12645
12646 void RegisterWallet(CWallet* pwalletIn);
12647 void UnregisterWallet(CWallet* pwalletIn);
12648 bool ProcessBlock(CNode* pfrom, CBlock* pblock);
12649 bool CheckDiskSpace(uint64 nAdditionalBytes=0);
12650 FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb");
12651 FILE* AppendBlockFile(unsigned int& nFileRet);
12652 bool LoadBlockIndex(bool fAllowNew=true);
12653 void PrintBlockTree();
12654 bool ProcessMessages(CNode* pfrom);
12655 bool SendMessages(CNode* pto, bool fSendTrickle);
12656 void GenerateBitcoins(bool fGenerate, CWallet* pwallet);
12657 CBlock* CreateNewBlock(CReserveKey& reservekey);
12658 void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
12659 void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1);
12660 bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey);
12661 bool CheckProofOfWork(uint256 hash, unsigned int nBits);
12662 unsigned int ComputeMinWork(unsigned int nBase, int64 nTime);
12663 int GetNumBlocksOfPeers();
12664 bool IsInitialBlockDownload();
12665 std::string GetWarnings(std::string strFor);
12666
12667
12668
12669
12670
12671
12672
12673
12674
12675
12676
12677
12678 bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut);
12679
12680 template<typename T>
12681 bool WriteSetting(const std::string& strKey, const T& value)
12682 {
12683 bool fOk = false;
12684 BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
12685 {
12686 std::string strWalletFile;
12687 if (!GetWalletFile(pwallet, strWalletFile))
12688 continue;
12689 fOk |= CWalletDB(strWalletFile).WriteSetting(strKey, value);
12690 }
12691 return fOk;
12692 }
12693
12694
12695 class CDiskTxPos
12696 {
12697 public:
12698 unsigned int nFile;
12699 unsigned int nBlockPos;
12700 unsigned int nTxPos;
12701
12702 CDiskTxPos()
12703 {
12704 SetNull();
12705 }
12706
12707 CDiskTxPos(unsigned int nFileIn, unsigned int nBlockPosIn, unsigned int nTxPosIn)
12708 {
12709 nFile = nFileIn;
12710 nBlockPos = nBlockPosIn;
12711 nTxPos = nTxPosIn;
12712 }
12713
12714 IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); )
12715 void SetNull() { nFile = -1; nBlockPos = 0; nTxPos = 0; }
12716 bool IsNull() const { return (nFile == -1); }
12717
12718 friend bool operator==(const CDiskTxPos& a, const CDiskTxPos& b)
12719 {
12720 return (a.nFile == b.nFile &&
12721 a.nBlockPos == b.nBlockPos &&
12722 a.nTxPos == b.nTxPos);
12723 }
12724
12725 friend bool operator!=(const CDiskTxPos& a, const CDiskTxPos& b)
12726 {
12727 return !(a == b);
12728 }
12729
12730 std::string ToString() const
12731 {
12732 if (IsNull())
12733 return strprintf("null");
12734 else
12735 return strprintf("(nFile=%d, nBlockPos=%d, nTxPos=%d)", nFile, nBlockPos, nTxPos);
12736 }
12737
12738 void print() const
12739 {
12740 printf("%s", ToString().c_str());
12741 }
12742 };
12743
12744
12745
12746
12747 class CInPoint
12748 {
12749 public:
12750 CTransaction* ptx;
12751 unsigned int n;
12752
12753 CInPoint() { SetNull(); }
12754 CInPoint(CTransaction* ptxIn, unsigned int nIn) { ptx = ptxIn; n = nIn; }
12755 void SetNull() { ptx = NULL; n = -1; }
12756 bool IsNull() const { return (ptx == NULL && n == -1); }
12757 };
12758
12759
12760
12761
12762 class COutPoint
12763 {
12764 public:
12765 uint256 hash;
12766 unsigned int n;
12767
12768 COutPoint() { SetNull(); }
12769 COutPoint(uint256 hashIn, unsigned int nIn) { hash = hashIn; n = nIn; }
12770 IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); )
12771 void SetNull() { hash = 0; n = -1; }
12772 bool IsNull() const { return (hash == 0 && n == -1); }
12773
12774 friend bool operator<(const COutPoint& a, const COutPoint& b)
12775 {
12776 return (a.hash < b.hash || (a.hash == b.hash && a.n < b.n));
12777 }
12778
12779 friend bool operator==(const COutPoint& a, const COutPoint& b)
12780 {
12781 return (a.hash == b.hash && a.n == b.n);
12782 }
12783
12784 friend bool operator!=(const COutPoint& a, const COutPoint& b)
12785 {
12786 return !(a == b);
12787 }
12788
12789 std::string ToString() const
12790 {
12791 return strprintf("COutPoint(%s, %d)", hash.ToString().substr(0,10).c_str(), n);
12792 }
12793
12794 void print() const
12795 {
12796 printf("%s\n", ToString().c_str());
12797 }
12798 };
12799
12800
12801
12802
12803 //
12804 // An input of a transaction. It contains the location of the previous
12805 // transaction's output that it claims and a signature that matches the
12806 // output's public key.
12807 //
12808 class CTxIn
12809 {
12810 public:
12811 COutPoint prevout;
12812 CScript scriptSig;
12813 unsigned int nSequence;
12814
12815 CTxIn()
12816 {
12817 nSequence = UINT_MAX;
12818 }
12819
12820 explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX)
12821 {
12822 prevout = prevoutIn;
12823 scriptSig = scriptSigIn;
12824 nSequence = nSequenceIn;
12825 }
12826
12827 CTxIn(uint256 hashPrevTx, unsigned int nOut, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX)
12828 {
12829 prevout = COutPoint(hashPrevTx, nOut);
12830 scriptSig = scriptSigIn;
12831 nSequence = nSequenceIn;
12832 }
12833
12834 IMPLEMENT_SERIALIZE
12835 (
12836 READWRITE(prevout);
12837 READWRITE(scriptSig);
12838 READWRITE(nSequence);
12839 )
12840
12841 bool IsFinal() const
12842 {
12843 return (nSequence == UINT_MAX);
12844 }
12845
12846 friend bool operator==(const CTxIn& a, const CTxIn& b)
12847 {
12848 return (a.prevout == b.prevout &&
12849 a.scriptSig == b.scriptSig &&
12850 a.nSequence == b.nSequence);
12851 }
12852
12853 friend bool operator!=(const CTxIn& a, const CTxIn& b)
12854 {
12855 return !(a == b);
12856 }
12857
12858 std::string ToString() const
12859 {
12860 std::string str;
12861 str += strprintf("CTxIn(");
12862 str += prevout.ToString();
12863 if (prevout.IsNull())
12864 str += strprintf(", coinbase %s", HexStr(scriptSig).c_str());
12865 else
12866 str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24).c_str());
12867 if (nSequence != UINT_MAX)
12868 str += strprintf(", nSequence=%u", nSequence);
12869 str += ")";
12870 return str;
12871 }
12872
12873 void print() const
12874 {
12875 printf("%s\n", ToString().c_str());
12876 }
12877 };
12878
12879
12880
12881
12882 //
12883 // An output of a transaction. It contains the public key that the next input
12884 // must be able to sign with to claim it.
12885 //
12886 class CTxOut
12887 {
12888 public:
12889 int64 nValue;
12890 CScript scriptPubKey;
12891
12892 CTxOut()
12893 {
12894 SetNull();
12895 }
12896
12897 CTxOut(int64 nValueIn, CScript scriptPubKeyIn)
12898 {
12899 nValue = nValueIn;
12900 scriptPubKey = scriptPubKeyIn;
12901 }
12902
12903 IMPLEMENT_SERIALIZE
12904 (
12905 READWRITE(nValue);
12906 READWRITE(scriptPubKey);
12907 )
12908
12909 void SetNull()
12910 {
12911 nValue = -1;
12912 scriptPubKey.clear();
12913 }
12914
12915 bool IsNull()
12916 {
12917 return (nValue == -1);
12918 }
12919
12920 uint256 GetHash() const
12921 {
12922 return SerializeHash(*this);
12923 }
12924
12925 friend bool operator==(const CTxOut& a, const CTxOut& b)
12926 {
12927 return (a.nValue == b.nValue &&
12928 a.scriptPubKey == b.scriptPubKey);
12929 }
12930
12931 friend bool operator!=(const CTxOut& a, const CTxOut& b)
12932 {
12933 return !(a == b);
12934 }
12935
12936 std::string ToString() const
12937 {
12938 if (scriptPubKey.size() < 6)
12939 return "CTxOut(error)";
12940 return strprintf("CTxOut(nValue=%"PRI64d".%08"PRI64d", scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,30).c_str());
12941 }
12942
12943 void print() const
12944 {
12945 printf("%s\n", ToString().c_str());
12946 }
12947 };
12948
12949
12950
12951
12952 //
12953 // The basic transaction that is broadcasted on the network and contained in
12954 // blocks. A transaction can contain multiple inputs and outputs.
12955 //
12956 class CTransaction
12957 {
12958 public:
12959 int nVersion;
12960 std::vector<CTxIn> vin;
12961 std::vector<CTxOut> vout;
12962 unsigned int nLockTime;
12963
12964 // Denial-of-service detection:
12965 mutable int nDoS;
12966 bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; }
12967
12968 CTransaction()
12969 {
12970 SetNull();
12971 }
12972
12973 IMPLEMENT_SERIALIZE
12974 (
12975 READWRITE(this->nVersion);
12976 nVersion = this->nVersion;
12977 READWRITE(vin);
12978 READWRITE(vout);
12979 READWRITE(nLockTime);
12980 )
12981
12982 void SetNull()
12983 {
12984 nVersion = 1;
12985 vin.clear();
12986 vout.clear();
12987 nLockTime = 0;
12988 nDoS = 0; // Denial-of-service prevention
12989 }
12990
12991 bool IsNull() const
12992 {
12993 return (vin.empty() && vout.empty());
12994 }
12995
12996 uint256 GetHash() const
12997 {
12998 return SerializeHash(*this);
12999 }
13000
13001 bool IsFinal(int nBlockHeight=0, int64 nBlockTime=0) const
13002 {
13003 // Time based nLockTime implemented in 0.1.6
13004 if (nLockTime == 0)
13005 return true;
13006 if (nBlockHeight == 0)
13007 nBlockHeight = nBestHeight;
13008 if (nBlockTime == 0)
13009 nBlockTime = GetAdjustedTime();
13010 if ((int64)nLockTime < (nLockTime < LOCKTIME_THRESHOLD ? (int64)nBlockHeight : nBlockTime))
13011 return true;
13012 BOOST_FOREACH(const CTxIn& txin, vin)
13013 if (!txin.IsFinal())
13014 return false;
13015 return true;
13016 }
13017
13018 bool IsNewerThan(const CTransaction& old) const
13019 {
13020 if (vin.size() != old.vin.size())
13021 return false;
13022 for (int i = 0; i < vin.size(); i++)
13023 if (vin[i].prevout != old.vin[i].prevout)
13024 return false;
13025
13026 bool fNewer = false;
13027 unsigned int nLowest = UINT_MAX;
13028 for (int i = 0; i < vin.size(); i++)
13029 {
13030 if (vin[i].nSequence != old.vin[i].nSequence)
13031 {
13032 if (vin[i].nSequence <= nLowest)
13033 {
13034 fNewer = false;
13035 nLowest = vin[i].nSequence;
13036 }
13037 if (old.vin[i].nSequence < nLowest)
13038 {
13039 fNewer = true;
13040 nLowest = old.vin[i].nSequence;
13041 }
13042 }
13043 }
13044 return fNewer;
13045 }
13046
13047 bool IsCoinBase() const
13048 {
13049 return (vin.size() == 1 && vin[0].prevout.IsNull());
13050 }
13051
13052 int GetSigOpCount() const
13053 {
13054 int n = 0;
13055 BOOST_FOREACH(const CTxIn& txin, vin)
13056 n += txin.scriptSig.GetSigOpCount();
13057 BOOST_FOREACH(const CTxOut& txout, vout)
13058 n += txout.scriptPubKey.GetSigOpCount();
13059 return n;
13060 }
13061
13062 bool IsStandard() const
13063 {
13064 BOOST_FOREACH(const CTxIn& txin, vin)
13065 if (!txin.scriptSig.IsPushOnly())
13066 return error("nonstandard txin: %s", txin.scriptSig.ToString().c_str());
13067 BOOST_FOREACH(const CTxOut& txout, vout)
13068 if (!::IsStandard(txout.scriptPubKey))
13069 return error("nonstandard txout: %s", txout.scriptPubKey.ToString().c_str());
13070 return true;
13071 }
13072
13073 int64 GetValueOut() const
13074 {
13075 int64 nValueOut = 0;
13076 BOOST_FOREACH(const CTxOut& txout, vout)
13077 {
13078 nValueOut += txout.nValue;
13079 if (!MoneyRange(txout.nValue) || !MoneyRange(nValueOut))
13080 throw std::runtime_error("CTransaction::GetValueOut() : value out of range");
13081 }
13082 return nValueOut;
13083 }
13084
13085 static bool AllowFree(double dPriority)
13086 {
13087 // Large (in bytes) low-priority (new, small-coin) transactions
13088 // need a fee.
13089 return dPriority > COIN * 144 / 250;
13090 }
13091
13092 int64 GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=true, bool fForRelay=false) const
13093 {
13094 // Base fee is either MIN_TX_FEE or MIN_RELAY_TX_FEE
13095 int64 nBaseFee = fForRelay ? MIN_RELAY_TX_FEE : MIN_TX_FEE;
13096
13097 unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK);
13098 unsigned int nNewBlockSize = nBlockSize + nBytes;
13099 int64 nMinFee = (1 + (int64)nBytes / 1000) * nBaseFee;
13100
13101 if (fAllowFree)
13102 {
13103 if (nBlockSize == 1)
13104 {
13105 // Transactions under 10K are free
13106 // (about 4500bc if made of 50bc inputs)
13107 if (nBytes < 10000)
13108 nMinFee = 0;
13109 }
13110 else
13111 {
13112 // Free transaction area
13113 if (nNewBlockSize < 27000)
13114 nMinFee = 0;
13115 }
13116 }
13117
13118 // To limit dust spam, require MIN_TX_FEE/MIN_RELAY_TX_FEE if any output is less than 0.01
13119 if (nMinFee < nBaseFee)
13120 BOOST_FOREACH(const CTxOut& txout, vout)
13121 if (txout.nValue < CENT)
13122 nMinFee = nBaseFee;
13123
13124 // Raise the price as the block approaches full
13125 if (nBlockSize != 1 && nNewBlockSize >= MAX_BLOCK_SIZE_GEN/2)
13126 {
13127 if (nNewBlockSize >= MAX_BLOCK_SIZE_GEN)
13128 return MAX_MONEY;
13129 nMinFee *= MAX_BLOCK_SIZE_GEN / (MAX_BLOCK_SIZE_GEN - nNewBlockSize);
13130 }
13131
13132 if (!MoneyRange(nMinFee))
13133 nMinFee = MAX_MONEY;
13134 return nMinFee;
13135 }
13136
13137
13138 bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL)
13139 {
13140 CAutoFile filein = OpenBlockFile(pos.nFile, 0, pfileRet ? "rb+" : "rb");
13141 if (!filein)
13142 return error("CTransaction::ReadFromDisk() : OpenBlockFile failed");
13143
13144 // Read transaction
13145 if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)
13146 return error("CTransaction::ReadFromDisk() : fseek failed");
13147 filein >> *this;
13148
13149 // Return file pointer
13150 if (pfileRet)
13151 {
13152 if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)
13153 return error("CTransaction::ReadFromDisk() : second fseek failed");
13154 *pfileRet = filein.release();
13155 }
13156 return true;
13157 }
13158
13159 friend bool operator==(const CTransaction& a, const CTransaction& b)
13160 {
13161 return (a.nVersion == b.nVersion &&
13162 a.vin == b.vin &&
13163 a.vout == b.vout &&
13164 a.nLockTime == b.nLockTime);
13165 }
13166
13167 friend bool operator!=(const CTransaction& a, const CTransaction& b)
13168 {
13169 return !(a == b);
13170 }
13171
13172
13173 std::string ToString() const
13174 {
13175 std::string str;
13176 str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%d, vout.size=%d, nLockTime=%d)\n",
13177 GetHash().ToString().substr(0,10).c_str(),
13178 nVersion,
13179 vin.size(),
13180 vout.size(),
13181 nLockTime);
13182 for (int i = 0; i < vin.size(); i++)
13183 str += " " + vin[i].ToString() + "\n";
13184 for (int i = 0; i < vout.size(); i++)
13185 str += " " + vout[i].ToString() + "\n";
13186 return str;
13187 }
13188
13189 void print() const
13190 {
13191 printf("%s", ToString().c_str());
13192 }
13193
13194
13195 bool ReadFromDisk(CTxDB& txdb, COutPoint prevout, CTxIndex& txindexRet);
13196 bool ReadFromDisk(CTxDB& txdb, COutPoint prevout);
13197 bool ReadFromDisk(COutPoint prevout);
13198 bool DisconnectInputs(CTxDB& txdb);
13199 bool ConnectInputs(CTxDB& txdb, std::map<uint256, CTxIndex>& mapTestPool, CDiskTxPos posThisTx,
13200 CBlockIndex* pindexBlock, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee,
13201 bool& fInvalid);
13202 bool ClientConnectInputs();
13203 bool CheckTransaction() const;
13204 bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL);
13205 bool AcceptToMemoryPool(bool fCheckInputs=true, bool* pfMissingInputs=NULL);
13206 protected:
13207 bool AddToMemoryPoolUnchecked();
13208 public:
13209 bool RemoveFromMemoryPool();
13210 };
13211
13212
13213
13214
13215
13216 //
13217 // A transaction with a merkle branch linking it to the block chain
13218 //
13219 class CMerkleTx : public CTransaction
13220 {
13221 public:
13222 uint256 hashBlock;
13223 std::vector<uint256> vMerkleBranch;
13224 int nIndex;
13225
13226 // memory only
13227 mutable char fMerkleVerified;
13228
13229
13230 CMerkleTx()
13231 {
13232 Init();
13233 }
13234
13235 CMerkleTx(const CTransaction& txIn) : CTransaction(txIn)
13236 {
13237 Init();
13238 }
13239
13240 void Init()
13241 {
13242 hashBlock = 0;
13243 nIndex = -1;
13244 fMerkleVerified = false;
13245 }
13246
13247
13248 IMPLEMENT_SERIALIZE
13249 (
13250 nSerSize += SerReadWrite(s, *(CTransaction*)this, nType, nVersion, ser_action);
13251 nVersion = this->nVersion;
13252 READWRITE(hashBlock);
13253 READWRITE(vMerkleBranch);
13254 READWRITE(nIndex);
13255 )
13256
13257
13258 int SetMerkleBranch(const CBlock* pblock=NULL);
13259 int GetDepthInMainChain(int& nHeightRet) const;
13260 int GetDepthInMainChain() const { int nHeight; return GetDepthInMainChain(nHeight); }
13261 bool IsInMainChain() const { return GetDepthInMainChain() > 0; }
13262 int GetBlocksToMaturity() const;
13263 bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true);
13264 bool AcceptToMemoryPool();
13265 };
13266
13267
13268
13269
13270 //
13271 // A txdb record that contains the disk location of a transaction and the
13272 // locations of transactions that spend its outputs. vSpent is really only
13273 // used as a flag, but having the location is very helpful for debugging.
13274 //
13275 class CTxIndex
13276 {
13277 public:
13278 CDiskTxPos pos;
13279 std::vector<CDiskTxPos> vSpent;
13280
13281 CTxIndex()
13282 {
13283 SetNull();
13284 }
13285
13286 CTxIndex(const CDiskTxPos& posIn, unsigned int nOutputs)
13287 {
13288 pos = posIn;
13289 vSpent.resize(nOutputs);
13290 }
13291
13292 IMPLEMENT_SERIALIZE
13293 (
13294 if (!(nType & SER_GETHASH))
13295 READWRITE(nVersion);
13296 READWRITE(pos);
13297 READWRITE(vSpent);
13298 )
13299
13300 void SetNull()
13301 {
13302 pos.SetNull();
13303 vSpent.clear();
13304 }
13305
13306 bool IsNull()
13307 {
13308 return pos.IsNull();
13309 }
13310
13311 friend bool operator==(const CTxIndex& a, const CTxIndex& b)
13312 {
13313 return (a.pos == b.pos &&
13314 a.vSpent == b.vSpent);
13315 }
13316
13317 friend bool operator!=(const CTxIndex& a, const CTxIndex& b)
13318 {
13319 return !(a == b);
13320 }
13321 int GetDepthInMainChain() const;
13322 };
13323
13324
13325
13326
13327
13328 //
13329 // Nodes collect new transactions into a block, hash them into a hash tree,
13330 // and scan through nonce values to make the block's hash satisfy proof-of-work
13331 // requirements. When they solve the proof-of-work, they broadcast the block
13332 // to everyone and the block is added to the block chain. The first transaction
13333 // in the block is a special one that creates a new coin owned by the creator
13334 // of the block.
13335 //
13336 // Blocks are appended to blk0001.dat files on disk. Their location on disk
13337 // is indexed by CBlockIndex objects in memory.
13338 //
13339 class CBlock
13340 {
13341 public:
13342 // header
13343 int nVersion;
13344 uint256 hashPrevBlock;
13345 uint256 hashMerkleRoot;
13346 unsigned int nTime;
13347 unsigned int nBits;
13348 unsigned int nNonce;
13349
13350 // network and disk
13351 std::vector<CTransaction> vtx;
13352
13353 // memory only
13354 mutable std::vector<uint256> vMerkleTree;
13355
13356 // Denial-of-service detection:
13357 mutable int nDoS;
13358 bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; }
13359
13360 CBlock()
13361 {
13362 SetNull();
13363 }
13364
13365 IMPLEMENT_SERIALIZE
13366 (
13367 READWRITE(this->nVersion);
13368 nVersion = this->nVersion;
13369 READWRITE(hashPrevBlock);
13370 READWRITE(hashMerkleRoot);
13371 READWRITE(nTime);
13372 READWRITE(nBits);
13373 READWRITE(nNonce);
13374
13375 // ConnectBlock depends on vtx being last so it can calculate offset
13376 if (!(nType & (SER_GETHASH|SER_BLOCKHEADERONLY)))
13377 READWRITE(vtx);
13378 else if (fRead)
13379 const_cast<CBlock*>(this)->vtx.clear();
13380 )
13381
13382 void SetNull()
13383 {
13384 nVersion = 1;
13385 hashPrevBlock = 0;
13386 hashMerkleRoot = 0;
13387 nTime = 0;
13388 nBits = 0;
13389 nNonce = 0;
13390 vtx.clear();
13391 vMerkleTree.clear();
13392 nDoS = 0;
13393 }
13394
13395 bool IsNull() const
13396 {
13397 return (nBits == 0);
13398 }
13399
13400 uint256 GetHash() const
13401 {
13402 return Hash(BEGIN(nVersion), END(nNonce));
13403 }
13404
13405 int64 GetBlockTime() const
13406 {
13407 return (int64)nTime;
13408 }
13409
13410 int GetSigOpCount() const
13411 {
13412 int n = 0;
13413 BOOST_FOREACH(const CTransaction& tx, vtx)
13414 n += tx.GetSigOpCount();
13415 return n;
13416 }
13417
13418
13419 uint256 BuildMerkleTree() const
13420 {
13421 vMerkleTree.clear();
13422 BOOST_FOREACH(const CTransaction& tx, vtx)
13423 vMerkleTree.push_back(tx.GetHash());
13424 int j = 0;
13425 for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
13426 {
13427 for (int i = 0; i < nSize; i += 2)
13428 {
13429 int i2 = std::min(i+1, nSize-1);
13430 vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]), END(vMerkleTree[j+i]),
13431 BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2])));
13432 }
13433 j += nSize;
13434 }
13435 return (vMerkleTree.empty() ? 0 : vMerkleTree.back());
13436 }
13437
13438 std::vector<uint256> GetMerkleBranch(int nIndex) const
13439 {
13440 if (vMerkleTree.empty())
13441 BuildMerkleTree();
13442 std::vector<uint256> vMerkleBranch;
13443 int j = 0;
13444 for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
13445 {
13446 int i = std::min(nIndex^1, nSize-1);
13447 vMerkleBranch.push_back(vMerkleTree[j+i]);
13448 nIndex >>= 1;
13449 j += nSize;
13450 }
13451 return vMerkleBranch;
13452 }
13453
13454 static uint256 CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex)
13455 {
13456 if (nIndex == -1)
13457 return 0;
13458 BOOST_FOREACH(const uint256& otherside, vMerkleBranch)
13459 {
13460 if (nIndex & 1)
13461 hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash));
13462 else
13463 hash = Hash(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside));
13464 nIndex >>= 1;
13465 }
13466 return hash;
13467 }
13468
13469
13470 bool WriteToDisk(unsigned int& nFileRet, unsigned int& nBlockPosRet)
13471 {
13472 // Open history file to append
13473 CAutoFile fileout = AppendBlockFile(nFileRet);
13474 if (!fileout)
13475 return error("CBlock::WriteToDisk() : AppendBlockFile failed");
13476
13477 // Write index header
13478 unsigned int nSize = fileout.GetSerializeSize(*this);
13479 fileout << FLATDATA(pchMessageStart) << nSize;
13480
13481 // Write block
13482 nBlockPosRet = ftell(fileout);
13483 if (nBlockPosRet == -1)
13484 return error("CBlock::WriteToDisk() : ftell failed");
13485 fileout << *this;
13486
13487 // Flush stdio buffers and commit to disk before returning
13488 fflush(fileout);
13489 if (!IsInitialBlockDownload() || (nBestHeight+1) % 500 == 0)
13490 {
13491 #ifdef WIN32
13492 _commit(_fileno(fileout));
13493 #else
13494 fsync(fileno(fileout));
13495 #endif
13496 }
13497
13498 return true;
13499 }
13500
13501 bool ReadFromDisk(unsigned int nFile, unsigned int nBlockPos, bool fReadTransactions=true)
13502 {
13503 SetNull();
13504
13505 // Open history file to read
13506 CAutoFile filein = OpenBlockFile(nFile, nBlockPos, "rb");
13507 if (!filein)
13508 return error("CBlock::ReadFromDisk() : OpenBlockFile failed");
13509 if (!fReadTransactions)
13510 filein.nType |= SER_BLOCKHEADERONLY;
13511
13512 // Read block
13513 filein >> *this;
13514
13515 // Check the header
13516 if (!CheckProofOfWork(GetHash(), nBits))
13517 return error("CBlock::ReadFromDisk() : errors in block header");
13518
13519 return true;
13520 }
13521
13522
13523
13524 void print() const
13525 {
13526 printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%d)\n",
13527 GetHash().ToString().substr(0,20).c_str(),
13528 nVersion,
13529 hashPrevBlock.ToString().substr(0,20).c_str(),
13530 hashMerkleRoot.ToString().substr(0,10).c_str(),
13531 nTime, nBits, nNonce,
13532 vtx.size());
13533 for (int i = 0; i < vtx.size(); i++)
13534 {
13535 printf(" ");
13536 vtx[i].print();
13537 }
13538 printf(" vMerkleTree: ");
13539 for (int i = 0; i < vMerkleTree.size(); i++)
13540 printf("%s ", vMerkleTree[i].ToString().substr(0,10).c_str());
13541 printf("\n");
13542 }
13543
13544
13545 bool DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex);
13546 bool ConnectBlock(CTxDB& txdb, CBlockIndex* pindex);
13547 bool ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions=true);
13548 bool SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew);
13549 bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos);
13550 bool CheckBlock() const;
13551 bool AcceptBlock();
13552 };
13553
13554
13555
13556
13557
13558
13559 //
13560 // The block chain is a tree shaped structure starting with the
13561 // genesis block at the root, with each block potentially having multiple
13562 // candidates to be the next block. pprev and pnext link a path through the
13563 // main/longest chain. A blockindex may have multiple pprev pointing back
13564 // to it, but pnext will only point forward to the longest branch, or will
13565 // be null if the block is not part of the longest chain.
13566 //
13567 class CBlockIndex
13568 {
13569 public:
13570 const uint256* phashBlock;
13571 CBlockIndex* pprev;
13572 CBlockIndex* pnext;
13573 unsigned int nFile;
13574 unsigned int nBlockPos;
13575 int nHeight;
13576 CBigNum bnChainWork;
13577
13578 // block header
13579 int nVersion;
13580 uint256 hashMerkleRoot;
13581 unsigned int nTime;
13582 unsigned int nBits;
13583 unsigned int nNonce;
13584
13585
13586 CBlockIndex()
13587 {
13588 phashBlock = NULL;
13589 pprev = NULL;
13590 pnext = NULL;
13591 nFile = 0;
13592 nBlockPos = 0;
13593 nHeight = 0;
13594 bnChainWork = 0;
13595
13596 nVersion = 0;
13597 hashMerkleRoot = 0;
13598 nTime = 0;
13599 nBits = 0;
13600 nNonce = 0;
13601 }
13602
13603 CBlockIndex(unsigned int nFileIn, unsigned int nBlockPosIn, CBlock& block)
13604 {
13605 phashBlock = NULL;
13606 pprev = NULL;
13607 pnext = NULL;
13608 nFile = nFileIn;
13609 nBlockPos = nBlockPosIn;
13610 nHeight = 0;
13611 bnChainWork = 0;
13612
13613 nVersion = block.nVersion;
13614 hashMerkleRoot = block.hashMerkleRoot;
13615 nTime = block.nTime;
13616 nBits = block.nBits;
13617 nNonce = block.nNonce;
13618 }
13619
13620 CBlock GetBlockHeader() const
13621 {
13622 CBlock block;
13623 block.nVersion = nVersion;
13624 if (pprev)
13625 block.hashPrevBlock = pprev->GetBlockHash();
13626 block.hashMerkleRoot = hashMerkleRoot;
13627 block.nTime = nTime;
13628 block.nBits = nBits;
13629 block.nNonce = nNonce;
13630 return block;
13631 }
13632
13633 uint256 GetBlockHash() const
13634 {
13635 return *phashBlock;
13636 }
13637
13638 int64 GetBlockTime() const
13639 {
13640 return (int64)nTime;
13641 }
13642
13643 CBigNum GetBlockWork() const
13644 {
13645 CBigNum bnTarget;
13646 bnTarget.SetCompact(nBits);
13647 if (bnTarget <= 0)
13648 return 0;
13649 return (CBigNum(1)<<256) / (bnTarget+1);
13650 }
13651
13652 bool IsInMainChain() const
13653 {
13654 return (pnext || this == pindexBest);
13655 }
13656
13657 bool CheckIndex() const
13658 {
13659 return CheckProofOfWork(GetBlockHash(), nBits);
13660 }
13661
13662 bool EraseBlockFromDisk()
13663 {
13664 // Open history file
13665 CAutoFile fileout = OpenBlockFile(nFile, nBlockPos, "rb+");
13666 if (!fileout)
13667 return false;
13668
13669 // Overwrite with empty null block
13670 CBlock block;
13671 block.SetNull();
13672 fileout << block;
13673
13674 return true;
13675 }
13676
13677 enum { nMedianTimeSpan=11 };
13678
13679 int64 GetMedianTimePast() const
13680 {
13681 int64 pmedian[nMedianTimeSpan];
13682 int64* pbegin = &pmedian[nMedianTimeSpan];
13683 int64* pend = &pmedian[nMedianTimeSpan];
13684
13685 const CBlockIndex* pindex = this;
13686 for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev)
13687 *(--pbegin) = pindex->GetBlockTime();
13688
13689 std::sort(pbegin, pend);
13690 return pbegin[(pend - pbegin)/2];
13691 }
13692
13693 int64 GetMedianTime() const
13694 {
13695 const CBlockIndex* pindex = this;
13696 for (int i = 0; i < nMedianTimeSpan/2; i++)
13697 {
13698 if (!pindex->pnext)
13699 return GetBlockTime();
13700 pindex = pindex->pnext;
13701 }
13702 return pindex->GetMedianTimePast();
13703 }
13704
13705
13706
13707 std::string ToString() const
13708 {
13709 return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)",
13710 pprev, pnext, nFile, nBlockPos, nHeight,
13711 hashMerkleRoot.ToString().substr(0,10).c_str(),
13712 GetBlockHash().ToString().substr(0,20).c_str());
13713 }
13714
13715 void print() const
13716 {
13717 printf("%s\n", ToString().c_str());
13718 }
13719 };
13720
13721
13722
13723 //
13724 // Used to marshal pointers into hashes for db storage.
13725 //
13726 class CDiskBlockIndex : public CBlockIndex
13727 {
13728 public:
13729 uint256 hashPrev;
13730 uint256 hashNext;
13731
13732 CDiskBlockIndex()
13733 {
13734 hashPrev = 0;
13735 hashNext = 0;
13736 }
13737
13738 explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex)
13739 {
13740 hashPrev = (pprev ? pprev->GetBlockHash() : 0);
13741 hashNext = (pnext ? pnext->GetBlockHash() : 0);
13742 }
13743
13744 IMPLEMENT_SERIALIZE
13745 (
13746 if (!(nType & SER_GETHASH))
13747 READWRITE(nVersion);
13748
13749 READWRITE(hashNext);
13750 READWRITE(nFile);
13751 READWRITE(nBlockPos);
13752 READWRITE(nHeight);
13753
13754 // block header
13755 READWRITE(this->nVersion);
13756 READWRITE(hashPrev);
13757 READWRITE(hashMerkleRoot);
13758 READWRITE(nTime);
13759 READWRITE(nBits);
13760 READWRITE(nNonce);
13761 )
13762
13763 uint256 GetBlockHash() const
13764 {
13765 CBlock block;
13766 block.nVersion = nVersion;
13767 block.hashPrevBlock = hashPrev;
13768 block.hashMerkleRoot = hashMerkleRoot;
13769 block.nTime = nTime;
13770 block.nBits = nBits;
13771 block.nNonce = nNonce;
13772 return block.GetHash();
13773 }
13774
13775
13776 std::string ToString() const
13777 {
13778 std::string str = "CDiskBlockIndex(";
13779 str += CBlockIndex::ToString();
13780 str += strprintf("\n hashBlock=%s, hashPrev=%s, hashNext=%s)",
13781 GetBlockHash().ToString().c_str(),
13782 hashPrev.ToString().substr(0,20).c_str(),
13783 hashNext.ToString().substr(0,20).c_str());
13784 return str;
13785 }
13786
13787 void print() const
13788 {
13789 printf("%s\n", ToString().c_str());
13790 }
13791 };
13792
13793
13794
13795
13796
13797
13798
13799
13800 //
13801 // Describes a place in the block chain to another node such that if the
13802 // other node doesn't have the same branch, it can find a recent common trunk.
13803 // The further back it is, the further before the fork it may be.
13804 //
13805 class CBlockLocator
13806 {
13807 protected:
13808 std::vector<uint256> vHave;
13809 public:
13810
13811 CBlockLocator()
13812 {
13813 }
13814
13815 explicit CBlockLocator(const CBlockIndex* pindex)
13816 {
13817 Set(pindex);
13818 }
13819
13820 explicit CBlockLocator(uint256 hashBlock)
13821 {
13822 std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
13823 if (mi != mapBlockIndex.end())
13824 Set((*mi).second);
13825 }
13826
13827 IMPLEMENT_SERIALIZE
13828 (
13829 if (!(nType & SER_GETHASH))
13830 READWRITE(nVersion);
13831 READWRITE(vHave);
13832 )
13833
13834 void SetNull()
13835 {
13836 vHave.clear();
13837 }
13838
13839 bool IsNull()
13840 {
13841 return vHave.empty();
13842 }
13843
13844 void Set(const CBlockIndex* pindex)
13845 {
13846 vHave.clear();
13847 int nStep = 1;
13848 while (pindex)
13849 {
13850 vHave.push_back(pindex->GetBlockHash());
13851
13852 // Exponentially larger steps back
13853 for (int i = 0; pindex && i < nStep; i++)
13854 pindex = pindex->pprev;
13855 if (vHave.size() > 10)
13856 nStep *= 2;
13857 }
13858 vHave.push_back(hashGenesisBlock);
13859 }
13860
13861 int GetDistanceBack()
13862 {
13863 // Retrace how far back it was in the sender's branch
13864 int nDistance = 0;
13865 int nStep = 1;
13866 BOOST_FOREACH(const uint256& hash, vHave)
13867 {
13868 std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
13869 if (mi != mapBlockIndex.end())
13870 {
13871 CBlockIndex* pindex = (*mi).second;
13872 if (pindex->IsInMainChain())
13873 return nDistance;
13874 }
13875 nDistance += nStep;
13876 if (nDistance > 10)
13877 nStep *= 2;
13878 }
13879 return nDistance;
13880 }
13881
13882 CBlockIndex* GetBlockIndex()
13883 {
13884 // Find the first block the caller has in the main chain
13885 BOOST_FOREACH(const uint256& hash, vHave)
13886 {
13887 std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
13888 if (mi != mapBlockIndex.end())
13889 {
13890 CBlockIndex* pindex = (*mi).second;
13891 if (pindex->IsInMainChain())
13892 return pindex;
13893 }
13894 }
13895 return pindexGenesisBlock;
13896 }
13897
13898 uint256 GetBlockHash()
13899 {
13900 // Find the first block the caller has in the main chain
13901 BOOST_FOREACH(const uint256& hash, vHave)
13902 {
13903 std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
13904 if (mi != mapBlockIndex.end())
13905 {
13906 CBlockIndex* pindex = (*mi).second;
13907 if (pindex->IsInMainChain())
13908 return hash;
13909 }
13910 }
13911 return hashGenesisBlock;
13912 }
13913
13914 int GetHeight()
13915 {
13916 CBlockIndex* pindex = GetBlockIndex();
13917 if (!pindex)
13918 return 0;
13919 return pindex->nHeight;
13920 }
13921 };
13922
13923
13924
13925
13926
13927
13928
13929
13930
13931 //
13932 // Alerts are for notifying old versions if they become too obsolete and
13933 // need to upgrade. The message is displayed in the status bar.
13934 // Alert messages are broadcast as a vector of signed data. Unserializing may
13935 // not read the entire buffer if the alert is for a newer version, but older
13936 // versions can still relay the original data.
13937 //
13938 class CUnsignedAlert
13939 {
13940 public:
13941 int nVersion;
13942 int64 nRelayUntil; // when newer nodes stop relaying to newer nodes
13943 int64 nExpiration;
13944 int nID;
13945 int nCancel;
13946 std::set<int> setCancel;
13947 int nMinVer; // lowest version inclusive
13948 int nMaxVer; // highest version inclusive
13949 std::set<std::string> setSubVer; // empty matches all
13950 int nPriority;
13951
13952 // Actions
13953 std::string strComment;
13954 std::string strStatusBar;
13955 std::string strReserved;
13956
13957 IMPLEMENT_SERIALIZE
13958 (
13959 READWRITE(this->nVersion);
13960 nVersion = this->nVersion;
13961 READWRITE(nRelayUntil);
13962 READWRITE(nExpiration);
13963 READWRITE(nID);
13964 READWRITE(nCancel);
13965 READWRITE(setCancel);
13966 READWRITE(nMinVer);
13967 READWRITE(nMaxVer);
13968 READWRITE(setSubVer);
13969 READWRITE(nPriority);
13970
13971 READWRITE(strComment);
13972 READWRITE(strStatusBar);
13973 READWRITE(strReserved);
13974 )
13975
13976 void SetNull()
13977 {
13978 nVersion = 1;
13979 nRelayUntil = 0;
13980 nExpiration = 0;
13981 nID = 0;
13982 nCancel = 0;
13983 setCancel.clear();
13984 nMinVer = 0;
13985 nMaxVer = 0;
13986 setSubVer.clear();
13987 nPriority = 0;
13988
13989 strComment.clear();
13990 strStatusBar.clear();
13991 strReserved.clear();
13992 }
13993
13994 std::string ToString() const
13995 {
13996 std::string strSetCancel;
13997 BOOST_FOREACH(int n, setCancel)
13998 strSetCancel += strprintf("%d ", n);
13999 std::string strSetSubVer;
14000 BOOST_FOREACH(std::string str, setSubVer)
14001 strSetSubVer += "\"" + str + "\" ";
14002 return strprintf(
14003 "CAlert(\n"
14004 " nVersion = %d\n"
14005 " nRelayUntil = %"PRI64d"\n"
14006 " nExpiration = %"PRI64d"\n"
14007 " nID = %d\n"
14008 " nCancel = %d\n"
14009 " setCancel = %s\n"
14010 " nMinVer = %d\n"
14011 " nMaxVer = %d\n"
14012 " setSubVer = %s\n"
14013 " nPriority = %d\n"
14014 " strComment = \"%s\"\n"
14015 " strStatusBar = \"%s\"\n"
14016 ")\n",
14017 nVersion,
14018 nRelayUntil,
14019 nExpiration,
14020 nID,
14021 nCancel,
14022 strSetCancel.c_str(),
14023 nMinVer,
14024 nMaxVer,
14025 strSetSubVer.c_str(),
14026 nPriority,
14027 strComment.c_str(),
14028 strStatusBar.c_str());
14029 }
14030
14031 void print() const
14032 {
14033 printf("%s", ToString().c_str());
14034 }
14035 };
14036
14037 class CAlert : public CUnsignedAlert
14038 {
14039 public:
14040 std::vector<unsigned char> vchMsg;
14041 std::vector<unsigned char> vchSig;
14042
14043 CAlert()
14044 {
14045 SetNull();
14046 }
14047
14048 IMPLEMENT_SERIALIZE
14049 (
14050 READWRITE(vchMsg);
14051 READWRITE(vchSig);
14052 )
14053
14054 void SetNull()
14055 {
14056 CUnsignedAlert::SetNull();
14057 vchMsg.clear();
14058 vchSig.clear();
14059 }
14060
14061 bool IsNull() const
14062 {
14063 return (nExpiration == 0);
14064 }
14065
14066 uint256 GetHash() const
14067 {
14068 return SerializeHash(*this);
14069 }
14070
14071 bool IsInEffect() const
14072 {
14073 return (GetAdjustedTime() < nExpiration);
14074 }
14075
14076 bool Cancels(const CAlert& alert) const
14077 {
14078 if (!IsInEffect())
14079 return false; // this was a no-op before 31403
14080 return (alert.nID <= nCancel || setCancel.count(alert.nID));
14081 }
14082
14083 bool AppliesTo(int nVersion, std::string strSubVerIn) const
14084 {
14085 return (IsInEffect() &&
14086 nMinVer <= nVersion && nVersion <= nMaxVer &&
14087 (setSubVer.empty() || setSubVer.count(strSubVerIn)));
14088 }
14089
14090 bool AppliesToMe() const
14091 {
14092 return AppliesTo(VERSION, ::pszSubVer);
14093 }
14094
14095 bool RelayTo(CNode* pnode) const
14096 {
14097 if (!IsInEffect())
14098 return false;
14099 // returns true if wasn't already contained in the set
14100 if (pnode->setKnown.insert(GetHash()).second)
14101 {
14102 if (AppliesTo(pnode->nVersion, pnode->strSubVer) ||
14103 AppliesToMe() ||
14104 GetAdjustedTime() < nRelayUntil)
14105 {
14106 pnode->PushMessage("alert", *this);
14107 return true;
14108 }
14109 }
14110 return false;
14111 }
14112
14113 bool CheckSignature()
14114 {
14115 CKey key;
14116 if (!key.SetPubKey(ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284")))
14117 return error("CAlert::CheckSignature() : SetPubKey failed");
14118 if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig))
14119 return error("CAlert::CheckSignature() : verify signature failed");
14120
14121 // Now unserialize the data
14122 CDataStream sMsg(vchMsg);
14123 sMsg >> *(CUnsignedAlert*)this;
14124 return true;
14125 }
14126
14127 bool ProcessAlert();
14128 };
14129
14130 #endif
-
+ 4B7074D3A08D375347F9534DFB9D5A623E443A04E68A739CA780A569E5B5E91B0EB2C683233A72ACAB8AF08825C29EB731270E065BF37F4D487251ABDF15AD78
bitcoin/src/makefile.linux-mingw
(0 . 0)(1 . 102)
14135 # Copyright (c) 2009-2010 Satoshi Nakamoto
14136 # Distributed under the MIT/X11 software license, see the accompanying
14137 # file license.txt or http://www.opensource.org/licenses/mit-license.php.
14138
14139 DEPSDIR:=/usr/i586-mingw32msvc
14140
14141 USE_UPNP:=0
14142
14143 INCLUDEPATHS= \
14144 -I"$(DEPSDIR)/boost_1_47_0" \
14145 -I"$(DEPSDIR)/db-4.8.30.NC/build_unix" \
14146 -I"$(DEPSDIR)/openssl-1.0.0e/include" \
14147 -I"$(DEPSDIR)"
14148
14149 LIBPATHS= \
14150 -L"$(DEPSDIR)/boost_1_47_0/stage/lib" \
14151 -L"$(DEPSDIR)/db-4.8.30.NC/build_unix" \
14152 -L"$(DEPSDIR)/openssl-1.0.0e"
14153
14154 LIBS= \
14155 -l boost_system-mt-s \
14156 -l boost_filesystem-mt-s \
14157 -l boost_program_options-mt-s \
14158 -l boost_thread_win32-mt-s \
14159 -l db_cxx \
14160 -l ssl \
14161 -l crypto
14162
14163 DEFS=-D_MT -DWIN32 -D_WINDOWS -DNOPCH -DUSE_SSL -DBOOST_THREAD_USE_LIB
14164 DEBUGFLAGS=-g
14165 CFLAGS=-O2 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
14166 HEADERS = \
14167 base58.h \
14168 bignum.h \
14169 checkpoints.h \
14170 crypter.h \
14171 db.h \
14172 headers.h \
14173 init.h \
14174 irc.h \
14175 key.h \
14176 keystore.h \
14177 main.h \
14178 net.h \
14179 noui.h \
14180 protocol.h \
14181 bitcoinrpc.h \
14182 script.h \
14183 serialize.h \
14184 strlcpy.h \
14185 uint256.h \
14186 util.h \
14187 wallet.h
14188
14189
14190 ifdef USE_UPNP
14191 LIBPATHS += -L"$(DEPSDIR)/miniupnpc"
14192 LIBS += -l miniupnpc -l iphlpapi
14193 DEFS += -DSTATICLIB -DUSE_UPNP=$(USE_UPNP)
14194 endif
14195
14196 LIBS += -l mingwthrd -l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32 -l shlwapi
14197
14198 OBJS= \
14199 obj/checkpoints.o \
14200 obj/crypter.o \
14201 obj/db.o \
14202 obj/init.o \
14203 obj/irc.o \
14204 obj/keystore.o \
14205 obj/main.o \
14206 obj/net.o \
14207 obj/protocol.o \
14208 obj/bitcoinrpc.o \
14209 obj/script.o \
14210 obj/util.o \
14211 obj/wallet.o
14212
14213 all: bitcoind.exe
14214
14215 obj/nogui/%.o: %.cpp $(HEADERS)
14216 i586-mingw32msvc-g++ -c $(CFLAGS) -o $@ $<
14217
14218 bitcoind.exe: $(OBJS:obj/%=obj/nogui/%)
14219 i586-mingw32msvc-g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS)
14220
14221
14222 obj/test/%.o: obj/test/%.cpp $(HEADERS)
14223 i586-mingw32msvc-g++ -c $(CFLAGS) -o $@ $<
14224
14225 test_bitcoin.exe: obj/test/test_bitcoin.o $(filter-out obj/nogui/init.o,$(OBJS:obj/%=obj/nogui/%))
14226 i586-mingw32msvc-g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) -lboost_unit_test_framework-mt-s
14227
14228
14229 clean:
14230 -rm -f obj/*.o
14231 -rm -f obj/nogui/*.o
14232 -rm -f obj/test/*.o
14233 -rm -f test/*.o
14234 -rm -f headers.h.gch
14235 -rm -f bitcoind.exe
14236 -rm -f test_bitcoin.exe
-
+ DB27FA66049B17C4C68621529AD41DE8973051762F0A0A96DD87FD9C7D7801FEFB338342CE262124A0623EE319BF05CB3E25B5EB0CB50E27A918409EF90CA96A
bitcoin/src/makefile.unix
(0 . 0)(1 . 161)
14241 # Copyright (c) 2009-2010 Satoshi Nakamoto
14242 # Distributed under the MIT/X11 software license, see the accompanying
14243 # file license.txt or http://www.opensource.org/licenses/mit-license.php.
14244
14245 USE_UPNP:=0
14246
14247 DEFS=-DNOPCH
14248
14249 DEFS += $(addprefix -I,$(BOOST_INCLUDE_PATH) $(BDB_INCLUDE_PATH) $(OPENSSL_INCLUDE_PATH))
14250 LIBS = $(addprefix -L,$(BOOST_LIB_PATH) $(BDB_LIB_PATH) $(OPENSSL_LIB_PATH))
14251
14252 LMODE = dynamic
14253 LMODE2 = dynamic
14254 ifdef STATIC
14255 LMODE = static
14256 ifeq (${STATIC}, all)
14257 LMODE2 = static
14258 endif
14259 else
14260 TESTDEFS += -DBOOST_TEST_DYN_LINK
14261 endif
14262
14263 # for boost 1.37, add -mt to the boost libraries
14264 LIBS += \
14265 -Wl,-B$(LMODE) \
14266 -l boost_system$(BOOST_LIB_SUFFIX) \
14267 -l boost_filesystem$(BOOST_LIB_SUFFIX) \
14268 -l boost_program_options$(BOOST_LIB_SUFFIX) \
14269 -l boost_thread$(BOOST_LIB_SUFFIX) \
14270 -l db_cxx$(BDB_LIB_SUFFIX) \
14271 -l ssl \
14272 -l crypto
14273
14274 ifndef USE_UPNP
14275 override USE_UPNP = -
14276 endif
14277 ifneq (${USE_UPNP}, -)
14278 LIBS += -l miniupnpc
14279 DEFS += -DUSE_UPNP=$(USE_UPNP)
14280 endif
14281
14282 ifneq (${USE_SSL}, 0)
14283 DEFS += -DUSE_SSL
14284 endif
14285
14286 LIBS+= \
14287 -Wl,-B$(LMODE2) \
14288 -l z \
14289 -l dl \
14290 -l pthread
14291
14292
14293 # Hardening
14294 # Make some classes of vulnerabilities unexploitable in case one is discovered.
14295 #
14296 # This is a workaround for Ubuntu bug #691722, the default -fstack-protector causes
14297 # -fstack-protector-all to be ignored unless -fno-stack-protector is used first.
14298 # see: https://bugs.launchpad.net/ubuntu/+source/gcc-4.5/+bug/691722
14299 HARDENING=-fno-stack-protector
14300
14301 # Stack Canaries
14302 # Put numbers at the beginning of each stack frame and check that they are the same.
14303 # If a stack buffer if overflowed, it writes over the canary number and then on return
14304 # when that number is checked, it won't be the same and the program will exit with
14305 # a "Stack smashing detected" error instead of being exploited.
14306 HARDENING+=-fstack-protector-all -Wstack-protector
14307
14308 # Make some important things such as the global offset table read only as soon as
14309 # the dynamic linker is finished building it. This will prevent overwriting of addresses
14310 # which would later be jumped to.
14311 HARDENING+=-Wl,-z,relro -Wl,-z,now
14312
14313 # Build position independent code to take advantage of Address Space Layout Randomization
14314 # offered by some kernels.
14315 # see doc/build-unix.txt for more information.
14316 ifdef PIE
14317 HARDENING+=-fPIE -pie
14318 endif
14319
14320 # -D_FORTIFY_SOURCE=2 does some checking for potentially exploitable code patterns in
14321 # the source such overflowing a statically defined buffer.
14322 HARDENING+=-D_FORTIFY_SOURCE=2
14323 #
14324
14325
14326 DEBUGFLAGS=-g
14327 CXXFLAGS=-O2
14328 xCXXFLAGS=-pthread -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(HARDENING) $(CXXFLAGS)
14329 HEADERS = \
14330 base58.h \
14331 bignum.h \
14332 checkpoints.h \
14333 crypter.h \
14334 db.h \
14335 headers.h \
14336 init.h \
14337 irc.h \
14338 key.h \
14339 keystore.h \
14340 main.h \
14341 net.h \
14342 noui.h \
14343 protocol.h \
14344 bitcoinrpc.h \
14345 script.h \
14346 serialize.h \
14347 strlcpy.h \
14348 uint256.h \
14349 util.h \
14350 wallet.h
14351
14352 OBJS= \
14353 obj/checkpoints.o \
14354 obj/crypter.o \
14355 obj/db.o \
14356 obj/init.o \
14357 obj/irc.o \
14358 obj/keystore.o \
14359 obj/main.o \
14360 obj/net.o \
14361 obj/protocol.o \
14362 obj/bitcoinrpc.o \
14363 obj/script.o \
14364 obj/util.o \
14365 obj/wallet.o
14366
14367
14368 all: bitcoind
14369
14370 # auto-generated dependencies:
14371 -include obj/nogui/*.P
14372 -include obj-test/*.P
14373
14374 obj/nogui/%.o: %.cpp
14375 $(CXX) -c $(xCXXFLAGS) -MMD -o $@ $<
14376 @cp $(@:%.o=%.d) $(@:%.o=%.P); \
14377 sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
14378 -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \
14379 rm -f $(@:%.o=%.d)
14380
14381 bitcoind: $(OBJS:obj/%=obj/nogui/%)
14382 $(CXX) $(xCXXFLAGS) -o $@ $^ $(LDFLAGS) $(LIBS)
14383
14384 obj-test/%.o: test/%.cpp
14385 $(CXX) -c $(TESTDEFS) $(xCXXFLAGS) -MMD -o $@ $<
14386 @cp $(@:%.o=%.d) $(@:%.o=%.P); \
14387 sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
14388 -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \
14389 rm -f $(@:%.o=%.d)
14390
14391 test_bitcoin: obj-test/test_bitcoin.o $(filter-out obj/nogui/init.o,$(OBJS:obj/%=obj/nogui/%))
14392 $(CXX) $(xCXXFLAGS) -o $@ $(LIBPATHS) $^ -Wl,-B$(LMODE) -lboost_unit_test_framework $(LDFLAGS) $(LIBS)
14393
14394 clean:
14395 -rm -f bitcoind test_bitcoin
14396 -rm -f obj/*.o
14397 -rm -f obj/nogui/*.o
14398 -rm -f obj-test/*.o
14399 -rm -f obj/*.P
14400 -rm -f obj/nogui/*.P
14401 -rm -f obj-test/*.P
-
+ E76F8111F2C74A992113F6B9691407F6F14E2D37920516727EDF7F78FDAF7A4E4D42C3378B46C0B5EAB7F45DE7E375ACDEB6AFB9C33725E7081760D15338E281
bitcoin/src/net.cpp
(0 . 0)(1 . 1951)
14406 // Copyright (c) 2009-2010 Satoshi Nakamoto
14407 // Copyright (c) 2009-2012 The Bitcoin developers
14408 // Distributed under the MIT/X11 software license, see the accompanying
14409 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
14410
14411 #include "headers.h"
14412 #include "irc.h"
14413 #include "db.h"
14414 #include "net.h"
14415 #include "init.h"
14416 #include "strlcpy.h"
14417
14418 #ifdef WIN32
14419 #include <string.h>
14420 #endif
14421
14422 #ifdef USE_UPNP
14423 #include <miniupnpc/miniwget.h>
14424 #include <miniupnpc/miniupnpc.h>
14425 #include <miniupnpc/upnpcommands.h>
14426 #include <miniupnpc/upnperrors.h>
14427 #endif
14428
14429 using namespace std;
14430 using namespace boost;
14431
14432 static const int MAX_OUTBOUND_CONNECTIONS = 8;
14433
14434 void ThreadMessageHandler2(void* parg);
14435 void ThreadSocketHandler2(void* parg);
14436 void ThreadOpenConnections2(void* parg);
14437 #ifdef USE_UPNP
14438 void ThreadMapPort2(void* parg);
14439 #endif
14440 void ThreadDNSAddressSeed2(void* parg);
14441 bool OpenNetworkConnection(const CAddress& addrConnect);
14442
14443
14444
14445
14446
14447 //
14448 // Global state variables
14449 //
14450 bool fClient = false;
14451 bool fAllowDNS = false;
14452 uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
14453 CAddress addrLocalHost("0.0.0.0", 0, false, nLocalServices);
14454 static CNode* pnodeLocalHost = NULL;
14455 uint64 nLocalHostNonce = 0;
14456 array<int, 10> vnThreadsRunning;
14457 static SOCKET hListenSocket = INVALID_SOCKET;
14458
14459 vector<CNode*> vNodes;
14460 CCriticalSection cs_vNodes;
14461 map<vector<unsigned char>, CAddress> mapAddresses;
14462 CCriticalSection cs_mapAddresses;
14463 map<CInv, CDataStream> mapRelay;
14464 deque<pair<int64, CInv> > vRelayExpiration;
14465 CCriticalSection cs_mapRelay;
14466 map<CInv, int64> mapAlreadyAskedFor;
14467
14468 // Settings
14469 int fUseProxy = false;
14470 int nConnectTimeout = 5000;
14471 CAddress addrProxy("127.0.0.1",9050);
14472
14473
14474
14475
14476 unsigned short GetListenPort()
14477 {
14478 return (unsigned short)(GetArg("-port", GetDefaultPort()));
14479 }
14480
14481 void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
14482 {
14483 // Filter out duplicate requests
14484 if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
14485 return;
14486 pindexLastGetBlocksBegin = pindexBegin;
14487 hashLastGetBlocksEnd = hashEnd;
14488
14489 PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
14490 }
14491
14492
14493
14494
14495
14496 bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet, int nTimeout)
14497 {
14498 hSocketRet = INVALID_SOCKET;
14499
14500 SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
14501 if (hSocket == INVALID_SOCKET)
14502 return false;
14503 #ifdef SO_NOSIGPIPE
14504 int set = 1;
14505 setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
14506 #endif
14507
14508 bool fProxy = (fUseProxy && addrConnect.IsRoutable());
14509 struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr());
14510
14511 #ifdef WIN32
14512 u_long fNonblock = 1;
14513 if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
14514 #else
14515 int fFlags = fcntl(hSocket, F_GETFL, 0);
14516 if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == -1)
14517 #endif
14518 {
14519 closesocket(hSocket);
14520 return false;
14521 }
14522
14523
14524 if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
14525 {
14526 // WSAEINVAL is here because some legacy version of winsock uses it
14527 if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINVAL)
14528 {
14529 struct timeval timeout;
14530 timeout.tv_sec = nTimeout / 1000;
14531 timeout.tv_usec = (nTimeout % 1000) * 1000;
14532
14533 fd_set fdset;
14534 FD_ZERO(&fdset);
14535 FD_SET(hSocket, &fdset);
14536 int nRet = select(hSocket + 1, NULL, &fdset, NULL, &timeout);
14537 if (nRet == 0)
14538 {
14539 printf("connection timeout\n");
14540 closesocket(hSocket);
14541 return false;
14542 }
14543 if (nRet == SOCKET_ERROR)
14544 {
14545 printf("select() for connection failed: %i\n",WSAGetLastError());
14546 closesocket(hSocket);
14547 return false;
14548 }
14549 socklen_t nRetSize = sizeof(nRet);
14550 #ifdef WIN32
14551 if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, (char*)(&nRet), &nRetSize) == SOCKET_ERROR)
14552 #else
14553 if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR)
14554 #endif
14555 {
14556 printf("getsockopt() for connection failed: %i\n",WSAGetLastError());
14557 closesocket(hSocket);
14558 return false;
14559 }
14560 if (nRet != 0)
14561 {
14562 printf("connect() failed after select(): %s\n",strerror(nRet));
14563 closesocket(hSocket);
14564 return false;
14565 }
14566 }
14567 #ifdef WIN32
14568 else if (WSAGetLastError() != WSAEISCONN)
14569 #else
14570 else
14571 #endif
14572 {
14573 printf("connect() failed: %i\n",WSAGetLastError());
14574 closesocket(hSocket);
14575 return false;
14576 }
14577 }
14578
14579 /*
14580 this isn't even strictly necessary
14581 CNode::ConnectNode immediately turns the socket back to non-blocking
14582 but we'll turn it back to blocking just in case
14583 */
14584 #ifdef WIN32
14585 fNonblock = 0;
14586 if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
14587 #else
14588 fFlags = fcntl(hSocket, F_GETFL, 0);
14589 if (fcntl(hSocket, F_SETFL, fFlags & !O_NONBLOCK) == SOCKET_ERROR)
14590 #endif
14591 {
14592 closesocket(hSocket);
14593 return false;
14594 }
14595
14596 if (fProxy)
14597 {
14598 printf("proxy connecting %s\n", addrConnect.ToString().c_str());
14599 char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
14600 memcpy(pszSocks4IP + 2, &addrConnect.port, 2);
14601 memcpy(pszSocks4IP + 4, &addrConnect.ip, 4);
14602 char* pszSocks4 = pszSocks4IP;
14603 int nSize = sizeof(pszSocks4IP);
14604
14605 int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL);
14606 if (ret != nSize)
14607 {
14608 closesocket(hSocket);
14609 return error("Error sending to proxy");
14610 }
14611 char pchRet[8];
14612 if (recv(hSocket, pchRet, 8, 0) != 8)
14613 {
14614 closesocket(hSocket);
14615 return error("Error reading proxy response");
14616 }
14617 if (pchRet[1] != 0x5a)
14618 {
14619 closesocket(hSocket);
14620 if (pchRet[1] != 0x5b)
14621 printf("ERROR: Proxy returned error %d\n", pchRet[1]);
14622 return false;
14623 }
14624 printf("proxy connected %s\n", addrConnect.ToString().c_str());
14625 }
14626
14627 hSocketRet = hSocket;
14628 return true;
14629 }
14630
14631 // portDefault is in host order
14632 bool Lookup(const char *pszName, vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup, int portDefault, bool fAllowPort)
14633 {
14634 vaddr.clear();
14635 if (pszName[0] == 0)
14636 return false;
14637 int port = portDefault;
14638 char psz[256];
14639 char *pszHost = psz;
14640 strlcpy(psz, pszName, sizeof(psz));
14641 if (fAllowPort)
14642 {
14643 char* pszColon = strrchr(psz+1,':');
14644 char *pszPortEnd = NULL;
14645 int portParsed = pszColon ? strtoul(pszColon+1, &pszPortEnd, 10) : 0;
14646 if (pszColon && pszPortEnd && pszPortEnd[0] == 0)
14647 {
14648 if (psz[0] == '[' && pszColon[-1] == ']')
14649 {
14650 // Future: enable IPv6 colon-notation inside []
14651 pszHost = psz+1;
14652 pszColon[-1] = 0;
14653 }
14654 else
14655 pszColon[0] = 0;
14656 port = portParsed;
14657 if (port < 0 || port > USHRT_MAX)
14658 port = USHRT_MAX;
14659 }
14660 }
14661
14662 unsigned int addrIP = inet_addr(pszHost);
14663 if (addrIP != INADDR_NONE)
14664 {
14665 // valid IP address passed
14666 vaddr.push_back(CAddress(addrIP, port, nServices));
14667 return true;
14668 }
14669
14670 if (!fAllowLookup)
14671 return false;
14672
14673 struct hostent* phostent = gethostbyname(pszHost);
14674 if (!phostent)
14675 return false;
14676
14677 if (phostent->h_addrtype != AF_INET)
14678 return false;
14679
14680 char** ppAddr = phostent->h_addr_list;
14681 while (*ppAddr != NULL && vaddr.size() != nMaxSolutions)
14682 {
14683 CAddress addr(((struct in_addr*)ppAddr[0])->s_addr, port, nServices);
14684 if (addr.IsValid())
14685 vaddr.push_back(addr);
14686 ppAddr++;
14687 }
14688
14689 return (vaddr.size() > 0);
14690 }
14691
14692 // portDefault is in host order
14693 bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup, int portDefault, bool fAllowPort)
14694 {
14695 vector<CAddress> vaddr;
14696 bool fRet = Lookup(pszName, vaddr, nServices, 1, fAllowLookup, portDefault, fAllowPort);
14697 if (fRet)
14698 addr = vaddr[0];
14699 return fRet;
14700 }
14701
14702 bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const char* pszKeyword, unsigned int& ipRet)
14703 {
14704 SOCKET hSocket;
14705 if (!ConnectSocket(addrConnect, hSocket))
14706 return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
14707
14708 send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
14709
14710 string strLine;
14711 while (RecvLine(hSocket, strLine))
14712 {
14713 if (strLine.empty()) // HTTP response is separated from headers by blank line
14714 {
14715 loop
14716 {
14717 if (!RecvLine(hSocket, strLine))
14718 {
14719 closesocket(hSocket);
14720 return false;
14721 }
14722 if (pszKeyword == NULL)
14723 break;
14724 if (strLine.find(pszKeyword) != -1)
14725 {
14726 strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
14727 break;
14728 }
14729 }
14730 closesocket(hSocket);
14731 if (strLine.find("<") != -1)
14732 strLine = strLine.substr(0, strLine.find("<"));
14733 strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
14734 while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
14735 strLine.resize(strLine.size()-1);
14736 CAddress addr(strLine,0,true);
14737 printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
14738 if (addr.ip == 0 || addr.ip == INADDR_NONE || !addr.IsRoutable())
14739 return false;
14740 ipRet = addr.ip;
14741 return true;
14742 }
14743 }
14744 closesocket(hSocket);
14745 return error("GetMyExternalIP() : connection closed");
14746 }
14747
14748 // We now get our external IP from the IRC server first and only use this as a backup
14749 bool GetMyExternalIP(unsigned int& ipRet)
14750 {
14751 CAddress addrConnect;
14752 const char* pszGet;
14753 const char* pszKeyword;
14754
14755 if (fUseProxy)
14756 return false;
14757
14758 for (int nLookup = 0; nLookup <= 1; nLookup++)
14759 for (int nHost = 1; nHost <= 2; nHost++)
14760 {
14761 // We should be phasing out our use of sites like these. If we need
14762 // replacements, we should ask for volunteers to put this simple
14763 // php file on their webserver that prints the client IP:
14764 // <?php echo $_SERVER["REMOTE_ADDR"]; ?>
14765 if (nHost == 1)
14766 {
14767 addrConnect = CAddress("91.198.22.70",80); // checkip.dyndns.org
14768
14769 if (nLookup == 1)
14770 {
14771 CAddress addrIP("checkip.dyndns.org", 80, true);
14772 if (addrIP.IsValid())
14773 addrConnect = addrIP;
14774 }
14775
14776 pszGet = "GET / HTTP/1.1\r\n"
14777 "Host: checkip.dyndns.org\r\n"
14778 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
14779 "Connection: close\r\n"
14780 "\r\n";
14781
14782 pszKeyword = "Address:";
14783 }
14784 else if (nHost == 2)
14785 {
14786 addrConnect = CAddress("74.208.43.192", 80); // www.showmyip.com
14787
14788 if (nLookup == 1)
14789 {
14790 CAddress addrIP("www.showmyip.com", 80, true);
14791 if (addrIP.IsValid())
14792 addrConnect = addrIP;
14793 }
14794
14795 pszGet = "GET /simple/ HTTP/1.1\r\n"
14796 "Host: www.showmyip.com\r\n"
14797 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
14798 "Connection: close\r\n"
14799 "\r\n";
14800
14801 pszKeyword = NULL; // Returns just IP address
14802 }
14803
14804 if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
14805 return true;
14806 }
14807
14808 return false;
14809 }
14810
14811 void ThreadGetMyExternalIP(void* parg)
14812 {
14813 // Wait for IRC to get it first
14814 if (!GetBoolArg("-noirc"))
14815 {
14816 for (int i = 0; i < 2 * 60; i++)
14817 {
14818 Sleep(1000);
14819 if (fGotExternalIP || fShutdown)
14820 return;
14821 }
14822 }
14823
14824 // Fallback in case IRC fails to get it
14825 if (GetMyExternalIP(addrLocalHost.ip))
14826 {
14827 printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
14828 if (addrLocalHost.IsRoutable())
14829 {
14830 // If we already connected to a few before we had our IP, go back and addr them.
14831 // setAddrKnown automatically filters any duplicate sends.
14832 CAddress addr(addrLocalHost);
14833 addr.nTime = GetAdjustedTime();
14834 CRITICAL_BLOCK(cs_vNodes)
14835 BOOST_FOREACH(CNode* pnode, vNodes)
14836 pnode->PushAddress(addr);
14837 }
14838 }
14839 }
14840
14841
14842
14843
14844
14845 bool AddAddress(CAddress addr, int64 nTimePenalty, CAddrDB *pAddrDB)
14846 {
14847 if (!addr.IsRoutable())
14848 return false;
14849 if (addr.ip == addrLocalHost.ip)
14850 return false;
14851 addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
14852 bool fUpdated = false;
14853 bool fNew = false;
14854 CAddress addrFound = addr;
14855
14856 CRITICAL_BLOCK(cs_mapAddresses)
14857 {
14858 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
14859 if (it == mapAddresses.end())
14860 {
14861 // New address
14862 printf("AddAddress(%s)\n", addr.ToString().c_str());
14863 mapAddresses.insert(make_pair(addr.GetKey(), addr));
14864 fUpdated = true;
14865 fNew = true;
14866 }
14867 else
14868 {
14869 addrFound = (*it).second;
14870 if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
14871 {
14872 // Services have been added
14873 addrFound.nServices |= addr.nServices;
14874 fUpdated = true;
14875 }
14876 bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
14877 int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
14878 if (addrFound.nTime < addr.nTime - nUpdateInterval)
14879 {
14880 // Periodically update most recently seen time
14881 addrFound.nTime = addr.nTime;
14882 fUpdated = true;
14883 }
14884 }
14885 }
14886 // There is a nasty deadlock bug if this is done inside the cs_mapAddresses
14887 // CRITICAL_BLOCK:
14888 // Thread 1: begin db transaction (locks inside-db-mutex)
14889 // then AddAddress (locks cs_mapAddresses)
14890 // Thread 2: AddAddress (locks cs_mapAddresses)
14891 // ... then db operation hangs waiting for inside-db-mutex
14892 if (fUpdated)
14893 {
14894 if (pAddrDB)
14895 pAddrDB->WriteAddress(addrFound);
14896 else
14897 CAddrDB().WriteAddress(addrFound);
14898 }
14899 return fNew;
14900 }
14901
14902 void AddressCurrentlyConnected(const CAddress& addr)
14903 {
14904 CAddress *paddrFound = NULL;
14905
14906 CRITICAL_BLOCK(cs_mapAddresses)
14907 {
14908 // Only if it's been published already
14909 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
14910 if (it != mapAddresses.end())
14911 paddrFound = &(*it).second;
14912 }
14913
14914 if (paddrFound)
14915 {
14916 int64 nUpdateInterval = 20 * 60;
14917 if (paddrFound->nTime < GetAdjustedTime() - nUpdateInterval)
14918 {
14919 // Periodically update most recently seen time
14920 paddrFound->nTime = GetAdjustedTime();
14921 CAddrDB addrdb;
14922 addrdb.WriteAddress(*paddrFound);
14923 }
14924 }
14925 }
14926
14927
14928
14929
14930
14931 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
14932 {
14933 // If the dialog might get closed before the reply comes back,
14934 // call this in the destructor so it doesn't get called after it's deleted.
14935 CRITICAL_BLOCK(cs_vNodes)
14936 {
14937 BOOST_FOREACH(CNode* pnode, vNodes)
14938 {
14939 CRITICAL_BLOCK(pnode->cs_mapRequests)
14940 {
14941 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
14942 {
14943 CRequestTracker& tracker = (*mi).second;
14944 if (tracker.fn == fn && tracker.param1 == param1)
14945 pnode->mapRequests.erase(mi++);
14946 else
14947 mi++;
14948 }
14949 }
14950 }
14951 }
14952 }
14953
14954
14955
14956
14957
14958
14959
14960 //
14961 // Subscription methods for the broadcast and subscription system.
14962 // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
14963 //
14964 // The subscription system uses a meet-in-the-middle strategy.
14965 // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
14966 // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
14967 //
14968
14969 bool AnySubscribed(unsigned int nChannel)
14970 {
14971 if (pnodeLocalHost->IsSubscribed(nChannel))
14972 return true;
14973 CRITICAL_BLOCK(cs_vNodes)
14974 BOOST_FOREACH(CNode* pnode, vNodes)
14975 if (pnode->IsSubscribed(nChannel))
14976 return true;
14977 return false;
14978 }
14979
14980 bool CNode::IsSubscribed(unsigned int nChannel)
14981 {
14982 if (nChannel >= vfSubscribe.size())
14983 return false;
14984 return vfSubscribe[nChannel];
14985 }
14986
14987 void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
14988 {
14989 if (nChannel >= vfSubscribe.size())
14990 return;
14991
14992 if (!AnySubscribed(nChannel))
14993 {
14994 // Relay subscribe
14995 CRITICAL_BLOCK(cs_vNodes)
14996 BOOST_FOREACH(CNode* pnode, vNodes)
14997 if (pnode != this)
14998 pnode->PushMessage("subscribe", nChannel, nHops);
14999 }
15000
15001 vfSubscribe[nChannel] = true;
15002 }
15003
15004 void CNode::CancelSubscribe(unsigned int nChannel)
15005 {
15006 if (nChannel >= vfSubscribe.size())
15007 return;
15008
15009 // Prevent from relaying cancel if wasn't subscribed
15010 if (!vfSubscribe[nChannel])
15011 return;
15012 vfSubscribe[nChannel] = false;
15013
15014 if (!AnySubscribed(nChannel))
15015 {
15016 // Relay subscription cancel
15017 CRITICAL_BLOCK(cs_vNodes)
15018 BOOST_FOREACH(CNode* pnode, vNodes)
15019 if (pnode != this)
15020 pnode->PushMessage("sub-cancel", nChannel);
15021 }
15022 }
15023
15024
15025
15026
15027
15028
15029
15030
15031
15032 CNode* FindNode(unsigned int ip)
15033 {
15034 CRITICAL_BLOCK(cs_vNodes)
15035 {
15036 BOOST_FOREACH(CNode* pnode, vNodes)
15037 if (pnode->addr.ip == ip)
15038 return (pnode);
15039 }
15040 return NULL;
15041 }
15042
15043 CNode* FindNode(CAddress addr)
15044 {
15045 CRITICAL_BLOCK(cs_vNodes)
15046 {
15047 BOOST_FOREACH(CNode* pnode, vNodes)
15048 if (pnode->addr == addr)
15049 return (pnode);
15050 }
15051 return NULL;
15052 }
15053
15054 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
15055 {
15056 if (addrConnect.ip == addrLocalHost.ip)
15057 return NULL;
15058
15059 // Look for an existing connection
15060 CNode* pnode = FindNode(addrConnect.ip);
15061 if (pnode)
15062 {
15063 if (nTimeout != 0)
15064 pnode->AddRef(nTimeout);
15065 else
15066 pnode->AddRef();
15067 return pnode;
15068 }
15069
15070 /// debug print
15071 printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n",
15072 addrConnect.ToString().c_str(),
15073 (double)(addrConnect.nTime - GetAdjustedTime())/3600.0,
15074 (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0);
15075
15076 CRITICAL_BLOCK(cs_mapAddresses)
15077 mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime();
15078
15079 // Connect
15080 SOCKET hSocket;
15081 if (ConnectSocket(addrConnect, hSocket))
15082 {
15083 /// debug print
15084 printf("connected %s\n", addrConnect.ToString().c_str());
15085
15086 // Set to nonblocking
15087 #ifdef WIN32
15088 u_long nOne = 1;
15089 if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
15090 printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
15091 #else
15092 if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
15093 printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
15094 #endif
15095
15096 // Add node
15097 CNode* pnode = new CNode(hSocket, addrConnect, false);
15098 if (nTimeout != 0)
15099 pnode->AddRef(nTimeout);
15100 else
15101 pnode->AddRef();
15102 CRITICAL_BLOCK(cs_vNodes)
15103 vNodes.push_back(pnode);
15104
15105 pnode->nTimeConnected = GetTime();
15106 return pnode;
15107 }
15108 else
15109 {
15110 return NULL;
15111 }
15112 }
15113
15114 void CNode::CloseSocketDisconnect()
15115 {
15116 fDisconnect = true;
15117 if (hSocket != INVALID_SOCKET)
15118 {
15119 if (fDebug)
15120 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
15121 printf("disconnecting node %s\n", addr.ToString().c_str());
15122 closesocket(hSocket);
15123 hSocket = INVALID_SOCKET;
15124 }
15125 }
15126
15127 void CNode::Cleanup()
15128 {
15129 // All of a nodes broadcasts and subscriptions are automatically torn down
15130 // when it goes down, so a node has to stay up to keep its broadcast going.
15131
15132 // Cancel subscriptions
15133 for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
15134 if (vfSubscribe[nChannel])
15135 CancelSubscribe(nChannel);
15136 }
15137
15138
15139 std::map<unsigned int, int64> CNode::setBanned;
15140 CCriticalSection CNode::cs_setBanned;
15141
15142 void CNode::ClearBanned()
15143 {
15144 setBanned.clear();
15145 }
15146
15147 bool CNode::IsBanned(unsigned int ip)
15148 {
15149 bool fResult = false;
15150 CRITICAL_BLOCK(cs_setBanned)
15151 {
15152 std::map<unsigned int, int64>::iterator i = setBanned.find(ip);
15153 if (i != setBanned.end())
15154 {
15155 int64 t = (*i).second;
15156 if (GetTime() < t)
15157 fResult = true;
15158 }
15159 }
15160 return fResult;
15161 }
15162
15163 bool CNode::Misbehaving(int howmuch)
15164 {
15165 if (addr.IsLocal())
15166 {
15167 printf("Warning: local node %s misbehaving\n", addr.ToString().c_str());
15168 return false;
15169 }
15170
15171 nMisbehavior += howmuch;
15172 if (nMisbehavior >= GetArg("-banscore", 100))
15173 {
15174 int64 banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban
15175 CRITICAL_BLOCK(cs_setBanned)
15176 if (setBanned[addr.ip] < banTime)
15177 setBanned[addr.ip] = banTime;
15178 CloseSocketDisconnect();
15179 printf("Disconnected %s for misbehavior (score=%d)\n", addr.ToString().c_str(), nMisbehavior);
15180 return true;
15181 }
15182 return false;
15183 }
15184
15185
15186
15187
15188
15189
15190
15191
15192
15193
15194
15195
15196 void ThreadSocketHandler(void* parg)
15197 {
15198 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
15199 try
15200 {
15201 vnThreadsRunning[0]++;
15202 ThreadSocketHandler2(parg);
15203 vnThreadsRunning[0]--;
15204 }
15205 catch (std::exception& e) {
15206 vnThreadsRunning[0]--;
15207 PrintException(&e, "ThreadSocketHandler()");
15208 } catch (...) {
15209 vnThreadsRunning[0]--;
15210 throw; // support pthread_cancel()
15211 }
15212 printf("ThreadSocketHandler exiting\n");
15213 }
15214
15215 void ThreadSocketHandler2(void* parg)
15216 {
15217 printf("ThreadSocketHandler started\n");
15218 list<CNode*> vNodesDisconnected;
15219 int nPrevNodeCount = 0;
15220
15221 loop
15222 {
15223 //
15224 // Disconnect nodes
15225 //
15226 CRITICAL_BLOCK(cs_vNodes)
15227 {
15228 // Disconnect unused nodes
15229 vector<CNode*> vNodesCopy = vNodes;
15230 BOOST_FOREACH(CNode* pnode, vNodesCopy)
15231 {
15232 if (pnode->fDisconnect ||
15233 (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
15234 {
15235 // remove from vNodes
15236 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
15237
15238 // close socket and cleanup
15239 pnode->CloseSocketDisconnect();
15240 pnode->Cleanup();
15241
15242 // hold in disconnected pool until all refs are released
15243 pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
15244 if (pnode->fNetworkNode || pnode->fInbound)
15245 pnode->Release();
15246 vNodesDisconnected.push_back(pnode);
15247 }
15248 }
15249
15250 // Delete disconnected nodes
15251 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
15252 BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
15253 {
15254 // wait until threads are done using it
15255 if (pnode->GetRefCount() <= 0)
15256 {
15257 bool fDelete = false;
15258 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
15259 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
15260 TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
15261 TRY_CRITICAL_BLOCK(pnode->cs_inventory)
15262 fDelete = true;
15263 if (fDelete)
15264 {
15265 vNodesDisconnected.remove(pnode);
15266 delete pnode;
15267 }
15268 }
15269 }
15270 }
15271 if (vNodes.size() != nPrevNodeCount)
15272 {
15273 nPrevNodeCount = vNodes.size();
15274 MainFrameRepaint();
15275 }
15276
15277
15278 //
15279 // Find which sockets have data to receive
15280 //
15281 struct timeval timeout;
15282 timeout.tv_sec = 0;
15283 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
15284
15285 fd_set fdsetRecv;
15286 fd_set fdsetSend;
15287 fd_set fdsetError;
15288 FD_ZERO(&fdsetRecv);
15289 FD_ZERO(&fdsetSend);
15290 FD_ZERO(&fdsetError);
15291 SOCKET hSocketMax = 0;
15292
15293 if(hListenSocket != INVALID_SOCKET)
15294 FD_SET(hListenSocket, &fdsetRecv);
15295 hSocketMax = max(hSocketMax, hListenSocket);
15296 CRITICAL_BLOCK(cs_vNodes)
15297 {
15298 BOOST_FOREACH(CNode* pnode, vNodes)
15299 {
15300 if (pnode->hSocket == INVALID_SOCKET)
15301 continue;
15302 FD_SET(pnode->hSocket, &fdsetRecv);
15303 FD_SET(pnode->hSocket, &fdsetError);
15304 hSocketMax = max(hSocketMax, pnode->hSocket);
15305 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
15306 if (!pnode->vSend.empty())
15307 FD_SET(pnode->hSocket, &fdsetSend);
15308 }
15309 }
15310
15311 vnThreadsRunning[0]--;
15312 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
15313 vnThreadsRunning[0]++;
15314 if (fShutdown)
15315 return;
15316 if (nSelect == SOCKET_ERROR)
15317 {
15318 int nErr = WSAGetLastError();
15319 if (hSocketMax > -1)
15320 {
15321 printf("socket select error %d\n", nErr);
15322 for (int i = 0; i <= hSocketMax; i++)
15323 FD_SET(i, &fdsetRecv);
15324 }
15325 FD_ZERO(&fdsetSend);
15326 FD_ZERO(&fdsetError);
15327 Sleep(timeout.tv_usec/1000);
15328 }
15329
15330
15331 //
15332 // Accept new connections
15333 //
15334 if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
15335 {
15336 struct sockaddr_in sockaddr;
15337 socklen_t len = sizeof(sockaddr);
15338 SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
15339 CAddress addr;
15340 int nInbound = 0;
15341
15342 if (hSocket != INVALID_SOCKET)
15343 addr = CAddress(sockaddr);
15344
15345 CRITICAL_BLOCK(cs_vNodes)
15346 BOOST_FOREACH(CNode* pnode, vNodes)
15347 if (pnode->fInbound)
15348 nInbound++;
15349
15350 if (hSocket == INVALID_SOCKET)
15351 {
15352 if (WSAGetLastError() != WSAEWOULDBLOCK)
15353 printf("socket error accept failed: %d\n", WSAGetLastError());
15354 }
15355 else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
15356 {
15357 closesocket(hSocket);
15358 }
15359 else if (CNode::IsBanned(addr.ip))
15360 {
15361 printf("connection from %s dropped (banned)\n", addr.ToString().c_str());
15362 closesocket(hSocket);
15363 }
15364 else
15365 {
15366 printf("accepted connection %s\n", addr.ToString().c_str());
15367 CNode* pnode = new CNode(hSocket, addr, true);
15368 pnode->AddRef();
15369 CRITICAL_BLOCK(cs_vNodes)
15370 vNodes.push_back(pnode);
15371 }
15372 }
15373
15374
15375 //
15376 // Service each socket
15377 //
15378 vector<CNode*> vNodesCopy;
15379 CRITICAL_BLOCK(cs_vNodes)
15380 {
15381 vNodesCopy = vNodes;
15382 BOOST_FOREACH(CNode* pnode, vNodesCopy)
15383 pnode->AddRef();
15384 }
15385 BOOST_FOREACH(CNode* pnode, vNodesCopy)
15386 {
15387 if (fShutdown)
15388 return;
15389
15390 //
15391 // Receive
15392 //
15393 if (pnode->hSocket == INVALID_SOCKET)
15394 continue;
15395 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
15396 {
15397 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
15398 {
15399 CDataStream& vRecv = pnode->vRecv;
15400 unsigned int nPos = vRecv.size();
15401
15402 if (nPos > ReceiveBufferSize()) {
15403 if (!pnode->fDisconnect)
15404 printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
15405 pnode->CloseSocketDisconnect();
15406 }
15407 else {
15408 // typical socket buffer is 8K-64K
15409 char pchBuf[0x10000];
15410 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
15411 if (nBytes > 0)
15412 {
15413 vRecv.resize(nPos + nBytes);
15414 memcpy(&vRecv[nPos], pchBuf, nBytes);
15415 pnode->nLastRecv = GetTime();
15416 }
15417 else if (nBytes == 0)
15418 {
15419 // socket closed gracefully
15420 if (!pnode->fDisconnect)
15421 printf("socket closed\n");
15422 pnode->CloseSocketDisconnect();
15423 }
15424 else if (nBytes < 0)
15425 {
15426 // error
15427 int nErr = WSAGetLastError();
15428 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
15429 {
15430 if (!pnode->fDisconnect)
15431 printf("socket recv error %d\n", nErr);
15432 pnode->CloseSocketDisconnect();
15433 }
15434 }
15435 }
15436 }
15437 }
15438
15439 //
15440 // Send
15441 //
15442 if (pnode->hSocket == INVALID_SOCKET)
15443 continue;
15444 if (FD_ISSET(pnode->hSocket, &fdsetSend))
15445 {
15446 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
15447 {
15448 CDataStream& vSend = pnode->vSend;
15449 if (!vSend.empty())
15450 {
15451 int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
15452 if (nBytes > 0)
15453 {
15454 vSend.erase(vSend.begin(), vSend.begin() + nBytes);
15455 pnode->nLastSend = GetTime();
15456 }
15457 else if (nBytes < 0)
15458 {
15459 // error
15460 int nErr = WSAGetLastError();
15461 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
15462 {
15463 printf("socket send error %d\n", nErr);
15464 pnode->CloseSocketDisconnect();
15465 }
15466 }
15467 if (vSend.size() > SendBufferSize()) {
15468 if (!pnode->fDisconnect)
15469 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
15470 pnode->CloseSocketDisconnect();
15471 }
15472 }
15473 }
15474 }
15475
15476 //
15477 // Inactivity checking
15478 //
15479 if (pnode->vSend.empty())
15480 pnode->nLastSendEmpty = GetTime();
15481 if (GetTime() - pnode->nTimeConnected > 60)
15482 {
15483 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
15484 {
15485 printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
15486 pnode->fDisconnect = true;
15487 }
15488 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
15489 {
15490 printf("socket not sending\n");
15491 pnode->fDisconnect = true;
15492 }
15493 else if (GetTime() - pnode->nLastRecv > 90*60)
15494 {
15495 printf("socket inactivity timeout\n");
15496 pnode->fDisconnect = true;
15497 }
15498 }
15499 }
15500 CRITICAL_BLOCK(cs_vNodes)
15501 {
15502 BOOST_FOREACH(CNode* pnode, vNodesCopy)
15503 pnode->Release();
15504 }
15505
15506 Sleep(10);
15507 }
15508 }
15509
15510
15511
15512
15513
15514
15515
15516
15517
15518 #ifdef USE_UPNP
15519 void ThreadMapPort(void* parg)
15520 {
15521 IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
15522 try
15523 {
15524 vnThreadsRunning[5]++;
15525 ThreadMapPort2(parg);
15526 vnThreadsRunning[5]--;
15527 }
15528 catch (std::exception& e) {
15529 vnThreadsRunning[5]--;
15530 PrintException(&e, "ThreadMapPort()");
15531 } catch (...) {
15532 vnThreadsRunning[5]--;
15533 PrintException(NULL, "ThreadMapPort()");
15534 }
15535 printf("ThreadMapPort exiting\n");
15536 }
15537
15538 void ThreadMapPort2(void* parg)
15539 {
15540 printf("ThreadMapPort started\n");
15541
15542 char port[6];
15543 sprintf(port, "%d", GetListenPort());
15544
15545 const char * multicastif = 0;
15546 const char * minissdpdpath = 0;
15547 struct UPNPDev * devlist = 0;
15548 char lanaddr[64];
15549
15550 #ifndef UPNPDISCOVER_SUCCESS
15551 /* miniupnpc 1.5 */
15552 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
15553 #else
15554 /* miniupnpc 1.6 */
15555 int error = 0;
15556 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
15557 #endif
15558
15559 struct UPNPUrls urls;
15560 struct IGDdatas data;
15561 int r;
15562
15563 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
15564 if (r == 1)
15565 {
15566 if (!addrLocalHost.IsRoutable())
15567 {
15568 char externalIPAddress[40];
15569 r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
15570 if(r != UPNPCOMMAND_SUCCESS)
15571 printf("UPnP: GetExternalIPAddress() returned %d\n", r);
15572 else
15573 {
15574 if(externalIPAddress[0])
15575 {
15576 printf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
15577 CAddress addrExternalFromUPnP(externalIPAddress, 0, false, nLocalServices);
15578 if (addrExternalFromUPnP.IsRoutable())
15579 addrLocalHost = addrExternalFromUPnP;
15580 }
15581 else
15582 printf("UPnP: GetExternalIPAddress failed.\n");
15583 }
15584 }
15585
15586 string strDesc = "Bitcoin " + FormatFullVersion();
15587 #ifndef UPNPDISCOVER_SUCCESS
15588 /* miniupnpc 1.5 */
15589 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
15590 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
15591 #else
15592 /* miniupnpc 1.6 */
15593 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
15594 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
15595 #endif
15596
15597 if(r!=UPNPCOMMAND_SUCCESS)
15598 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
15599 port, port, lanaddr, r, strupnperror(r));
15600 else
15601 printf("UPnP Port Mapping successful.\n");
15602 int i = 1;
15603 loop {
15604 if (fShutdown || !fUseUPnP)
15605 {
15606 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
15607 printf("UPNP_DeletePortMapping() returned : %d\n", r);
15608 freeUPNPDevlist(devlist); devlist = 0;
15609 FreeUPNPUrls(&urls);
15610 return;
15611 }
15612 if (i % 600 == 0) // Refresh every 20 minutes
15613 {
15614 #ifndef UPNPDISCOVER_SUCCESS
15615 /* miniupnpc 1.5 */
15616 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
15617 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
15618 #else
15619 /* miniupnpc 1.6 */
15620 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
15621 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
15622 #endif
15623
15624 if(r!=UPNPCOMMAND_SUCCESS)
15625 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
15626 port, port, lanaddr, r, strupnperror(r));
15627 else
15628 printf("UPnP Port Mapping successful.\n");;
15629 }
15630 Sleep(2000);
15631 i++;
15632 }
15633 } else {
15634 printf("No valid UPnP IGDs found\n");
15635 freeUPNPDevlist(devlist); devlist = 0;
15636 if (r != 0)
15637 FreeUPNPUrls(&urls);
15638 loop {
15639 if (fShutdown || !fUseUPnP)
15640 return;
15641 Sleep(2000);
15642 }
15643 }
15644 }
15645
15646 void MapPort(bool fMapPort)
15647 {
15648 if (fUseUPnP != fMapPort)
15649 {
15650 fUseUPnP = fMapPort;
15651 WriteSetting("fUseUPnP", fUseUPnP);
15652 }
15653 if (fUseUPnP && vnThreadsRunning[5] < 1)
15654 {
15655 if (!CreateThread(ThreadMapPort, NULL))
15656 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
15657 }
15658 }
15659 #else
15660 void MapPort(bool /* unused fMapPort */)
15661 {
15662 // Intentionally left blank.
15663 }
15664 #endif
15665
15666
15667
15668
15669
15670
15671
15672
15673
15674
15675 static const char *strDNSSeed[] = {
15676 "bitseed.xf2.org",
15677 "dnsseed.bluematt.me",
15678 "seed.bitcoin.sipa.be",
15679 "dnsseed.bitcoin.dashjr.org",
15680 };
15681
15682 void ThreadDNSAddressSeed(void* parg)
15683 {
15684 IMPLEMENT_RANDOMIZE_STACK(ThreadDNSAddressSeed(parg));
15685 try
15686 {
15687 vnThreadsRunning[6]++;
15688 ThreadDNSAddressSeed2(parg);
15689 vnThreadsRunning[6]--;
15690 }
15691 catch (std::exception& e) {
15692 vnThreadsRunning[6]--;
15693 PrintException(&e, "ThreadDNSAddressSeed()");
15694 } catch (...) {
15695 vnThreadsRunning[6]--;
15696 throw; // support pthread_cancel()
15697 }
15698 printf("ThreadDNSAddressSeed exiting\n");
15699 }
15700
15701 void ThreadDNSAddressSeed2(void* parg)
15702 {
15703 printf("ThreadDNSAddressSeed started\n");
15704 int found = 0;
15705
15706 if (!fTestNet)
15707 {
15708 printf("Loading addresses from DNS seeds (could take a while)\n");
15709
15710 for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
15711 vector<CAddress> vaddr;
15712 if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, -1, true))
15713 {
15714 CAddrDB addrDB;
15715 addrDB.TxnBegin();
15716 BOOST_FOREACH (CAddress& addr, vaddr)
15717 {
15718 if (addr.GetByte(3) != 127)
15719 {
15720 addr.nTime = 0;
15721 AddAddress(addr, 0, &addrDB);
15722 found++;
15723 }
15724 }
15725 addrDB.TxnCommit(); // Save addresses (it's ok if this fails)
15726 }
15727 }
15728 }
15729
15730 printf("%d addresses found from DNS seeds\n", found);
15731 }
15732
15733
15734
15735
15736
15737
15738
15739
15740
15741
15742
15743
15744 unsigned int pnSeed[] =
15745 {
15746 0x959bd347, 0xf8de42b2, 0x73bc0518, 0xea6edc50, 0x21b00a4d, 0xc725b43d, 0xd665464d, 0x1a2a770e,
15747 0x27c93946, 0x65b2fa46, 0xb80ae255, 0x66b3b446, 0xb1877a3e, 0x6ee89e3e, 0xc3175b40, 0x2a01a83c,
15748 0x95b1363a, 0xa079ad3d, 0xe6ca801f, 0x027f4f4a, 0x34f7f03a, 0xf790f04a, 0x16ca801f, 0x2f4d5e40,
15749 0x3a4d5e40, 0xc43a322e, 0xc8159753, 0x14d4724c, 0x7919a118, 0xe0bdb34e, 0x68a16b2e, 0xff64b44d,
15750 0x6099115b, 0x9b57b05b, 0x7bd1b4ad, 0xdf95944f, 0x29d2b73d, 0xafa8db79, 0xe247ba41, 0x24078348,
15751 0xf722f03c, 0x33567ebc, 0xace64ed4, 0x984d3932, 0xb5f34e55, 0x27b7024d, 0x94579247, 0x8894042e,
15752 0x9357d34c, 0x1063c24b, 0xcaa228b1, 0xa3c5a8b2, 0x5dc64857, 0xa2c23643, 0xa8369a54, 0x31203077,
15753 0x00707c5c, 0x09fc0b3a, 0x272e9e2e, 0xf80f043e, 0x9449ca3e, 0x5512c33e, 0xd106b555, 0xe8024157,
15754 0xe288ec29, 0xc79c5461, 0xafb63932, 0xdb02ab4b, 0x0e512777, 0x8a145a4c, 0xb201ff4f, 0x5e09314b,
15755 0xcd9bfbcd, 0x1c023765, 0x4394e75c, 0xa728bd4d, 0x65331552, 0xa98420b1, 0x89ecf559, 0x6e80801f,
15756 0xf404f118, 0xefd62b51, 0x05918346, 0x9b186d5f, 0xacabab46, 0xf912e255, 0xc188ea62, 0xcc55734e,
15757 0xc668064d, 0xd77a4558, 0x46201c55, 0xf17dfc80, 0xf7142f2e, 0x87bfb718, 0x8aa54fb2, 0xc451d518,
15758 0xc4ae8831, 0x8dd44d55, 0x5bbd206c, 0x64536b5d, 0x5c667e60, 0x3b064242, 0xfe963a42, 0xa28e6dc8,
15759 0xe8a9604a, 0xc989464e, 0xd124a659, 0x50065140, 0xa44dfe5e, 0x1079e655, 0x3fb986d5, 0x47895b18,
15760 0x7d3ce4ad, 0x4561ba50, 0x296eec62, 0x255b41ad, 0xaed35ec9, 0x55556f12, 0xc7d3154d, 0x3297b65d,
15761 0x8930121f, 0xabf42e4e, 0x4a29e044, 0x1212685d, 0x676c1e40, 0xce009744, 0x383a8948, 0xa2dbd0ad,
15762 0xecc2564d, 0x07dbc252, 0x887ee24b, 0x5171644c, 0x6bb798c1, 0x847f495d, 0x4cbb7145, 0x3bb81c32,
15763 0x45eb262e, 0xc8015a4e, 0x250a361b, 0xf694f946, 0xd64a183e, 0xd4f1dd59, 0x8f20ffd4, 0x51d9e55c,
15764 0x09521763, 0x5e02002e, 0x32c8074d, 0xe685762e, 0x8290b0bc, 0x762a922e, 0xfc5ee754, 0x83a24829,
15765 0x775b224d, 0x6295bb4d, 0x38ec0555, 0xbffbba50, 0xe5560260, 0x86b16a7c, 0xd372234e, 0x49a3c24b,
15766 0x2f6a171f, 0x4d75ed60, 0xae94115b, 0xcb543744, 0x63080c59, 0x3f9c724c, 0xc977ce18, 0x532efb18,
15767 0x69dc3b2e, 0x5f94d929, 0x1732bb4d, 0x9c814b4d, 0xe6b3762e, 0xc024f662, 0x8face35b, 0x6b5b044d,
15768 0x798c7b57, 0x79a6b44c, 0x067d3057, 0xf9e94e5f, 0x91cbe15b, 0x71405eb2, 0x2662234e, 0xcbcc4a6d,
15769 0xbf69d54b, 0xa79b4e55, 0xec6d3e51, 0x7c0b3c02, 0x60f83653, 0x24c1e15c, 0x1110b62e, 0x10350f59,
15770 0xa56f1d55, 0x3509e7a9, 0xeb128354, 0x14268e2e, 0x934e28bc, 0x8e32692e, 0x8331a21f, 0x3e633932,
15771 0xc812b12e, 0xc684bf2e, 0x80112d2e, 0xe0ddc96c, 0xc630ca4a, 0x5c09b3b2, 0x0b580518, 0xc8e9d54b,
15772 0xd169aa43, 0x17d0d655, 0x1d029963, 0x7ff87559, 0xcb701f1f, 0x6fa3e85d, 0xe45e9a54, 0xf05d1802,
15773 0x44d03b2e, 0x837b692e, 0xccd4354e, 0x3d6da13c, 0x3423084d, 0xf707c34a, 0x55f6db3a, 0xad26e442,
15774 0x6233a21f, 0x09e80e59, 0x8caeb54d, 0xbe870941, 0xb407d20e, 0x20b51018, 0x56fb152e, 0x460d2a4e,
15775 0xbb9a2946, 0x560eb12e, 0xed83dd29, 0xd6724f53, 0xa50aafb8, 0x451346d9, 0x88348e2e, 0x7312fead,
15776 0x8ecaf96f, 0x1bda4e5f, 0xf1671e40, 0x3c8c3e3b, 0x4716324d, 0xdde24ede, 0xf98cd17d, 0xa91d4644,
15777 0x28124eb2, 0x147d5129, 0xd022042e, 0x61733d3b, 0xad0d5e02, 0x8ce2932e, 0xe5c18502, 0x549c1e32,
15778 0x9685801f, 0x86e217ad, 0xd948214b, 0x4110f462, 0x3a2e894e, 0xbd35492e, 0x87e0d558, 0x64b8ef7d,
15779 0x7c3eb962, 0x72a84b3e, 0x7cd667c9, 0x28370a2e, 0x4bc60e7b, 0x6fc1ec60, 0x14a6983f, 0x86739a4b,
15780 0x46954e5f, 0x32e2e15c, 0x2e9326cf, 0xe5801c5e, 0x379607b2, 0x32151145, 0xf0e39744, 0xacb54c55,
15781 0xa37dfb60, 0x83b55cc9, 0x388f7ca5, 0x15034f5f, 0x3e94965b, 0x68e0ffad, 0x35280f59, 0x8fe190cf,
15782 0x7c6ba5b2, 0xa5e9db43, 0x4ee1fc60, 0xd9d94e5f, 0x04040677, 0x0ea9b35e, 0x5961f14f, 0x67fda063,
15783 0xa48a5a31, 0xc6524e55, 0x283d325e, 0x3f37515f, 0x96b94b3e, 0xacce620e, 0x6481cc5b, 0xa4a06d4b,
15784 0x9e95d2d9, 0xe40c03d5, 0xc2f4514b, 0xb79aad44, 0xf64be843, 0xb2064070, 0xfca00455, 0x429dfa4e,
15785 0x2323f173, 0xeda4185e, 0xabd5227d, 0x9efd4d58, 0xb1104758, 0x4811e955, 0xbd9ab355, 0xe921f44b,
15786 0x9f166dce, 0x09e279b2, 0xe0c9ac7b, 0x7901a5ad, 0xa145d4b0, 0x79104671, 0xec31e35a, 0x4fe0b555,
15787 0xc7d9cbad, 0xad057f55, 0xe94cc759, 0x7fe0b043, 0xe4529f2e, 0x0d4dd4b2, 0x9f11a54d, 0x031e2e4e,
15788 0xe6014f5f, 0x11d1ca6c, 0x26bd7f61, 0xeb86854f, 0x4d347b57, 0x116bbe2e, 0xdba7234e, 0x7bcbfd2e,
15789 0x174dd4b2, 0x6686762e, 0xb089ba50, 0xc6258246, 0x087e767b, 0xc4a8cb4a, 0x595dba50, 0x7f0ae502,
15790 0x7b1dbd5a, 0xa0603492, 0x57d1af4b, 0x9e21ffd4, 0x6393064d, 0x7407376e, 0xe484762e, 0x122a4e53,
15791 0x4a37aa43, 0x3888a6be, 0xee77864e, 0x039c8dd5, 0x688d89af, 0x0e988f62, 0x08218246, 0xfc2f8246,
15792 0xd1d97040, 0xd64cd4b2, 0x5ae4a6b8, 0x7d0de9bc, 0x8d304d61, 0x06c5c672, 0xa4c8bd4d, 0xe0fd373b,
15793 0x575ebe4d, 0x72d26277, 0x55570f55, 0x77b154d9, 0xe214293a, 0xfc740f4b, 0xfe3f6a57, 0xa9c55f02,
15794 0xae4054db, 0x2394d918, 0xb511b24a, 0xb8741ab2, 0x0758e65e, 0xc7b5795b, 0xb0a30a4c, 0xaf7f170c,
15795 0xf3b4762e, 0x8179576d, 0x738a1581, 0x4b95b64c, 0x9829b618, 0x1bea932e, 0x7bdeaa4b, 0xcb5e0281,
15796 0x65618f54, 0x0658474b, 0x27066acf, 0x40556d65, 0x7d204d53, 0xf28bc244, 0xdce23455, 0xadc0ff54,
15797 0x3863c948, 0xcee34e5f, 0xdeb85e02, 0x2ed17a61, 0x6a7b094d, 0x7f0cfc40, 0x59603f54, 0x3220afbc,
15798 0xb5dfd962, 0x125d21c0, 0x13f8d243, 0xacfefb4e, 0x86c2c147, 0x3d8bbd59, 0xbd02a21f, 0x2593042e,
15799 0xc6a17a7c, 0x28925861, 0xb487ed44, 0xb5f4fd6d, 0x90c28a45, 0x5a14f74d, 0x43d71b4c, 0x728ebb5d,
15800 0x885bf950, 0x08134dd0, 0x38ec046e, 0xc575684b, 0x50082d2e, 0xa2f47757, 0x270f86ae, 0xf3ff6462,
15801 0x10ed3f4e, 0x4b58d462, 0xe01ce23e, 0x8c5b092e, 0x63e52f4e, 0x22c1e85d, 0xa908f54e, 0x8591624f,
15802 0x2c0fb94e, 0xa280ba3c, 0xb6f41b4c, 0x24f9aa47, 0x27201647, 0x3a3ea6dc, 0xa14fc3be, 0x3c34bdd5,
15803 0x5b8d4f5b, 0xaadeaf4b, 0xc71cab50, 0x15697a4c, 0x9a1a734c, 0x2a037d81, 0x2590bd59, 0x48ec2741,
15804 0x53489c5b, 0x7f00314b, 0x2170d362, 0xf2e92542, 0x42c10b44, 0x98f0f118, 0x883a3456, 0x099a932e,
15805 0xea38f7bc, 0x644e9247, 0xbb61b62e, 0x30e0863d, 0x5f51be54, 0x207215c7, 0x5f306c45, 0xaa7f3932,
15806 0x98da7d45, 0x4e339b59, 0x2e411581, 0xa808f618, 0xad2c0c59, 0x54476741, 0x09e99fd1, 0x5db8f752,
15807 0xc16df8bd, 0x1dd4b44f, 0x106edf2e, 0x9e15c180, 0x2ad6b56f, 0x633a5332, 0xff33787c, 0x077cb545,
15808 0x6610be6d, 0x75aad2c4, 0x72fb4d5b, 0xe81e0f59, 0x576f6332, 0x47333373, 0x351ed783, 0x2d90fb50,
15809 0x8d5e0f6c, 0x5b27a552, 0xdb293ebb, 0xe55ef950, 0x4b133ad8, 0x75df975a, 0x7b6a8740, 0xa899464b,
15810 0xfab15161, 0x10f8b64d, 0xd055ea4d, 0xee8e146b, 0x4b14afb8, 0x4bc1c44a, 0x9b961dcc, 0xd111ff43,
15811 0xfca0b745, 0xc800e412, 0x0afad9d1, 0xf751c350, 0xf9f0cccf, 0xa290a545, 0x8ef13763, 0x7ec70d59,
15812 0x2b066acf, 0x65496c45, 0xade02c1b, 0xae6eb077, 0x92c1e65b, 0xc064e6a9, 0xc649e56d, 0x5287a243,
15813 0x36de4f5b, 0x5b1df6ad, 0x65c39a59, 0xdba805b2, 0x20067aa8, 0x6457e56d, 0x3cee26cf, 0xfd3ff26d,
15814 0x04f86d4a, 0x06b8e048, 0xa93bcd5c, 0x91135852, 0xbe90a643, 0x8fa0094d, 0x06d8215f, 0x2677094d,
15815 0xd735685c, 0x164a00c9, 0x5209ac5f, 0xa9564c5c, 0x3b504f5f, 0xcc826bd0, 0x4615042e, 0x5fe13b4a,
15816 0x8c81b86d, 0x879ab68c, 0x1de564b8, 0x434487d8, 0x2dcb1b63, 0x82ab524a, 0xb0676abb, 0xa13d9c62,
15817 0xdbb5b86d, 0x5b7f4b59, 0xaddfb44d, 0xad773532, 0x3997054c, 0x72cebd89, 0xb194544c, 0xc5b8046e,
15818 0x6e1adeb2, 0xaa5abb51, 0xefb54b44, 0x15efc54f, 0xe9f1bc4d, 0x5f401b6c, 0x97f018ad, 0xc82f9252,
15819 0x2cdc762e, 0x8e52e56d, 0x1827175e, 0x9b7d7d80, 0xb2ad6845, 0x51065140, 0x71180a18, 0x5b27006c,
15820 0x0621e255, 0x721cbe58, 0x670c0cb8, 0xf8bd715d, 0xe0bdc5d9, 0xed843501, 0x4b84554d, 0x7f1a18bc,
15821 0x53bcaf47, 0x5729d35f, 0xf0dda246, 0x22382bd0, 0x4d641fb0, 0x316afcde, 0x50a22f1f, 0x73608046,
15822 0xc461d84a, 0xb2dbe247,
15823 };
15824
15825
15826
15827 void ThreadOpenConnections(void* parg)
15828 {
15829 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
15830 try
15831 {
15832 vnThreadsRunning[1]++;
15833 ThreadOpenConnections2(parg);
15834 vnThreadsRunning[1]--;
15835 }
15836 catch (std::exception& e) {
15837 vnThreadsRunning[1]--;
15838 PrintException(&e, "ThreadOpenConnections()");
15839 } catch (...) {
15840 vnThreadsRunning[1]--;
15841 PrintException(NULL, "ThreadOpenConnections()");
15842 }
15843 printf("ThreadOpenConnections exiting\n");
15844 }
15845
15846 void ThreadOpenConnections2(void* parg)
15847 {
15848 printf("ThreadOpenConnections started\n");
15849
15850 // Connect to specific addresses
15851 if (mapArgs.count("-connect"))
15852 {
15853 for (int64 nLoop = 0;; nLoop++)
15854 {
15855 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
15856 {
15857 CAddress addr(strAddr, fAllowDNS);
15858 if (addr.IsValid())
15859 OpenNetworkConnection(addr);
15860 for (int i = 0; i < 10 && i < nLoop; i++)
15861 {
15862 Sleep(500);
15863 if (fShutdown)
15864 return;
15865 }
15866 }
15867 }
15868 }
15869
15870 // Connect to manually added nodes first
15871 if (mapArgs.count("-addnode"))
15872 {
15873 BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
15874 {
15875 CAddress addr(strAddr, fAllowDNS);
15876 if (addr.IsValid())
15877 {
15878 OpenNetworkConnection(addr);
15879 Sleep(500);
15880 if (fShutdown)
15881 return;
15882 }
15883 }
15884 }
15885
15886 // Initiate network connections
15887 int64 nStart = GetTime();
15888 loop
15889 {
15890 vnThreadsRunning[1]--;
15891 Sleep(500);
15892 vnThreadsRunning[1]++;
15893 if (fShutdown)
15894 return;
15895
15896 // Limit outbound connections
15897 loop
15898 {
15899 int nOutbound = 0;
15900 CRITICAL_BLOCK(cs_vNodes)
15901 BOOST_FOREACH(CNode* pnode, vNodes)
15902 if (!pnode->fInbound)
15903 nOutbound++;
15904 int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
15905 nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
15906 if (nOutbound < nMaxOutboundConnections)
15907 break;
15908 vnThreadsRunning[1]--;
15909 Sleep(2000);
15910 vnThreadsRunning[1]++;
15911 if (fShutdown)
15912 return;
15913 }
15914
15915 bool fAddSeeds = false;
15916
15917 CRITICAL_BLOCK(cs_mapAddresses)
15918 {
15919 // Add seed nodes if IRC isn't working
15920 bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
15921 if (mapAddresses.empty() && (GetTime() - nStart > 60 || fUseProxy) && !fTestNet)
15922 fAddSeeds = true;
15923 }
15924
15925 if (fAddSeeds)
15926 {
15927 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
15928 {
15929 // It'll only connect to one or two seed nodes because once it connects,
15930 // it'll get a pile of addresses with newer timestamps.
15931 // Seed nodes are given a random 'last seen time' of between one and two
15932 // weeks ago.
15933 const int64 nOneWeek = 7*24*60*60;
15934 CAddress addr;
15935 addr.ip = pnSeed[i];
15936 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
15937 AddAddress(addr);
15938 }
15939 }
15940
15941 //
15942 // Choose an address to connect to based on most recently seen
15943 //
15944 CAddress addrConnect;
15945 int64 nBest = INT64_MIN;
15946
15947 // Only connect to one address per a.b.?.? range.
15948 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
15949 set<unsigned int> setConnected;
15950 CRITICAL_BLOCK(cs_vNodes)
15951 BOOST_FOREACH(CNode* pnode, vNodes)
15952 setConnected.insert(pnode->addr.ip & 0x0000ffff);
15953
15954 int64 nANow = GetAdjustedTime();
15955
15956 CRITICAL_BLOCK(cs_mapAddresses)
15957 {
15958 BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
15959 {
15960 const CAddress& addr = item.second;
15961 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
15962 continue;
15963 int64 nSinceLastSeen = nANow - addr.nTime;
15964 int64 nSinceLastTry = nANow - addr.nLastTry;
15965
15966 // Randomize the order in a deterministic way, putting the standard port first
15967 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
15968 if (addr.port != htons(GetDefaultPort()))
15969 nRandomizer += 2 * 60 * 60;
15970
15971 // Last seen Base retry frequency
15972 // <1 hour 10 min
15973 // 1 hour 1 hour
15974 // 4 hours 2 hours
15975 // 24 hours 5 hours
15976 // 48 hours 7 hours
15977 // 7 days 13 hours
15978 // 30 days 27 hours
15979 // 90 days 46 hours
15980 // 365 days 93 hours
15981 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
15982
15983 // Fast reconnect for one hour after last seen
15984 if (nSinceLastSeen < 60 * 60)
15985 nDelay = 10 * 60;
15986
15987 // Limit retry frequency
15988 if (nSinceLastTry < nDelay)
15989 continue;
15990
15991 // If we have IRC, we'll be notified when they first come online,
15992 // and again every 24 hours by the refresh broadcast.
15993 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
15994 continue;
15995
15996 // Only try the old stuff if we don't have enough connections
15997 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
15998 continue;
15999
16000 // If multiple addresses are ready, prioritize by time since
16001 // last seen and time since last tried.
16002 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
16003 if (nScore > nBest)
16004 {
16005 nBest = nScore;
16006 addrConnect = addr;
16007 }
16008 }
16009 }
16010
16011 if (addrConnect.IsValid())
16012 OpenNetworkConnection(addrConnect);
16013 }
16014 }
16015
16016 bool OpenNetworkConnection(const CAddress& addrConnect)
16017 {
16018 //
16019 // Initiate outbound network connection
16020 //
16021 if (fShutdown)
16022 return false;
16023 if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() ||
16024 FindNode(addrConnect.ip) || CNode::IsBanned(addrConnect.ip))
16025 return false;
16026
16027 vnThreadsRunning[1]--;
16028 CNode* pnode = ConnectNode(addrConnect);
16029 vnThreadsRunning[1]++;
16030 if (fShutdown)
16031 return false;
16032 if (!pnode)
16033 return false;
16034 pnode->fNetworkNode = true;
16035
16036 return true;
16037 }
16038
16039
16040
16041
16042
16043
16044
16045
16046 void ThreadMessageHandler(void* parg)
16047 {
16048 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
16049 try
16050 {
16051 vnThreadsRunning[2]++;
16052 ThreadMessageHandler2(parg);
16053 vnThreadsRunning[2]--;
16054 }
16055 catch (std::exception& e) {
16056 vnThreadsRunning[2]--;
16057 PrintException(&e, "ThreadMessageHandler()");
16058 } catch (...) {
16059 vnThreadsRunning[2]--;
16060 PrintException(NULL, "ThreadMessageHandler()");
16061 }
16062 printf("ThreadMessageHandler exiting\n");
16063 }
16064
16065 void ThreadMessageHandler2(void* parg)
16066 {
16067 printf("ThreadMessageHandler started\n");
16068 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
16069 while (!fShutdown)
16070 {
16071 vector<CNode*> vNodesCopy;
16072 CRITICAL_BLOCK(cs_vNodes)
16073 {
16074 vNodesCopy = vNodes;
16075 BOOST_FOREACH(CNode* pnode, vNodesCopy)
16076 pnode->AddRef();
16077 }
16078
16079 // Poll the connected nodes for messages
16080 CNode* pnodeTrickle = NULL;
16081 if (!vNodesCopy.empty())
16082 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
16083 BOOST_FOREACH(CNode* pnode, vNodesCopy)
16084 {
16085 // Receive messages
16086 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
16087 ProcessMessages(pnode);
16088 if (fShutdown)
16089 return;
16090
16091 // Send messages
16092 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
16093 SendMessages(pnode, pnode == pnodeTrickle);
16094 if (fShutdown)
16095 return;
16096 }
16097
16098 CRITICAL_BLOCK(cs_vNodes)
16099 {
16100 BOOST_FOREACH(CNode* pnode, vNodesCopy)
16101 pnode->Release();
16102 }
16103
16104 // Wait and allow messages to bunch up.
16105 // Reduce vnThreadsRunning so StopNode has permission to exit while
16106 // we're sleeping, but we must always check fShutdown after doing this.
16107 vnThreadsRunning[2]--;
16108 Sleep(100);
16109 if (fRequestShutdown)
16110 Shutdown(NULL);
16111 vnThreadsRunning[2]++;
16112 if (fShutdown)
16113 return;
16114 }
16115 }
16116
16117
16118
16119
16120
16121
16122 bool BindListenPort(string& strError)
16123 {
16124 strError = "";
16125 int nOne = 1;
16126 addrLocalHost.port = htons(GetListenPort());
16127
16128 #ifdef WIN32
16129 // Initialize Windows Sockets
16130 WSADATA wsadata;
16131 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
16132 if (ret != NO_ERROR)
16133 {
16134 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
16135 printf("%s\n", strError.c_str());
16136 return false;
16137 }
16138 #endif
16139
16140 // Create socket for listening for incoming connections
16141 hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
16142 if (hListenSocket == INVALID_SOCKET)
16143 {
16144 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
16145 printf("%s\n", strError.c_str());
16146 return false;
16147 }
16148
16149 #ifdef SO_NOSIGPIPE
16150 // Different way of disabling SIGPIPE on BSD
16151 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
16152 #endif
16153
16154 #ifndef WIN32
16155 // Allow binding if the port is still in TIME_WAIT state after
16156 // the program was closed and restarted. Not an issue on windows.
16157 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
16158 #endif
16159
16160 #ifdef WIN32
16161 // Set to nonblocking, incoming connections will also inherit this
16162 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
16163 #else
16164 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
16165 #endif
16166 {
16167 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
16168 printf("%s\n", strError.c_str());
16169 return false;
16170 }
16171
16172 // The sockaddr_in structure specifies the address family,
16173 // IP address, and port for the socket that is being bound
16174 struct sockaddr_in sockaddr;
16175 memset(&sockaddr, 0, sizeof(sockaddr));
16176 sockaddr.sin_family = AF_INET;
16177 sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
16178 sockaddr.sin_port = htons(GetListenPort());
16179 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
16180 {
16181 int nErr = WSAGetLastError();
16182 if (nErr == WSAEADDRINUSE)
16183 strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
16184 else
16185 strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
16186 printf("%s\n", strError.c_str());
16187 return false;
16188 }
16189 printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
16190
16191 // Listen for incoming connections
16192 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
16193 {
16194 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
16195 printf("%s\n", strError.c_str());
16196 return false;
16197 }
16198
16199 return true;
16200 }
16201
16202 void StartNode(void* parg)
16203 {
16204 if (pnodeLocalHost == NULL)
16205 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", 0, false, nLocalServices));
16206
16207 #ifdef WIN32
16208 // Get local host ip
16209 char pszHostName[1000] = "";
16210 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
16211 {
16212 vector<CAddress> vaddr;
16213 if (Lookup(pszHostName, vaddr, nLocalServices, -1, true))
16214 BOOST_FOREACH (const CAddress &addr, vaddr)
16215 if (addr.GetByte(3) != 127)
16216 {
16217 addrLocalHost = addr;
16218 break;
16219 }
16220 }
16221 #else
16222 // Get local host ip
16223 struct ifaddrs* myaddrs;
16224 if (getifaddrs(&myaddrs) == 0)
16225 {
16226 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
16227 {
16228 if (ifa->ifa_addr == NULL) continue;
16229 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
16230 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
16231 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
16232 char pszIP[100];
16233 if (ifa->ifa_addr->sa_family == AF_INET)
16234 {
16235 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
16236 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
16237 printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
16238
16239 // Take the first IP that isn't loopback 127.x.x.x
16240 CAddress addr(*(unsigned int*)&s4->sin_addr, GetListenPort(), nLocalServices);
16241 if (addr.IsValid() && addr.GetByte(3) != 127)
16242 {
16243 addrLocalHost = addr;
16244 break;
16245 }
16246 }
16247 else if (ifa->ifa_addr->sa_family == AF_INET6)
16248 {
16249 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
16250 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
16251 printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
16252 }
16253 }
16254 freeifaddrs(myaddrs);
16255 }
16256 #endif
16257 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
16258
16259 if (fUseProxy || mapArgs.count("-connect") || fNoListen)
16260 {
16261 // Proxies can't take incoming connections
16262 addrLocalHost.ip = CAddress("0.0.0.0").ip;
16263 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
16264 }
16265 else
16266 {
16267 CreateThread(ThreadGetMyExternalIP, NULL);
16268 }
16269
16270 //
16271 // Start threads
16272 //
16273
16274 if (GetBoolArg("-nodnsseed"))
16275 printf("DNS seeding disabled\n");
16276 else
16277 if (!CreateThread(ThreadDNSAddressSeed, NULL))
16278 printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
16279
16280 // Map ports with UPnP
16281 if (fHaveUPnP)
16282 MapPort(fUseUPnP);
16283
16284 // Get addresses from IRC and advertise ours
16285 if (!CreateThread(ThreadIRCSeed, NULL))
16286 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
16287
16288 // Send and receive from sockets, accept connections
16289 if (!CreateThread(ThreadSocketHandler, NULL))
16290 printf("Error: CreateThread(ThreadSocketHandler) failed\n");
16291
16292 // Initiate outbound connections
16293 if (!CreateThread(ThreadOpenConnections, NULL))
16294 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
16295
16296 // Process messages
16297 if (!CreateThread(ThreadMessageHandler, NULL))
16298 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
16299
16300 // Generate coins in the background
16301 GenerateBitcoins(fGenerateBitcoins, pwalletMain);
16302 }
16303
16304 bool StopNode()
16305 {
16306 printf("StopNode()\n");
16307 fShutdown = true;
16308 nTransactionsUpdated++;
16309 int64 nStart = GetTime();
16310 while (vnThreadsRunning[0] > 0 || vnThreadsRunning[1] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
16311 #ifdef USE_UPNP
16312 || vnThreadsRunning[5] > 0
16313 #endif
16314 )
16315 {
16316 if (GetTime() - nStart > 20)
16317 break;
16318 Sleep(20);
16319 }
16320 if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
16321 if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
16322 if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
16323 if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
16324 if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
16325 if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
16326 if (vnThreadsRunning[6] > 0) printf("ThreadDNSAddressSeed still running\n");
16327 while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
16328 Sleep(20);
16329 Sleep(50);
16330
16331 return true;
16332 }
16333
16334 class CNetCleanup
16335 {
16336 public:
16337 CNetCleanup()
16338 {
16339 }
16340 ~CNetCleanup()
16341 {
16342 // Close sockets
16343 BOOST_FOREACH(CNode* pnode, vNodes)
16344 if (pnode->hSocket != INVALID_SOCKET)
16345 closesocket(pnode->hSocket);
16346 if (hListenSocket != INVALID_SOCKET)
16347 if (closesocket(hListenSocket) == SOCKET_ERROR)
16348 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
16349
16350 #ifdef WIN32
16351 // Shutdown Windows Sockets
16352 WSACleanup();
16353 #endif
16354 }
16355 }
16356 instance_of_cnetcleanup;
-
+ 82905169CADF6FB364C8C5073F4B80450A9A995219840FFB1E46F756F35BB9649677C75044D55A017B92C27E32CE5DAC52CDA187A18C3B544756882FF6A57B50
bitcoin/src/net.h
(0 . 0)(1 . 701)
16361 // Copyright (c) 2009-2010 Satoshi Nakamoto
16362 // Copyright (c) 2009-2012 The Bitcoin developers
16363 // Distributed under the MIT/X11 software license, see the accompanying
16364 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
16365 #ifndef BITCOIN_NET_H
16366 #define BITCOIN_NET_H
16367
16368 #include <deque>
16369 #include <boost/array.hpp>
16370 #include <boost/foreach.hpp>
16371 #include <openssl/rand.h>
16372
16373 #ifndef WIN32
16374 #include <arpa/inet.h>
16375 #endif
16376
16377 #include "protocol.h"
16378
16379 class CAddrDB;
16380 class CRequestTracker;
16381 class CNode;
16382 class CBlockIndex;
16383 extern int nBestHeight;
16384 extern int nConnectTimeout;
16385
16386
16387
16388 inline unsigned int ReceiveBufferSize() { return 1000*GetArg("-maxreceivebuffer", 10*1000); }
16389 inline unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 10*1000); }
16390 static const unsigned int PUBLISH_HOPS = 5;
16391
16392 bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet, int nTimeout=nConnectTimeout);
16393 bool Lookup(const char *pszName, std::vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup = false, int portDefault = 0, bool fAllowPort = false);
16394 bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup = false, int portDefault = 0, bool fAllowPort = false);
16395 bool GetMyExternalIP(unsigned int& ipRet);
16396 bool AddAddress(CAddress addr, int64 nTimePenalty=0, CAddrDB *pAddrDB=NULL);
16397 void AddressCurrentlyConnected(const CAddress& addr);
16398 CNode* FindNode(unsigned int ip);
16399 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0);
16400 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1);
16401 bool AnySubscribed(unsigned int nChannel);
16402 void MapPort(bool fMapPort);
16403 bool BindListenPort(std::string& strError=REF(std::string()));
16404 void StartNode(void* parg);
16405 bool StopNode();
16406
16407 enum
16408 {
16409 MSG_TX = 1,
16410 MSG_BLOCK,
16411 };
16412
16413 class CRequestTracker
16414 {
16415 public:
16416 void (*fn)(void*, CDataStream&);
16417 void* param1;
16418
16419 explicit CRequestTracker(void (*fnIn)(void*, CDataStream&)=NULL, void* param1In=NULL)
16420 {
16421 fn = fnIn;
16422 param1 = param1In;
16423 }
16424
16425 bool IsNull()
16426 {
16427 return fn == NULL;
16428 }
16429 };
16430
16431
16432
16433
16434
16435 extern bool fClient;
16436 extern bool fAllowDNS;
16437 extern uint64 nLocalServices;
16438 extern CAddress addrLocalHost;
16439 extern uint64 nLocalHostNonce;
16440 extern boost::array<int, 10> vnThreadsRunning;
16441
16442 extern std::vector<CNode*> vNodes;
16443 extern CCriticalSection cs_vNodes;
16444 extern std::map<std::vector<unsigned char>, CAddress> mapAddresses;
16445 extern CCriticalSection cs_mapAddresses;
16446 extern std::map<CInv, CDataStream> mapRelay;
16447 extern std::deque<std::pair<int64, CInv> > vRelayExpiration;
16448 extern CCriticalSection cs_mapRelay;
16449 extern std::map<CInv, int64> mapAlreadyAskedFor;
16450
16451 // Settings
16452 extern int fUseProxy;
16453 extern CAddress addrProxy;
16454
16455
16456
16457
16458
16459
16460 class CNode
16461 {
16462 public:
16463 // socket
16464 uint64 nServices;
16465 SOCKET hSocket;
16466 CDataStream vSend;
16467 CDataStream vRecv;
16468 CCriticalSection cs_vSend;
16469 CCriticalSection cs_vRecv;
16470 int64 nLastSend;
16471 int64 nLastRecv;
16472 int64 nLastSendEmpty;
16473 int64 nTimeConnected;
16474 unsigned int nHeaderStart;
16475 unsigned int nMessageStart;
16476 CAddress addr;
16477 int nVersion;
16478 std::string strSubVer;
16479 bool fClient;
16480 bool fInbound;
16481 bool fNetworkNode;
16482 bool fSuccessfullyConnected;
16483 bool fDisconnect;
16484 protected:
16485 int nRefCount;
16486
16487 // Denial-of-service detection/prevention
16488 // Key is ip address, value is banned-until-time
16489 static std::map<unsigned int, int64> setBanned;
16490 static CCriticalSection cs_setBanned;
16491 int nMisbehavior;
16492
16493 public:
16494 int64 nReleaseTime;
16495 std::map<uint256, CRequestTracker> mapRequests;
16496 CCriticalSection cs_mapRequests;
16497 uint256 hashContinue;
16498 CBlockIndex* pindexLastGetBlocksBegin;
16499 uint256 hashLastGetBlocksEnd;
16500 int nStartingHeight;
16501
16502 // flood relay
16503 std::vector<CAddress> vAddrToSend;
16504 std::set<CAddress> setAddrKnown;
16505 bool fGetAddr;
16506 std::set<uint256> setKnown;
16507
16508 // inventory based relay
16509 std::set<CInv> setInventoryKnown;
16510 std::vector<CInv> vInventoryToSend;
16511 CCriticalSection cs_inventory;
16512 std::multimap<int64, CInv> mapAskFor;
16513
16514 // publish and subscription
16515 std::vector<char> vfSubscribe;
16516
16517 CNode(SOCKET hSocketIn, CAddress addrIn, bool fInboundIn=false)
16518 {
16519 nServices = 0;
16520 hSocket = hSocketIn;
16521 vSend.SetType(SER_NETWORK);
16522 vSend.SetVersion(0);
16523 vRecv.SetType(SER_NETWORK);
16524 vRecv.SetVersion(0);
16525 // Version 0.2 obsoletes 20 Feb 2012
16526 if (GetTime() > 1329696000)
16527 {
16528 vSend.SetVersion(209);
16529 vRecv.SetVersion(209);
16530 }
16531 nLastSend = 0;
16532 nLastRecv = 0;
16533 nLastSendEmpty = GetTime();
16534 nTimeConnected = GetTime();
16535 nHeaderStart = -1;
16536 nMessageStart = -1;
16537 addr = addrIn;
16538 nVersion = 0;
16539 strSubVer = "";
16540 fClient = false; // set by version message
16541 fInbound = fInboundIn;
16542 fNetworkNode = false;
16543 fSuccessfullyConnected = false;
16544 fDisconnect = false;
16545 nRefCount = 0;
16546 nReleaseTime = 0;
16547 hashContinue = 0;
16548 pindexLastGetBlocksBegin = 0;
16549 hashLastGetBlocksEnd = 0;
16550 nStartingHeight = -1;
16551 fGetAddr = false;
16552 vfSubscribe.assign(256, false);
16553 nMisbehavior = 0;
16554
16555 // Be shy and don't send version until we hear
16556 if (!fInbound)
16557 PushVersion();
16558 }
16559
16560 ~CNode()
16561 {
16562 if (hSocket != INVALID_SOCKET)
16563 {
16564 closesocket(hSocket);
16565 hSocket = INVALID_SOCKET;
16566 }
16567 }
16568
16569 private:
16570 CNode(const CNode&);
16571 void operator=(const CNode&);
16572 public:
16573
16574
16575 int GetRefCount()
16576 {
16577 return std::max(nRefCount, 0) + (GetTime() < nReleaseTime ? 1 : 0);
16578 }
16579
16580 CNode* AddRef(int64 nTimeout=0)
16581 {
16582 if (nTimeout != 0)
16583 nReleaseTime = std::max(nReleaseTime, GetTime() + nTimeout);
16584 else
16585 nRefCount++;
16586 return this;
16587 }
16588
16589 void Release()
16590 {
16591 nRefCount--;
16592 }
16593
16594
16595
16596 void AddAddressKnown(const CAddress& addr)
16597 {
16598 setAddrKnown.insert(addr);
16599 }
16600
16601 void PushAddress(const CAddress& addr)
16602 {
16603 // Known checking here is only to save space from duplicates.
16604 // SendMessages will filter it again for knowns that were added
16605 // after addresses were pushed.
16606 if (addr.IsValid() && !setAddrKnown.count(addr))
16607 vAddrToSend.push_back(addr);
16608 }
16609
16610
16611 void AddInventoryKnown(const CInv& inv)
16612 {
16613 CRITICAL_BLOCK(cs_inventory)
16614 setInventoryKnown.insert(inv);
16615 }
16616
16617 void PushInventory(const CInv& inv)
16618 {
16619 CRITICAL_BLOCK(cs_inventory)
16620 if (!setInventoryKnown.count(inv))
16621 vInventoryToSend.push_back(inv);
16622 }
16623
16624 void AskFor(const CInv& inv)
16625 {
16626 // We're using mapAskFor as a priority queue,
16627 // the key is the earliest time the request can be sent
16628 int64& nRequestTime = mapAlreadyAskedFor[inv];
16629 printf("askfor %s %"PRI64d"\n", inv.ToString().c_str(), nRequestTime);
16630
16631 // Make sure not to reuse time indexes to keep things in the same order
16632 int64 nNow = (GetTime() - 1) * 1000000;
16633 static int64 nLastTime;
16634 ++nLastTime;
16635 nNow = std::max(nNow, nLastTime);
16636 nLastTime = nNow;
16637
16638 // Each retry is 2 minutes after the last
16639 nRequestTime = std::max(nRequestTime + 2 * 60 * 1000000, nNow);
16640 mapAskFor.insert(std::make_pair(nRequestTime, inv));
16641 }
16642
16643
16644
16645 void BeginMessage(const char* pszCommand)
16646 {
16647 ENTER_CRITICAL_SECTION(cs_vSend);
16648 if (nHeaderStart != -1)
16649 AbortMessage();
16650 nHeaderStart = vSend.size();
16651 vSend << CMessageHeader(pszCommand, 0);
16652 nMessageStart = vSend.size();
16653 if (fDebug) {
16654 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
16655 printf("sending: %s ", pszCommand);
16656 }
16657 }
16658
16659 void AbortMessage()
16660 {
16661 if (nHeaderStart == -1)
16662 return;
16663 vSend.resize(nHeaderStart);
16664 nHeaderStart = -1;
16665 nMessageStart = -1;
16666 LEAVE_CRITICAL_SECTION(cs_vSend);
16667
16668 if (fDebug)
16669 printf("(aborted)\n");
16670 }
16671
16672 void EndMessage()
16673 {
16674 if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
16675 {
16676 printf("dropmessages DROPPING SEND MESSAGE\n");
16677 AbortMessage();
16678 return;
16679 }
16680
16681 if (nHeaderStart == -1)
16682 return;
16683
16684 // Set the size
16685 unsigned int nSize = vSend.size() - nMessageStart;
16686 memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize));
16687
16688 // Set the checksum
16689 if (vSend.GetVersion() >= 209)
16690 {
16691 uint256 hash = Hash(vSend.begin() + nMessageStart, vSend.end());
16692 unsigned int nChecksum = 0;
16693 memcpy(&nChecksum, &hash, sizeof(nChecksum));
16694 assert(nMessageStart - nHeaderStart >= offsetof(CMessageHeader, nChecksum) + sizeof(nChecksum));
16695 memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nChecksum), &nChecksum, sizeof(nChecksum));
16696 }
16697
16698 if (fDebug) {
16699 printf("(%d bytes)\n", nSize);
16700 }
16701
16702 nHeaderStart = -1;
16703 nMessageStart = -1;
16704 LEAVE_CRITICAL_SECTION(cs_vSend);
16705 }
16706
16707 void EndMessageAbortIfEmpty()
16708 {
16709 if (nHeaderStart == -1)
16710 return;
16711 int nSize = vSend.size() - nMessageStart;
16712 if (nSize > 0)
16713 EndMessage();
16714 else
16715 AbortMessage();
16716 }
16717
16718
16719
16720 void PushVersion()
16721 {
16722 /// when NTP implemented, change to just nTime = GetAdjustedTime()
16723 int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
16724 CAddress addrYou = (fUseProxy ? CAddress("0.0.0.0") : addr);
16725 CAddress addrMe = (fUseProxy || !addrLocalHost.IsRoutable() ? CAddress("0.0.0.0") : addrLocalHost);
16726 RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
16727 PushMessage("version", VERSION, nLocalServices, nTime, addrYou, addrMe,
16728 nLocalHostNonce, std::string(pszSubVer), nBestHeight);
16729 }
16730
16731
16732
16733
16734 void PushMessage(const char* pszCommand)
16735 {
16736 try
16737 {
16738 BeginMessage(pszCommand);
16739 EndMessage();
16740 }
16741 catch (...)
16742 {
16743 AbortMessage();
16744 throw;
16745 }
16746 }
16747
16748 template<typename T1>
16749 void PushMessage(const char* pszCommand, const T1& a1)
16750 {
16751 try
16752 {
16753 BeginMessage(pszCommand);
16754 vSend << a1;
16755 EndMessage();
16756 }
16757 catch (...)
16758 {
16759 AbortMessage();
16760 throw;
16761 }
16762 }
16763
16764 template<typename T1, typename T2>
16765 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2)
16766 {
16767 try
16768 {
16769 BeginMessage(pszCommand);
16770 vSend << a1 << a2;
16771 EndMessage();
16772 }
16773 catch (...)
16774 {
16775 AbortMessage();
16776 throw;
16777 }
16778 }
16779
16780 template<typename T1, typename T2, typename T3>
16781 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3)
16782 {
16783 try
16784 {
16785 BeginMessage(pszCommand);
16786 vSend << a1 << a2 << a3;
16787 EndMessage();
16788 }
16789 catch (...)
16790 {
16791 AbortMessage();
16792 throw;
16793 }
16794 }
16795
16796 template<typename T1, typename T2, typename T3, typename T4>
16797 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4)
16798 {
16799 try
16800 {
16801 BeginMessage(pszCommand);
16802 vSend << a1 << a2 << a3 << a4;
16803 EndMessage();
16804 }
16805 catch (...)
16806 {
16807 AbortMessage();
16808 throw;
16809 }
16810 }
16811
16812 template<typename T1, typename T2, typename T3, typename T4, typename T5>
16813 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5)
16814 {
16815 try
16816 {
16817 BeginMessage(pszCommand);
16818 vSend << a1 << a2 << a3 << a4 << a5;
16819 EndMessage();
16820 }
16821 catch (...)
16822 {
16823 AbortMessage();
16824 throw;
16825 }
16826 }
16827
16828 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
16829 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6)
16830 {
16831 try
16832 {
16833 BeginMessage(pszCommand);
16834 vSend << a1 << a2 << a3 << a4 << a5 << a6;
16835 EndMessage();
16836 }
16837 catch (...)
16838 {
16839 AbortMessage();
16840 throw;
16841 }
16842 }
16843
16844 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
16845 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7)
16846 {
16847 try
16848 {
16849 BeginMessage(pszCommand);
16850 vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7;
16851 EndMessage();
16852 }
16853 catch (...)
16854 {
16855 AbortMessage();
16856 throw;
16857 }
16858 }
16859
16860 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
16861 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7, const T8& a8)
16862 {
16863 try
16864 {
16865 BeginMessage(pszCommand);
16866 vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8;
16867 EndMessage();
16868 }
16869 catch (...)
16870 {
16871 AbortMessage();
16872 throw;
16873 }
16874 }
16875
16876 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
16877 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7, const T8& a8, const T9& a9)
16878 {
16879 try
16880 {
16881 BeginMessage(pszCommand);
16882 vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9;
16883 EndMessage();
16884 }
16885 catch (...)
16886 {
16887 AbortMessage();
16888 throw;
16889 }
16890 }
16891
16892
16893 void PushRequest(const char* pszCommand,
16894 void (*fn)(void*, CDataStream&), void* param1)
16895 {
16896 uint256 hashReply;
16897 RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
16898
16899 CRITICAL_BLOCK(cs_mapRequests)
16900 mapRequests[hashReply] = CRequestTracker(fn, param1);
16901
16902 PushMessage(pszCommand, hashReply);
16903 }
16904
16905 template<typename T1>
16906 void PushRequest(const char* pszCommand, const T1& a1,
16907 void (*fn)(void*, CDataStream&), void* param1)
16908 {
16909 uint256 hashReply;
16910 RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
16911
16912 CRITICAL_BLOCK(cs_mapRequests)
16913 mapRequests[hashReply] = CRequestTracker(fn, param1);
16914
16915 PushMessage(pszCommand, hashReply, a1);
16916 }
16917
16918 template<typename T1, typename T2>
16919 void PushRequest(const char* pszCommand, const T1& a1, const T2& a2,
16920 void (*fn)(void*, CDataStream&), void* param1)
16921 {
16922 uint256 hashReply;
16923 RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
16924
16925 CRITICAL_BLOCK(cs_mapRequests)
16926 mapRequests[hashReply] = CRequestTracker(fn, param1);
16927
16928 PushMessage(pszCommand, hashReply, a1, a2);
16929 }
16930
16931
16932
16933 void PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd);
16934 bool IsSubscribed(unsigned int nChannel);
16935 void Subscribe(unsigned int nChannel, unsigned int nHops=0);
16936 void CancelSubscribe(unsigned int nChannel);
16937 void CloseSocketDisconnect();
16938 void Cleanup();
16939
16940
16941 // Denial-of-service detection/prevention
16942 // The idea is to detect peers that are behaving
16943 // badly and disconnect/ban them, but do it in a
16944 // one-coding-mistake-won't-shatter-the-entire-network
16945 // way.
16946 // IMPORTANT: There should be nothing I can give a
16947 // node that it will forward on that will make that
16948 // node's peers drop it. If there is, an attacker
16949 // can isolate a node and/or try to split the network.
16950 // Dropping a node for sending stuff that is invalid
16951 // now but might be valid in a later version is also
16952 // dangerous, because it can cause a network split
16953 // between nodes running old code and nodes running
16954 // new code.
16955 static void ClearBanned(); // needed for unit testing
16956 static bool IsBanned(unsigned int ip);
16957 bool Misbehaving(int howmuch); // 1 == a little, 100 == a lot
16958 };
16959
16960
16961
16962
16963
16964
16965
16966
16967
16968
16969 inline void RelayInventory(const CInv& inv)
16970 {
16971 // Put on lists to offer to the other nodes
16972 CRITICAL_BLOCK(cs_vNodes)
16973 BOOST_FOREACH(CNode* pnode, vNodes)
16974 pnode->PushInventory(inv);
16975 }
16976
16977 template<typename T>
16978 void RelayMessage(const CInv& inv, const T& a)
16979 {
16980 CDataStream ss(SER_NETWORK);
16981 ss.reserve(10000);
16982 ss << a;
16983 RelayMessage(inv, ss);
16984 }
16985
16986 template<>
16987 inline void RelayMessage<>(const CInv& inv, const CDataStream& ss)
16988 {
16989 CRITICAL_BLOCK(cs_mapRelay)
16990 {
16991 // Expire old relay messages
16992 while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
16993 {
16994 mapRelay.erase(vRelayExpiration.front().second);
16995 vRelayExpiration.pop_front();
16996 }
16997
16998 // Save original serialized message so newer versions are preserved
16999 mapRelay[inv] = ss;
17000 vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv));
17001 }
17002
17003 RelayInventory(inv);
17004 }
17005
17006
17007
17008
17009
17010
17011
17012
17013 //
17014 // Templates for the publish and subscription system.
17015 // The object being published as T& obj needs to have:
17016 // a set<unsigned int> setSources member
17017 // specializations of AdvertInsert and AdvertErase
17018 // Currently implemented for CTable and CProduct.
17019 //
17020
17021 template<typename T>
17022 void AdvertStartPublish(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj)
17023 {
17024 // Add to sources
17025 obj.setSources.insert(pfrom->addr.ip);
17026
17027 if (!AdvertInsert(obj))
17028 return;
17029
17030 // Relay
17031 CRITICAL_BLOCK(cs_vNodes)
17032 BOOST_FOREACH(CNode* pnode, vNodes)
17033 if (pnode != pfrom && (nHops < PUBLISH_HOPS || pnode->IsSubscribed(nChannel)))
17034 pnode->PushMessage("publish", nChannel, nHops, obj);
17035 }
17036
17037 template<typename T>
17038 void AdvertStopPublish(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj)
17039 {
17040 uint256 hash = obj.GetHash();
17041
17042 CRITICAL_BLOCK(cs_vNodes)
17043 BOOST_FOREACH(CNode* pnode, vNodes)
17044 if (pnode != pfrom && (nHops < PUBLISH_HOPS || pnode->IsSubscribed(nChannel)))
17045 pnode->PushMessage("pub-cancel", nChannel, nHops, hash);
17046
17047 AdvertErase(obj);
17048 }
17049
17050 template<typename T>
17051 void AdvertRemoveSource(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj)
17052 {
17053 // Remove a source
17054 obj.setSources.erase(pfrom->addr.ip);
17055
17056 // If no longer supported by any sources, cancel it
17057 if (obj.setSources.empty())
17058 AdvertStopPublish(pfrom, nChannel, nHops, obj);
17059 }
17060
17061 #endif
-
+ B93609AC9804DD4A668C9A0D6D6D96085D4F18068E96F75896DA5921AF274F5EDA3F45F2D6114305C259C4203875E9196B9551F9C3F60210E6CBE52B3507EC30
bitcoin/src/noui.h
(0 . 0)(1 . 74)
17066 // Copyright (c) 2010 Satoshi Nakamoto
17067 // Copyright (c) 2011 The Bitcoin developers
17068 // Distributed under the MIT/X11 software license, see the accompanying
17069 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
17070 #ifndef BITCOIN_NOUI_H
17071 #define BITCOIN_NOUI_H
17072
17073 #include <string>
17074 #include <boost/function.hpp>
17075 #include "wallet.h"
17076
17077 typedef void wxWindow;
17078 #define wxYES 0x00000002
17079 #define wxOK 0x00000004
17080 #define wxNO 0x00000008
17081 #define wxYES_NO (wxYES|wxNO)
17082 #define wxCANCEL 0x00000010
17083 #define wxAPPLY 0x00000020
17084 #define wxCLOSE 0x00000040
17085 #define wxOK_DEFAULT 0x00000000
17086 #define wxYES_DEFAULT 0x00000000
17087 #define wxNO_DEFAULT 0x00000080
17088 #define wxCANCEL_DEFAULT 0x80000000
17089 #define wxICON_EXCLAMATION 0x00000100
17090 #define wxICON_HAND 0x00000200
17091 #define wxICON_WARNING wxICON_EXCLAMATION
17092 #define wxICON_ERROR wxICON_HAND
17093 #define wxICON_QUESTION 0x00000400
17094 #define wxICON_INFORMATION 0x00000800
17095 #define wxICON_STOP wxICON_HAND
17096 #define wxICON_ASTERISK wxICON_INFORMATION
17097 #define wxICON_MASK (0x00000100|0x00000200|0x00000400|0x00000800)
17098 #define wxFORWARD 0x00001000
17099 #define wxBACKWARD 0x00002000
17100 #define wxRESET 0x00004000
17101 #define wxHELP 0x00008000
17102 #define wxMORE 0x00010000
17103 #define wxSETUP 0x00020000
17104
17105 inline int MyMessageBox(const std::string& message, const std::string& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1)
17106 {
17107 printf("%s: %s\n", caption.c_str(), message.c_str());
17108 fprintf(stderr, "%s: %s\n", caption.c_str(), message.c_str());
17109 return 4;
17110 }
17111 #define wxMessageBox MyMessageBox
17112
17113 inline int ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1)
17114 {
17115 return MyMessageBox(message, caption, style, parent, x, y);
17116 }
17117
17118 inline bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption, wxWindow* parent)
17119 {
17120 return true;
17121 }
17122
17123 inline void CalledSetStatusBar(const std::string& strText, int nField)
17124 {
17125 }
17126
17127 inline void UIThreadCall(boost::function0<void> fn)
17128 {
17129 }
17130
17131 inline void MainFrameRepaint()
17132 {
17133 }
17134
17135 inline void InitMessage(const std::string &message)
17136 {
17137 }
17138
17139 #endif
-
+ 2BD03102D0FF9E7AC45C6D271F59BE9B4A3079F7E7B7C9FA53A9C60DFFF6F7D0CFECC59DDCDCDA6513B89A1B2C4177AFEBAB7514FB6366CA8535C3205FEB5878
bitcoin/src/obj/.gitignore
(0 . 0)(1 . 2)
17144 *
17145 !.gitignore
-
+ 2BD03102D0FF9E7AC45C6D271F59BE9B4A3079F7E7B7C9FA53A9C60DFFF6F7D0CFECC59DDCDCDA6513B89A1B2C4177AFEBAB7514FB6366CA8535C3205FEB5878
bitcoin/src/obj/nogui/.gitignore
(0 . 0)(1 . 2)
17150 *
17151 !.gitignore
-
+ 2BD03102D0FF9E7AC45C6D271F59BE9B4A3079F7E7B7C9FA53A9C60DFFF6F7D0CFECC59DDCDCDA6513B89A1B2C4177AFEBAB7514FB6366CA8535C3205FEB5878
bitcoin/src/obj/test/.gitignore
(0 . 0)(1 . 2)
17156 *
17157 !.gitignore
-
+ 2BD03102D0FF9E7AC45C6D271F59BE9B4A3079F7E7B7C9FA53A9C60DFFF6F7D0CFECC59DDCDCDA6513B89A1B2C4177AFEBAB7514FB6366CA8535C3205FEB5878
bitcoin/src/obj-test/.gitignore
(0 . 0)(1 . 2)
17162 *
17163 !.gitignore
-
+ E76EC1350E05C0FEF1798A50903586ACE4737FAA6DB134094A88A23A96E2A54D8E135A840B822EF136D336B035B3B03B7DED83A99267C892663B15D11AD00720
bitcoin/src/protocol.cpp
(0 . 0)(1 . 312)
17168 // Copyright (c) 2009-2010 Satoshi Nakamoto
17169 // Copyright (c) 2011 The Bitcoin developers
17170 // Distributed under the MIT/X11 software license, see the accompanying
17171 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
17172
17173 #include "protocol.h"
17174 #include "util.h"
17175
17176 #ifndef WIN32
17177 # include <arpa/inet.h>
17178 #endif
17179
17180 // Prototypes from net.h, but that header (currently) stinks, can't #include it without breaking things
17181 bool Lookup(const char *pszName, std::vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup = false, int portDefault = 0, bool fAllowPort = false);
17182 bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup = false, int portDefault = 0, bool fAllowPort = false);
17183
17184 static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
17185 static const char* ppszTypeName[] =
17186 {
17187 "ERROR",
17188 "tx",
17189 "block",
17190 };
17191
17192 CMessageHeader::CMessageHeader()
17193 {
17194 memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart));
17195 memset(pchCommand, 0, sizeof(pchCommand));
17196 pchCommand[1] = 1;
17197 nMessageSize = -1;
17198 nChecksum = 0;
17199 }
17200
17201 CMessageHeader::CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn)
17202 {
17203 memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart));
17204 strncpy(pchCommand, pszCommand, COMMAND_SIZE);
17205 nMessageSize = nMessageSizeIn;
17206 nChecksum = 0;
17207 }
17208
17209 std::string CMessageHeader::GetCommand() const
17210 {
17211 if (pchCommand[COMMAND_SIZE-1] == 0)
17212 return std::string(pchCommand, pchCommand + strlen(pchCommand));
17213 else
17214 return std::string(pchCommand, pchCommand + COMMAND_SIZE);
17215 }
17216
17217 bool CMessageHeader::IsValid() const
17218 {
17219 // Check start string
17220 if (memcmp(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)) != 0)
17221 return false;
17222
17223 // Check the command string for errors
17224 for (const char* p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; p1++)
17225 {
17226 if (*p1 == 0)
17227 {
17228 // Must be all zeros after the first zero
17229 for (; p1 < pchCommand + COMMAND_SIZE; p1++)
17230 if (*p1 != 0)
17231 return false;
17232 }
17233 else if (*p1 < ' ' || *p1 > 0x7E)
17234 return false;
17235 }
17236
17237 // Message size
17238 if (nMessageSize > MAX_SIZE)
17239 {
17240 printf("CMessageHeader::IsValid() : (%s, %u bytes) nMessageSize > MAX_SIZE\n", GetCommand().c_str(), nMessageSize);
17241 return false;
17242 }
17243
17244 return true;
17245 }
17246
17247 CAddress::CAddress()
17248 {
17249 Init();
17250 }
17251
17252 CAddress::CAddress(unsigned int ipIn, unsigned short portIn, uint64 nServicesIn)
17253 {
17254 Init();
17255 ip = ipIn;
17256 port = htons(portIn == 0 ? GetDefaultPort() : portIn);
17257 nServices = nServicesIn;
17258 }
17259
17260 CAddress::CAddress(const struct sockaddr_in& sockaddr, uint64 nServicesIn)
17261 {
17262 Init();
17263 ip = sockaddr.sin_addr.s_addr;
17264 port = sockaddr.sin_port;
17265 nServices = nServicesIn;
17266 }
17267
17268 CAddress::CAddress(const char* pszIn, int portIn, bool fNameLookup, uint64 nServicesIn)
17269 {
17270 Init();
17271 Lookup(pszIn, *this, nServicesIn, fNameLookup, portIn);
17272 }
17273
17274 CAddress::CAddress(const char* pszIn, bool fNameLookup, uint64 nServicesIn)
17275 {
17276 Init();
17277 Lookup(pszIn, *this, nServicesIn, fNameLookup, 0, true);
17278 }
17279
17280 CAddress::CAddress(std::string strIn, int portIn, bool fNameLookup, uint64 nServicesIn)
17281 {
17282 Init();
17283 Lookup(strIn.c_str(), *this, nServicesIn, fNameLookup, portIn);
17284 }
17285
17286 CAddress::CAddress(std::string strIn, bool fNameLookup, uint64 nServicesIn)
17287 {
17288 Init();
17289 Lookup(strIn.c_str(), *this, nServicesIn, fNameLookup, 0, true);
17290 }
17291
17292 void CAddress::Init()
17293 {
17294 nServices = NODE_NETWORK;
17295 memcpy(pchReserved, pchIPv4, sizeof(pchReserved));
17296 ip = INADDR_NONE;
17297 port = htons(GetDefaultPort());
17298 nTime = 100000000;
17299 nLastTry = 0;
17300 }
17301
17302 bool operator==(const CAddress& a, const CAddress& b)
17303 {
17304 return (memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved)) == 0 &&
17305 a.ip == b.ip &&
17306 a.port == b.port);
17307 }
17308
17309 bool operator!=(const CAddress& a, const CAddress& b)
17310 {
17311 return (!(a == b));
17312 }
17313
17314 bool operator<(const CAddress& a, const CAddress& b)
17315 {
17316 int ret = memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved));
17317 if (ret < 0)
17318 return true;
17319 else if (ret == 0)
17320 {
17321 if (ntohl(a.ip) < ntohl(b.ip))
17322 return true;
17323 else if (a.ip == b.ip)
17324 return ntohs(a.port) < ntohs(b.port);
17325 }
17326 return false;
17327 }
17328
17329 std::vector<unsigned char> CAddress::GetKey() const
17330 {
17331 CDataStream ss;
17332 ss.reserve(18);
17333 ss << FLATDATA(pchReserved) << ip << port;
17334
17335 #if defined(_MSC_VER) && _MSC_VER < 1300
17336 return std::vector<unsigned char>((unsigned char*)&ss.begin()[0], (unsigned char*)&ss.end()[0]);
17337 #else
17338 return std::vector<unsigned char>(ss.begin(), ss.end());
17339 #endif
17340 }
17341
17342 struct sockaddr_in CAddress::GetSockAddr() const
17343 {
17344 struct sockaddr_in sockaddr;
17345 memset(&sockaddr, 0, sizeof(sockaddr));
17346 sockaddr.sin_family = AF_INET;
17347 sockaddr.sin_addr.s_addr = ip;
17348 sockaddr.sin_port = port;
17349 return sockaddr;
17350 }
17351
17352 bool CAddress::IsIPv4() const
17353 {
17354 return (memcmp(pchReserved, pchIPv4, sizeof(pchIPv4)) == 0);
17355 }
17356
17357 bool CAddress::IsRFC1918() const
17358 {
17359 return IsIPv4() && (GetByte(3) == 10 ||
17360 (GetByte(3) == 192 && GetByte(2) == 168) ||
17361 (GetByte(3) == 172 &&
17362 (GetByte(2) >= 16 && GetByte(2) <= 31)));
17363 }
17364
17365 bool CAddress::IsRFC3927() const
17366 {
17367 return IsIPv4() && (GetByte(3) == 169 && GetByte(2) == 254);
17368 }
17369
17370 bool CAddress::IsLocal() const
17371 {
17372 return IsIPv4() && (GetByte(3) == 127 ||
17373 GetByte(3) == 0);
17374 }
17375
17376 bool CAddress::IsRoutable() const
17377 {
17378 return IsValid() &&
17379 !(IsRFC1918() || IsRFC3927() || IsLocal());
17380 }
17381
17382 bool CAddress::IsValid() const
17383 {
17384 // Clean up 3-byte shifted addresses caused by garbage in size field
17385 // of addr messages from versions before 0.2.9 checksum.
17386 // Two consecutive addr messages look like this:
17387 // header20 vectorlen3 addr26 addr26 addr26 header20 vectorlen3 addr26 addr26 addr26...
17388 // so if the first length field is garbled, it reads the second batch
17389 // of addr misaligned by 3 bytes.
17390 if (memcmp(pchReserved, pchIPv4+3, sizeof(pchIPv4)-3) == 0)
17391 return false;
17392
17393 return (ip != 0 && ip != INADDR_NONE && port != htons(USHRT_MAX));
17394 }
17395
17396 unsigned char CAddress::GetByte(int n) const
17397 {
17398 return ((unsigned char*)&ip)[3-n];
17399 }
17400
17401 std::string CAddress::ToStringIPPort() const
17402 {
17403 return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port));
17404 }
17405
17406 std::string CAddress::ToStringIP() const
17407 {
17408 return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0));
17409 }
17410
17411 std::string CAddress::ToStringPort() const
17412 {
17413 return strprintf("%u", ntohs(port));
17414 }
17415
17416 std::string CAddress::ToString() const
17417 {
17418 return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port));
17419 }
17420
17421 void CAddress::print() const
17422 {
17423 printf("CAddress(%s)\n", ToString().c_str());
17424 }
17425
17426 CInv::CInv()
17427 {
17428 type = 0;
17429 hash = 0;
17430 }
17431
17432 CInv::CInv(int typeIn, const uint256& hashIn)
17433 {
17434 type = typeIn;
17435 hash = hashIn;
17436 }
17437
17438 CInv::CInv(const std::string& strType, const uint256& hashIn)
17439 {
17440 int i;
17441 for (i = 1; i < ARRAYLEN(ppszTypeName); i++)
17442 {
17443 if (strType == ppszTypeName[i])
17444 {
17445 type = i;
17446 break;
17447 }
17448 }
17449 if (i == ARRAYLEN(ppszTypeName))
17450 throw std::out_of_range(strprintf("CInv::CInv(string, uint256) : unknown type '%s'", strType.c_str()));
17451 hash = hashIn;
17452 }
17453
17454 bool operator<(const CInv& a, const CInv& b)
17455 {
17456 return (a.type < b.type || (a.type == b.type && a.hash < b.hash));
17457 }
17458
17459 bool CInv::IsKnownType() const
17460 {
17461 return (type >= 1 && type < ARRAYLEN(ppszTypeName));
17462 }
17463
17464 const char* CInv::GetCommand() const
17465 {
17466 if (!IsKnownType())
17467 throw std::out_of_range(strprintf("CInv::GetCommand() : type=%d unknown type", type));
17468 return ppszTypeName[type];
17469 }
17470
17471 std::string CInv::ToString() const
17472 {
17473 return strprintf("%s %s", GetCommand(), hash.ToString().substr(0,20).c_str());
17474 }
17475
17476 void CInv::print() const
17477 {
17478 printf("CInv(%s)\n", ToString().c_str());
17479 }
-
+ 9438A1F1A661180998E98347B42EB49363F6C4FEF82F8D970D4D1E0A367AA32055A505431BD86F100929BEA481DCAF6FDD6FC95BB4E1D083E7044AEE102D4479
bitcoin/src/protocol.h
(0 . 0)(1 . 150)
17484 // Copyright (c) 2009-2010 Satoshi Nakamoto
17485 // Copyright (c) 2011 The Bitcoin developers
17486 // Distributed under the MIT/X11 software license, see the accompanying
17487 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
17488
17489 #ifndef __cplusplus
17490 # error This header can only be compiled as C++.
17491 #endif
17492
17493 #ifndef __INCLUDED_PROTOCOL_H__
17494 #define __INCLUDED_PROTOCOL_H__
17495
17496 #include "serialize.h"
17497 #include <string>
17498 #include "uint256.h"
17499
17500 extern bool fTestNet;
17501 static inline unsigned short GetDefaultPort(const bool testnet = fTestNet)
17502 {
17503 return testnet ? 18333 : 8333;
17504 }
17505
17506 //
17507 // Message header
17508 // (4) message start
17509 // (12) command
17510 // (4) size
17511 // (4) checksum
17512
17513 extern unsigned char pchMessageStart[4];
17514
17515 class CMessageHeader
17516 {
17517 public:
17518 CMessageHeader();
17519 CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn);
17520
17521 std::string GetCommand() const;
17522 bool IsValid() const;
17523
17524 IMPLEMENT_SERIALIZE
17525 (
17526 READWRITE(FLATDATA(pchMessageStart));
17527 READWRITE(FLATDATA(pchCommand));
17528 READWRITE(nMessageSize);
17529 if (nVersion >= 209)
17530 READWRITE(nChecksum);
17531 )
17532
17533 // TODO: make private (improves encapsulation)
17534 public:
17535 enum { COMMAND_SIZE=12 };
17536 char pchMessageStart[sizeof(::pchMessageStart)];
17537 char pchCommand[COMMAND_SIZE];
17538 unsigned int nMessageSize;
17539 unsigned int nChecksum;
17540 };
17541
17542 enum
17543 {
17544 NODE_NETWORK = (1 << 0),
17545 };
17546
17547 class CAddress
17548 {
17549 public:
17550 CAddress();
17551 CAddress(unsigned int ipIn, unsigned short portIn=0, uint64 nServicesIn=NODE_NETWORK);
17552 explicit CAddress(const struct sockaddr_in& sockaddr, uint64 nServicesIn=NODE_NETWORK);
17553 explicit CAddress(const char* pszIn, int portIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK);
17554 explicit CAddress(const char* pszIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK);
17555 explicit CAddress(std::string strIn, int portIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK);
17556 explicit CAddress(std::string strIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK);
17557
17558 void Init();
17559
17560 IMPLEMENT_SERIALIZE
17561 (
17562 if (fRead)
17563 const_cast<CAddress*>(this)->Init();
17564 if (nType & SER_DISK)
17565 READWRITE(nVersion);
17566 if ((nType & SER_DISK) || (nVersion >= 31402 && !(nType & SER_GETHASH)))
17567 READWRITE(nTime);
17568 READWRITE(nServices);
17569 READWRITE(FLATDATA(pchReserved)); // for IPv6
17570 READWRITE(ip);
17571 READWRITE(port);
17572 )
17573
17574 friend bool operator==(const CAddress& a, const CAddress& b);
17575 friend bool operator!=(const CAddress& a, const CAddress& b);
17576 friend bool operator<(const CAddress& a, const CAddress& b);
17577
17578 std::vector<unsigned char> GetKey() const;
17579 struct sockaddr_in GetSockAddr() const;
17580 bool IsIPv4() const;
17581 bool IsRFC1918() const;
17582 bool IsRFC3927() const;
17583 bool IsLocal() const;
17584 bool IsRoutable() const;
17585 bool IsValid() const;
17586 unsigned char GetByte(int n) const;
17587 std::string ToStringIPPort() const;
17588 std::string ToStringIP() const;
17589 std::string ToStringPort() const;
17590 std::string ToString() const;
17591 void print() const;
17592
17593 // TODO: make private (improves encapsulation)
17594 public:
17595 uint64 nServices;
17596 unsigned char pchReserved[12];
17597 unsigned int ip;
17598 unsigned short port;
17599
17600 // disk and network only
17601 unsigned int nTime;
17602
17603 // memory only
17604 unsigned int nLastTry;
17605 };
17606
17607 class CInv
17608 {
17609 public:
17610 CInv();
17611 CInv(int typeIn, const uint256& hashIn);
17612 CInv(const std::string& strType, const uint256& hashIn);
17613
17614 IMPLEMENT_SERIALIZE
17615 (
17616 READWRITE(type);
17617 READWRITE(hash);
17618 )
17619
17620 friend bool operator<(const CInv& a, const CInv& b);
17621
17622 bool IsKnownType() const;
17623 const char* GetCommand() const;
17624 std::string ToString() const;
17625 void print() const;
17626
17627 // TODO: make private (improves encapsulation)
17628 public:
17629 int type;
17630 uint256 hash;
17631 };
17632
17633 #endif // __INCLUDED_PROTOCOL_H__
-
+ 66F2B1854332F9019BEBB0786491BE6D0757D51ADAC896B5E42592B3C563346CD9FEB138FC782C52709145E0834E482E5F0320F8066EC22FDC95ABF42FAA6059
bitcoin/src/qtui.h
(0 . 0)(1 . 49)
17638 // Copyright (c) 2010 Satoshi Nakamoto
17639 // Distributed under the MIT/X11 software license, see the accompanying
17640 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
17641 #ifndef BITCOIN_EXTERNUI_H
17642 #define BITCOIN_EXTERNUI_H
17643
17644 #include <string>
17645 #include <boost/function/function0.hpp>
17646 #include "wallet.h"
17647
17648 typedef void wxWindow;
17649 #define wxYES 0x00000002
17650 #define wxOK 0x00000004
17651 #define wxNO 0x00000008
17652 #define wxYES_NO (wxYES|wxNO)
17653 #define wxCANCEL 0x00000010
17654 #define wxAPPLY 0x00000020
17655 #define wxCLOSE 0x00000040
17656 #define wxOK_DEFAULT 0x00000000
17657 #define wxYES_DEFAULT 0x00000000
17658 #define wxNO_DEFAULT 0x00000080
17659 #define wxCANCEL_DEFAULT 0x80000000
17660 #define wxICON_EXCLAMATION 0x00000100
17661 #define wxICON_HAND 0x00000200
17662 #define wxICON_WARNING wxICON_EXCLAMATION
17663 #define wxICON_ERROR wxICON_HAND
17664 #define wxICON_QUESTION 0x00000400
17665 #define wxICON_INFORMATION 0x00000800
17666 #define wxICON_STOP wxICON_HAND
17667 #define wxICON_ASTERISK wxICON_INFORMATION
17668 #define wxICON_MASK (0x00000100|0x00000200|0x00000400|0x00000800)
17669 #define wxFORWARD 0x00001000
17670 #define wxBACKWARD 0x00002000
17671 #define wxRESET 0x00004000
17672 #define wxHELP 0x00008000
17673 #define wxMORE 0x00010000
17674 #define wxSETUP 0x00020000
17675
17676 extern int MyMessageBox(const std::string& message, const std::string& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1);
17677 #define wxMessageBox MyMessageBox
17678 extern int ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1);
17679 extern bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption, wxWindow* parent);
17680 extern void CalledSetStatusBar(const std::string& strText, int nField);
17681 extern void UIThreadCall(boost::function0<void> fn);
17682 extern void MainFrameRepaint();
17683 extern void InitMessage(const std::string &message);
17684 extern std::string _(const char* psz);
17685
17686 #endif
-
+ 8EEB268376FADFC1CD0644F6CB837157BC5085696874CEF65FEA2294B2AFC3784900649952ACF097F08216F2493D22053B873CC1D33EFC639116B9EE1EB751F9
bitcoin/src/script.cpp
(0 . 0)(1 . 1203)
17691 // Copyright (c) 2009-2010 Satoshi Nakamoto
17692 // Copyright (c) 2011 The Bitcoin developers
17693 // Distributed under the MIT/X11 software license, see the accompanying
17694 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
17695 #include "headers.h"
17696
17697 using namespace std;
17698 using namespace boost;
17699
17700 bool CheckSig(vector<unsigned char> vchSig, vector<unsigned char> vchPubKey, CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType);
17701
17702
17703
17704 typedef vector<unsigned char> valtype;
17705 static const valtype vchFalse(0);
17706 static const valtype vchZero(0);
17707 static const valtype vchTrue(1, 1);
17708 static const CBigNum bnZero(0);
17709 static const CBigNum bnOne(1);
17710 static const CBigNum bnFalse(0);
17711 static const CBigNum bnTrue(1);
17712 static const size_t nMaxNumSize = 4;
17713
17714
17715 CBigNum CastToBigNum(const valtype& vch)
17716 {
17717 if (vch.size() > nMaxNumSize)
17718 throw runtime_error("CastToBigNum() : overflow");
17719 // Get rid of extra leading zeros
17720 return CBigNum(CBigNum(vch).getvch());
17721 }
17722
17723 bool CastToBool(const valtype& vch)
17724 {
17725 for (int i = 0; i < vch.size(); i++)
17726 {
17727 if (vch[i] != 0)
17728 {
17729 // Can be negative zero
17730 if (i == vch.size()-1 && vch[i] == 0x80)
17731 return false;
17732 return true;
17733 }
17734 }
17735 return false;
17736 }
17737
17738 void MakeSameSize(valtype& vch1, valtype& vch2)
17739 {
17740 // Lengthen the shorter one
17741 if (vch1.size() < vch2.size())
17742 vch1.resize(vch2.size(), 0);
17743 if (vch2.size() < vch1.size())
17744 vch2.resize(vch1.size(), 0);
17745 }
17746
17747
17748
17749 //
17750 // Script is a stack machine (like Forth) that evaluates a predicate
17751 // returning a bool indicating valid or not. There are no loops.
17752 //
17753 #define stacktop(i) (stack.at(stack.size()+(i)))
17754 #define altstacktop(i) (altstack.at(altstack.size()+(i)))
17755 static inline void popstack(vector<valtype>& stack)
17756 {
17757 if (stack.empty())
17758 throw runtime_error("popstack() : stack empty");
17759 stack.pop_back();
17760 }
17761
17762
17763 bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType)
17764 {
17765 CAutoBN_CTX pctx;
17766 CScript::const_iterator pc = script.begin();
17767 CScript::const_iterator pend = script.end();
17768 CScript::const_iterator pbegincodehash = script.begin();
17769 opcodetype opcode;
17770 valtype vchPushValue;
17771 vector<bool> vfExec;
17772 vector<valtype> altstack;
17773 if (script.size() > 10000)
17774 return false;
17775 int nOpCount = 0;
17776
17777
17778 try
17779 {
17780 while (pc < pend)
17781 {
17782 bool fExec = !count(vfExec.begin(), vfExec.end(), false);
17783
17784 //
17785 // Read instruction
17786 //
17787 if (!script.GetOp(pc, opcode, vchPushValue))
17788 return false;
17789 if (vchPushValue.size() > 520)
17790 return false;
17791 if (opcode > OP_16 && ++nOpCount > 201)
17792 return false;
17793
17794 if (opcode == OP_CAT ||
17795 opcode == OP_SUBSTR ||
17796 opcode == OP_LEFT ||
17797 opcode == OP_RIGHT ||
17798 opcode == OP_INVERT ||
17799 opcode == OP_AND ||
17800 opcode == OP_OR ||
17801 opcode == OP_XOR ||
17802 opcode == OP_2MUL ||
17803 opcode == OP_2DIV ||
17804 opcode == OP_MUL ||
17805 opcode == OP_DIV ||
17806 opcode == OP_MOD ||
17807 opcode == OP_LSHIFT ||
17808 opcode == OP_RSHIFT)
17809 return false;
17810
17811 if (fExec && 0 <= opcode && opcode <= OP_PUSHDATA4)
17812 stack.push_back(vchPushValue);
17813 else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF))
17814 switch (opcode)
17815 {
17816 //
17817 // Push value
17818 //
17819 case OP_1NEGATE:
17820 case OP_1:
17821 case OP_2:
17822 case OP_3:
17823 case OP_4:
17824 case OP_5:
17825 case OP_6:
17826 case OP_7:
17827 case OP_8:
17828 case OP_9:
17829 case OP_10:
17830 case OP_11:
17831 case OP_12:
17832 case OP_13:
17833 case OP_14:
17834 case OP_15:
17835 case OP_16:
17836 {
17837 // ( -- value)
17838 CBigNum bn((int)opcode - (int)(OP_1 - 1));
17839 stack.push_back(bn.getvch());
17840 }
17841 break;
17842
17843
17844 //
17845 // Control
17846 //
17847 case OP_NOP:
17848 case OP_NOP1: case OP_NOP2: case OP_NOP3: case OP_NOP4: case OP_NOP5:
17849 case OP_NOP6: case OP_NOP7: case OP_NOP8: case OP_NOP9: case OP_NOP10:
17850 break;
17851
17852 case OP_IF:
17853 case OP_NOTIF:
17854 {
17855 // <expression> if [statements] [else [statements]] endif
17856 bool fValue = false;
17857 if (fExec)
17858 {
17859 if (stack.size() < 1)
17860 return false;
17861 valtype& vch = stacktop(-1);
17862 fValue = CastToBool(vch);
17863 if (opcode == OP_NOTIF)
17864 fValue = !fValue;
17865 popstack(stack);
17866 }
17867 vfExec.push_back(fValue);
17868 }
17869 break;
17870
17871 case OP_ELSE:
17872 {
17873 if (vfExec.empty())
17874 return false;
17875 vfExec.back() = !vfExec.back();
17876 }
17877 break;
17878
17879 case OP_ENDIF:
17880 {
17881 if (vfExec.empty())
17882 return false;
17883 vfExec.pop_back();
17884 }
17885 break;
17886
17887 case OP_VERIFY:
17888 {
17889 // (true -- ) or
17890 // (false -- false) and return
17891 if (stack.size() < 1)
17892 return false;
17893 bool fValue = CastToBool(stacktop(-1));
17894 if (fValue)
17895 popstack(stack);
17896 else
17897 return false;
17898 }
17899 break;
17900
17901 case OP_RETURN:
17902 {
17903 return false;
17904 }
17905 break;
17906
17907
17908 //
17909 // Stack ops
17910 //
17911 case OP_TOALTSTACK:
17912 {
17913 if (stack.size() < 1)
17914 return false;
17915 altstack.push_back(stacktop(-1));
17916 popstack(stack);
17917 }
17918 break;
17919
17920 case OP_FROMALTSTACK:
17921 {
17922 if (altstack.size() < 1)
17923 return false;
17924 stack.push_back(altstacktop(-1));
17925 popstack(altstack);
17926 }
17927 break;
17928
17929 case OP_2DROP:
17930 {
17931 // (x1 x2 -- )
17932 if (stack.size() < 2)
17933 return false;
17934 popstack(stack);
17935 popstack(stack);
17936 }
17937 break;
17938
17939 case OP_2DUP:
17940 {
17941 // (x1 x2 -- x1 x2 x1 x2)
17942 if (stack.size() < 2)
17943 return false;
17944 valtype vch1 = stacktop(-2);
17945 valtype vch2 = stacktop(-1);
17946 stack.push_back(vch1);
17947 stack.push_back(vch2);
17948 }
17949 break;
17950
17951 case OP_3DUP:
17952 {
17953 // (x1 x2 x3 -- x1 x2 x3 x1 x2 x3)
17954 if (stack.size() < 3)
17955 return false;
17956 valtype vch1 = stacktop(-3);
17957 valtype vch2 = stacktop(-2);
17958 valtype vch3 = stacktop(-1);
17959 stack.push_back(vch1);
17960 stack.push_back(vch2);
17961 stack.push_back(vch3);
17962 }
17963 break;
17964
17965 case OP_2OVER:
17966 {
17967 // (x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2)
17968 if (stack.size() < 4)
17969 return false;
17970 valtype vch1 = stacktop(-4);
17971 valtype vch2 = stacktop(-3);
17972 stack.push_back(vch1);
17973 stack.push_back(vch2);
17974 }
17975 break;
17976
17977 case OP_2ROT:
17978 {
17979 // (x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2)
17980 if (stack.size() < 6)
17981 return false;
17982 valtype vch1 = stacktop(-6);
17983 valtype vch2 = stacktop(-5);
17984 stack.erase(stack.end()-6, stack.end()-4);
17985 stack.push_back(vch1);
17986 stack.push_back(vch2);
17987 }
17988 break;
17989
17990 case OP_2SWAP:
17991 {
17992 // (x1 x2 x3 x4 -- x3 x4 x1 x2)
17993 if (stack.size() < 4)
17994 return false;
17995 swap(stacktop(-4), stacktop(-2));
17996 swap(stacktop(-3), stacktop(-1));
17997 }
17998 break;
17999
18000 case OP_IFDUP:
18001 {
18002 // (x - 0 | x x)
18003 if (stack.size() < 1)
18004 return false;
18005 valtype vch = stacktop(-1);
18006 if (CastToBool(vch))
18007 stack.push_back(vch);
18008 }
18009 break;
18010
18011 case OP_DEPTH:
18012 {
18013 // -- stacksize
18014 CBigNum bn(stack.size());
18015 stack.push_back(bn.getvch());
18016 }
18017 break;
18018
18019 case OP_DROP:
18020 {
18021 // (x -- )
18022 if (stack.size() < 1)
18023 return false;
18024 popstack(stack);
18025 }
18026 break;
18027
18028 case OP_DUP:
18029 {
18030 // (x -- x x)
18031 if (stack.size() < 1)
18032 return false;
18033 valtype vch = stacktop(-1);
18034 stack.push_back(vch);
18035 }
18036 break;
18037
18038 case OP_NIP:
18039 {
18040 // (x1 x2 -- x2)
18041 if (stack.size() < 2)
18042 return false;
18043 stack.erase(stack.end() - 2);
18044 }
18045 break;
18046
18047 case OP_OVER:
18048 {
18049 // (x1 x2 -- x1 x2 x1)
18050 if (stack.size() < 2)
18051 return false;
18052 valtype vch = stacktop(-2);
18053 stack.push_back(vch);
18054 }
18055 break;
18056
18057 case OP_PICK:
18058 case OP_ROLL:
18059 {
18060 // (xn ... x2 x1 x0 n - xn ... x2 x1 x0 xn)
18061 // (xn ... x2 x1 x0 n - ... x2 x1 x0 xn)
18062 if (stack.size() < 2)
18063 return false;
18064 int n = CastToBigNum(stacktop(-1)).getint();
18065 popstack(stack);
18066 if (n < 0 || n >= stack.size())
18067 return false;
18068 valtype vch = stacktop(-n-1);
18069 if (opcode == OP_ROLL)
18070 stack.erase(stack.end()-n-1);
18071 stack.push_back(vch);
18072 }
18073 break;
18074
18075 case OP_ROT:
18076 {
18077 // (x1 x2 x3 -- x2 x3 x1)
18078 // x2 x1 x3 after first swap
18079 // x2 x3 x1 after second swap
18080 if (stack.size() < 3)
18081 return false;
18082 swap(stacktop(-3), stacktop(-2));
18083 swap(stacktop(-2), stacktop(-1));
18084 }
18085 break;
18086
18087 case OP_SWAP:
18088 {
18089 // (x1 x2 -- x2 x1)
18090 if (stack.size() < 2)
18091 return false;
18092 swap(stacktop(-2), stacktop(-1));
18093 }
18094 break;
18095
18096 case OP_TUCK:
18097 {
18098 // (x1 x2 -- x2 x1 x2)
18099 if (stack.size() < 2)
18100 return false;
18101 valtype vch = stacktop(-1);
18102 stack.insert(stack.end()-2, vch);
18103 }
18104 break;
18105
18106
18107 //
18108 // Splice ops
18109 //
18110 case OP_CAT:
18111 {
18112 // (x1 x2 -- out)
18113 if (stack.size() < 2)
18114 return false;
18115 valtype& vch1 = stacktop(-2);
18116 valtype& vch2 = stacktop(-1);
18117 vch1.insert(vch1.end(), vch2.begin(), vch2.end());
18118 popstack(stack);
18119 if (stacktop(-1).size() > 520)
18120 return false;
18121 }
18122 break;
18123
18124 case OP_SUBSTR:
18125 {
18126 // (in begin size -- out)
18127 if (stack.size() < 3)
18128 return false;
18129 valtype& vch = stacktop(-3);
18130 int nBegin = CastToBigNum(stacktop(-2)).getint();
18131 int nEnd = nBegin + CastToBigNum(stacktop(-1)).getint();
18132 if (nBegin < 0 || nEnd < nBegin)
18133 return false;
18134 if (nBegin > vch.size())
18135 nBegin = vch.size();
18136 if (nEnd > vch.size())
18137 nEnd = vch.size();
18138 vch.erase(vch.begin() + nEnd, vch.end());
18139 vch.erase(vch.begin(), vch.begin() + nBegin);
18140 popstack(stack);
18141 popstack(stack);
18142 }
18143 break;
18144
18145 case OP_LEFT:
18146 case OP_RIGHT:
18147 {
18148 // (in size -- out)
18149 if (stack.size() < 2)
18150 return false;
18151 valtype& vch = stacktop(-2);
18152 int nSize = CastToBigNum(stacktop(-1)).getint();
18153 if (nSize < 0)
18154 return false;
18155 if (nSize > vch.size())
18156 nSize = vch.size();
18157 if (opcode == OP_LEFT)
18158 vch.erase(vch.begin() + nSize, vch.end());
18159 else
18160 vch.erase(vch.begin(), vch.end() - nSize);
18161 popstack(stack);
18162 }
18163 break;
18164
18165 case OP_SIZE:
18166 {
18167 // (in -- in size)
18168 if (stack.size() < 1)
18169 return false;
18170 CBigNum bn(stacktop(-1).size());
18171 stack.push_back(bn.getvch());
18172 }
18173 break;
18174
18175
18176 //
18177 // Bitwise logic
18178 //
18179 case OP_INVERT:
18180 {
18181 // (in - out)
18182 if (stack.size() < 1)
18183 return false;
18184 valtype& vch = stacktop(-1);
18185 for (int i = 0; i < vch.size(); i++)
18186 vch[i] = ~vch[i];
18187 }
18188 break;
18189
18190 case OP_AND:
18191 case OP_OR:
18192 case OP_XOR:
18193 {
18194 // (x1 x2 - out)
18195 if (stack.size() < 2)
18196 return false;
18197 valtype& vch1 = stacktop(-2);
18198 valtype& vch2 = stacktop(-1);
18199 MakeSameSize(vch1, vch2);
18200 if (opcode == OP_AND)
18201 {
18202 for (int i = 0; i < vch1.size(); i++)
18203 vch1[i] &= vch2[i];
18204 }
18205 else if (opcode == OP_OR)
18206 {
18207 for (int i = 0; i < vch1.size(); i++)
18208 vch1[i] |= vch2[i];
18209 }
18210 else if (opcode == OP_XOR)
18211 {
18212 for (int i = 0; i < vch1.size(); i++)
18213 vch1[i] ^= vch2[i];
18214 }
18215 popstack(stack);
18216 }
18217 break;
18218
18219 case OP_EQUAL:
18220 case OP_EQUALVERIFY:
18221 //case OP_NOTEQUAL: // use OP_NUMNOTEQUAL
18222 {
18223 // (x1 x2 - bool)
18224 if (stack.size() < 2)
18225 return false;
18226 valtype& vch1 = stacktop(-2);
18227 valtype& vch2 = stacktop(-1);
18228 bool fEqual = (vch1 == vch2);
18229 // OP_NOTEQUAL is disabled because it would be too easy to say
18230 // something like n != 1 and have some wiseguy pass in 1 with extra
18231 // zero bytes after it (numerically, 0x01 == 0x0001 == 0x000001)
18232 //if (opcode == OP_NOTEQUAL)
18233 // fEqual = !fEqual;
18234 popstack(stack);
18235 popstack(stack);
18236 stack.push_back(fEqual ? vchTrue : vchFalse);
18237 if (opcode == OP_EQUALVERIFY)
18238 {
18239 if (fEqual)
18240 popstack(stack);
18241 else
18242 return false;
18243 }
18244 }
18245 break;
18246
18247
18248 //
18249 // Numeric
18250 //
18251 case OP_1ADD:
18252 case OP_1SUB:
18253 case OP_2MUL:
18254 case OP_2DIV:
18255 case OP_NEGATE:
18256 case OP_ABS:
18257 case OP_NOT:
18258 case OP_0NOTEQUAL:
18259 {
18260 // (in -- out)
18261 if (stack.size() < 1)
18262 return false;
18263 CBigNum bn = CastToBigNum(stacktop(-1));
18264 switch (opcode)
18265 {
18266 case OP_1ADD: bn += bnOne; break;
18267 case OP_1SUB: bn -= bnOne; break;
18268 case OP_2MUL: bn <<= 1; break;
18269 case OP_2DIV: bn >>= 1; break;
18270 case OP_NEGATE: bn = -bn; break;
18271 case OP_ABS: if (bn < bnZero) bn = -bn; break;
18272 case OP_NOT: bn = (bn == bnZero); break;
18273 case OP_0NOTEQUAL: bn = (bn != bnZero); break;
18274 default: assert(!"invalid opcode"); break;
18275 }
18276 popstack(stack);
18277 stack.push_back(bn.getvch());
18278 }
18279 break;
18280
18281 case OP_ADD:
18282 case OP_SUB:
18283 case OP_MUL:
18284 case OP_DIV:
18285 case OP_MOD:
18286 case OP_LSHIFT:
18287 case OP_RSHIFT:
18288 case OP_BOOLAND:
18289 case OP_BOOLOR:
18290 case OP_NUMEQUAL:
18291 case OP_NUMEQUALVERIFY:
18292 case OP_NUMNOTEQUAL:
18293 case OP_LESSTHAN:
18294 case OP_GREATERTHAN:
18295 case OP_LESSTHANOREQUAL:
18296 case OP_GREATERTHANOREQUAL:
18297 case OP_MIN:
18298 case OP_MAX:
18299 {
18300 // (x1 x2 -- out)
18301 if (stack.size() < 2)
18302 return false;
18303 CBigNum bn1 = CastToBigNum(stacktop(-2));
18304 CBigNum bn2 = CastToBigNum(stacktop(-1));
18305 CBigNum bn;
18306 switch (opcode)
18307 {
18308 case OP_ADD:
18309 bn = bn1 + bn2;
18310 break;
18311
18312 case OP_SUB:
18313 bn = bn1 - bn2;
18314 break;
18315
18316 case OP_MUL:
18317 if (!BN_mul(&bn, &bn1, &bn2, pctx))
18318 return false;
18319 break;
18320
18321 case OP_DIV:
18322 if (!BN_div(&bn, NULL, &bn1, &bn2, pctx))
18323 return false;
18324 break;
18325
18326 case OP_MOD:
18327 if (!BN_mod(&bn, &bn1, &bn2, pctx))
18328 return false;
18329 break;
18330
18331 case OP_LSHIFT:
18332 if (bn2 < bnZero || bn2 > CBigNum(2048))
18333 return false;
18334 bn = bn1 << bn2.getulong();
18335 break;
18336
18337 case OP_RSHIFT:
18338 if (bn2 < bnZero || bn2 > CBigNum(2048))
18339 return false;
18340 bn = bn1 >> bn2.getulong();
18341 break;
18342
18343 case OP_BOOLAND: bn = (bn1 != bnZero && bn2 != bnZero); break;
18344 case OP_BOOLOR: bn = (bn1 != bnZero || bn2 != bnZero); break;
18345 case OP_NUMEQUAL: bn = (bn1 == bn2); break;
18346 case OP_NUMEQUALVERIFY: bn = (bn1 == bn2); break;
18347 case OP_NUMNOTEQUAL: bn = (bn1 != bn2); break;
18348 case OP_LESSTHAN: bn = (bn1 < bn2); break;
18349 case OP_GREATERTHAN: bn = (bn1 > bn2); break;
18350 case OP_LESSTHANOREQUAL: bn = (bn1 <= bn2); break;
18351 case OP_GREATERTHANOREQUAL: bn = (bn1 >= bn2); break;
18352 case OP_MIN: bn = (bn1 < bn2 ? bn1 : bn2); break;
18353 case OP_MAX: bn = (bn1 > bn2 ? bn1 : bn2); break;
18354 default: assert(!"invalid opcode"); break;
18355 }
18356 popstack(stack);
18357 popstack(stack);
18358 stack.push_back(bn.getvch());
18359
18360 if (opcode == OP_NUMEQUALVERIFY)
18361 {
18362 if (CastToBool(stacktop(-1)))
18363 popstack(stack);
18364 else
18365 return false;
18366 }
18367 }
18368 break;
18369
18370 case OP_WITHIN:
18371 {
18372 // (x min max -- out)
18373 if (stack.size() < 3)
18374 return false;
18375 CBigNum bn1 = CastToBigNum(stacktop(-3));
18376 CBigNum bn2 = CastToBigNum(stacktop(-2));
18377 CBigNum bn3 = CastToBigNum(stacktop(-1));
18378 bool fValue = (bn2 <= bn1 && bn1 < bn3);
18379 popstack(stack);
18380 popstack(stack);
18381 popstack(stack);
18382 stack.push_back(fValue ? vchTrue : vchFalse);
18383 }
18384 break;
18385
18386
18387 //
18388 // Crypto
18389 //
18390 case OP_RIPEMD160:
18391 case OP_SHA1:
18392 case OP_SHA256:
18393 case OP_HASH160:
18394 case OP_HASH256:
18395 {
18396 // (in -- hash)
18397 if (stack.size() < 1)
18398 return false;
18399 valtype& vch = stacktop(-1);
18400 valtype vchHash((opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160) ? 20 : 32);
18401 if (opcode == OP_RIPEMD160)
18402 RIPEMD160(&vch[0], vch.size(), &vchHash[0]);
18403 else if (opcode == OP_SHA1)
18404 SHA1(&vch[0], vch.size(), &vchHash[0]);
18405 else if (opcode == OP_SHA256)
18406 SHA256(&vch[0], vch.size(), &vchHash[0]);
18407 else if (opcode == OP_HASH160)
18408 {
18409 uint160 hash160 = Hash160(vch);
18410 memcpy(&vchHash[0], &hash160, sizeof(hash160));
18411 }
18412 else if (opcode == OP_HASH256)
18413 {
18414 uint256 hash = Hash(vch.begin(), vch.end());
18415 memcpy(&vchHash[0], &hash, sizeof(hash));
18416 }
18417 popstack(stack);
18418 stack.push_back(vchHash);
18419 }
18420 break;
18421
18422 case OP_CODESEPARATOR:
18423 {
18424 // Hash starts after the code separator
18425 pbegincodehash = pc;
18426 }
18427 break;
18428
18429 case OP_CHECKSIG:
18430 case OP_CHECKSIGVERIFY:
18431 {
18432 // (sig pubkey -- bool)
18433 if (stack.size() < 2)
18434 return false;
18435
18436 valtype& vchSig = stacktop(-2);
18437 valtype& vchPubKey = stacktop(-1);
18438
18439 ////// debug print
18440 //PrintHex(vchSig.begin(), vchSig.end(), "sig: %s\n");
18441 //PrintHex(vchPubKey.begin(), vchPubKey.end(), "pubkey: %s\n");
18442
18443 // Subset of script starting at the most recent codeseparator
18444 CScript scriptCode(pbegincodehash, pend);
18445
18446 // Drop the signature, since there's no way for a signature to sign itself
18447 scriptCode.FindAndDelete(CScript(vchSig));
18448
18449 bool fSuccess = CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType);
18450
18451 popstack(stack);
18452 popstack(stack);
18453 stack.push_back(fSuccess ? vchTrue : vchFalse);
18454 if (opcode == OP_CHECKSIGVERIFY)
18455 {
18456 if (fSuccess)
18457 popstack(stack);
18458 else
18459 return false;
18460 }
18461 }
18462 break;
18463
18464 case OP_CHECKMULTISIG:
18465 case OP_CHECKMULTISIGVERIFY:
18466 {
18467 // ([sig ...] num_of_signatures [pubkey ...] num_of_pubkeys -- bool)
18468
18469 int i = 1;
18470 if (stack.size() < i)
18471 return false;
18472
18473 int nKeysCount = CastToBigNum(stacktop(-i)).getint();
18474 if (nKeysCount < 0 || nKeysCount > 20)
18475 return false;
18476 nOpCount += nKeysCount;
18477 if (nOpCount > 201)
18478 return false;
18479 int ikey = ++i;
18480 i += nKeysCount;
18481 if (stack.size() < i)
18482 return false;
18483
18484 int nSigsCount = CastToBigNum(stacktop(-i)).getint();
18485 if (nSigsCount < 0 || nSigsCount > nKeysCount)
18486 return false;
18487 int isig = ++i;
18488 i += nSigsCount;
18489 if (stack.size() < i)
18490 return false;
18491
18492 // Subset of script starting at the most recent codeseparator
18493 CScript scriptCode(pbegincodehash, pend);
18494
18495 // Drop the signatures, since there's no way for a signature to sign itself
18496 for (int k = 0; k < nSigsCount; k++)
18497 {
18498 valtype& vchSig = stacktop(-isig-k);
18499 scriptCode.FindAndDelete(CScript(vchSig));
18500 }
18501
18502 bool fSuccess = true;
18503 while (fSuccess && nSigsCount > 0)
18504 {
18505 valtype& vchSig = stacktop(-isig);
18506 valtype& vchPubKey = stacktop(-ikey);
18507
18508 // Check signature
18509 if (CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType))
18510 {
18511 isig++;
18512 nSigsCount--;
18513 }
18514 ikey++;
18515 nKeysCount--;
18516
18517 // If there are more signatures left than keys left,
18518 // then too many signatures have failed
18519 if (nSigsCount > nKeysCount)
18520 fSuccess = false;
18521 }
18522
18523 while (i-- > 0)
18524 popstack(stack);
18525 stack.push_back(fSuccess ? vchTrue : vchFalse);
18526
18527 if (opcode == OP_CHECKMULTISIGVERIFY)
18528 {
18529 if (fSuccess)
18530 popstack(stack);
18531 else
18532 return false;
18533 }
18534 }
18535 break;
18536
18537 default:
18538 return false;
18539 }
18540
18541 // Size limits
18542 if (stack.size() + altstack.size() > 1000)
18543 return false;
18544 }
18545 }
18546 catch (...)
18547 {
18548 return false;
18549 }
18550
18551
18552 if (!vfExec.empty())
18553 return false;
18554
18555 return true;
18556 }
18557
18558
18559
18560
18561
18562
18563
18564
18565
18566 uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType)
18567 {
18568 if (nIn >= txTo.vin.size())
18569 {
18570 printf("ERROR: SignatureHash() : nIn=%d out of range\n", nIn);
18571 return 1;
18572 }
18573 CTransaction txTmp(txTo);
18574
18575 // In case concatenating two scripts ends up with two codeseparators,
18576 // or an extra one at the end, this prevents all those possible incompatibilities.
18577 scriptCode.FindAndDelete(CScript(OP_CODESEPARATOR));
18578
18579 // Blank out other inputs' signatures
18580 for (int i = 0; i < txTmp.vin.size(); i++)
18581 txTmp.vin[i].scriptSig = CScript();
18582 txTmp.vin[nIn].scriptSig = scriptCode;
18583
18584 // Blank out some of the outputs
18585 if ((nHashType & 0x1f) == SIGHASH_NONE)
18586 {
18587 // Wildcard payee
18588 txTmp.vout.clear();
18589
18590 // Let the others update at will
18591 for (int i = 0; i < txTmp.vin.size(); i++)
18592 if (i != nIn)
18593 txTmp.vin[i].nSequence = 0;
18594 }
18595 else if ((nHashType & 0x1f) == SIGHASH_SINGLE)
18596 {
18597 // Only lockin the txout payee at same index as txin
18598 unsigned int nOut = nIn;
18599 if (nOut >= txTmp.vout.size())
18600 {
18601 printf("ERROR: SignatureHash() : nOut=%d out of range\n", nOut);
18602 return 1;
18603 }
18604 txTmp.vout.resize(nOut+1);
18605 for (int i = 0; i < nOut; i++)
18606 txTmp.vout[i].SetNull();
18607
18608 // Let the others update at will
18609 for (int i = 0; i < txTmp.vin.size(); i++)
18610 if (i != nIn)
18611 txTmp.vin[i].nSequence = 0;
18612 }
18613
18614 // Blank out other inputs completely, not recommended for open transactions
18615 if (nHashType & SIGHASH_ANYONECANPAY)
18616 {
18617 txTmp.vin[0] = txTmp.vin[nIn];
18618 txTmp.vin.resize(1);
18619 }
18620
18621 // Serialize and hash
18622 CDataStream ss(SER_GETHASH);
18623 ss.reserve(10000);
18624 ss << txTmp << nHashType;
18625 return Hash(ss.begin(), ss.end());
18626 }
18627
18628
18629 bool CheckSig(vector<unsigned char> vchSig, vector<unsigned char> vchPubKey, CScript scriptCode,
18630 const CTransaction& txTo, unsigned int nIn, int nHashType)
18631 {
18632 CKey key;
18633 if (!key.SetPubKey(vchPubKey))
18634 return false;
18635
18636 // Hash type is one byte tacked on to the end of the signature
18637 if (vchSig.empty())
18638 return false;
18639 if (nHashType == 0)
18640 nHashType = vchSig.back();
18641 else if (nHashType != vchSig.back())
18642 return false;
18643 vchSig.pop_back();
18644
18645 return key.Verify(SignatureHash(scriptCode, txTo, nIn, nHashType), vchSig);
18646 }
18647
18648
18649
18650
18651
18652
18653
18654
18655
18656
18657 bool Solver(const CScript& scriptPubKey, vector<pair<opcodetype, valtype> >& vSolutionRet)
18658 {
18659 // Templates
18660 static vector<CScript> vTemplates;
18661 if (vTemplates.empty())
18662 {
18663 // Standard tx, sender provides pubkey, receiver adds signature
18664 vTemplates.push_back(CScript() << OP_PUBKEY << OP_CHECKSIG);
18665
18666 // Bitcoin address tx, sender provides hash of pubkey, receiver provides signature and pubkey
18667 vTemplates.push_back(CScript() << OP_DUP << OP_HASH160 << OP_PUBKEYHASH << OP_EQUALVERIFY << OP_CHECKSIG);
18668 }
18669
18670 // Scan templates
18671 const CScript& script1 = scriptPubKey;
18672 BOOST_FOREACH(const CScript& script2, vTemplates)
18673 {
18674 vSolutionRet.clear();
18675 opcodetype opcode1, opcode2;
18676 vector<unsigned char> vch1, vch2;
18677
18678 // Compare
18679 CScript::const_iterator pc1 = script1.begin();
18680 CScript::const_iterator pc2 = script2.begin();
18681 loop
18682 {
18683 if (pc1 == script1.end() && pc2 == script2.end())
18684 {
18685 // Found a match
18686 reverse(vSolutionRet.begin(), vSolutionRet.end());
18687 return true;
18688 }
18689 if (!script1.GetOp(pc1, opcode1, vch1))
18690 break;
18691 if (!script2.GetOp(pc2, opcode2, vch2))
18692 break;
18693 if (opcode2 == OP_PUBKEY)
18694 {
18695 if (vch1.size() < 33 || vch1.size() > 120)
18696 break;
18697 vSolutionRet.push_back(make_pair(opcode2, vch1));
18698 }
18699 else if (opcode2 == OP_PUBKEYHASH)
18700 {
18701 if (vch1.size() != sizeof(uint160))
18702 break;
18703 vSolutionRet.push_back(make_pair(opcode2, vch1));
18704 }
18705 else if (opcode1 != opcode2 || vch1 != vch2)
18706 {
18707 break;
18708 }
18709 }
18710 }
18711
18712 vSolutionRet.clear();
18713 return false;
18714 }
18715
18716
18717 bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, uint256 hash, int nHashType, CScript& scriptSigRet)
18718 {
18719 scriptSigRet.clear();
18720
18721 vector<pair<opcodetype, valtype> > vSolution;
18722 if (!Solver(scriptPubKey, vSolution))
18723 return false;
18724
18725 // Compile solution
18726 BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution)
18727 {
18728 if (item.first == OP_PUBKEY)
18729 {
18730 // Sign
18731 const valtype& vchPubKey = item.second;
18732 CKey key;
18733 if (!keystore.GetKey(Hash160(vchPubKey), key))
18734 return false;
18735 if (key.GetPubKey() != vchPubKey)
18736 return false;
18737 if (hash != 0)
18738 {
18739 vector<unsigned char> vchSig;
18740 if (!key.Sign(hash, vchSig))
18741 return false;
18742 vchSig.push_back((unsigned char)nHashType);
18743 scriptSigRet << vchSig;
18744 }
18745 }
18746 else if (item.first == OP_PUBKEYHASH)
18747 {
18748 // Sign and give pubkey
18749 CKey key;
18750 if (!keystore.GetKey(uint160(item.second), key))
18751 return false;
18752 if (hash != 0)
18753 {
18754 vector<unsigned char> vchSig;
18755 if (!key.Sign(hash, vchSig))
18756 return false;
18757 vchSig.push_back((unsigned char)nHashType);
18758 scriptSigRet << vchSig << key.GetPubKey();
18759 }
18760 }
18761 else
18762 {
18763 return false;
18764 }
18765 }
18766
18767 return true;
18768 }
18769
18770
18771 bool IsStandard(const CScript& scriptPubKey)
18772 {
18773 vector<pair<opcodetype, valtype> > vSolution;
18774 return Solver(scriptPubKey, vSolution);
18775 }
18776
18777
18778 bool IsMine(const CKeyStore &keystore, const CScript& scriptPubKey)
18779 {
18780 vector<pair<opcodetype, valtype> > vSolution;
18781 if (!Solver(scriptPubKey, vSolution))
18782 return false;
18783
18784 // Compile solution
18785 BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution)
18786 {
18787 if (item.first == OP_PUBKEY)
18788 {
18789 const valtype& vchPubKey = item.second;
18790 vector<unsigned char> vchPubKeyFound;
18791 if (!keystore.GetPubKey(Hash160(vchPubKey), vchPubKeyFound))
18792 return false;
18793 if (vchPubKeyFound != vchPubKey)
18794 return false;
18795 }
18796 else if (item.first == OP_PUBKEYHASH)
18797 {
18798 if (!keystore.HaveKey(uint160(item.second)))
18799 return false;
18800 }
18801 else
18802 {
18803 return false;
18804 }
18805 }
18806
18807 return true;
18808 }
18809
18810 bool static ExtractAddressInner(const CScript& scriptPubKey, const CKeyStore* keystore, CBitcoinAddress& addressRet)
18811 {
18812 vector<pair<opcodetype, valtype> > vSolution;
18813 if (!Solver(scriptPubKey, vSolution))
18814 return false;
18815
18816 BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution)
18817 {
18818 if (item.first == OP_PUBKEY)
18819 addressRet.SetPubKey(item.second);
18820 else if (item.first == OP_PUBKEYHASH)
18821 addressRet.SetHash160((uint160)item.second);
18822 if (keystore == NULL || keystore->HaveKey(addressRet))
18823 return true;
18824 }
18825
18826 return false;
18827 }
18828
18829
18830 bool ExtractAddress(const CScript& scriptPubKey, const CKeyStore* keystore, CBitcoinAddress& addressRet)
18831 {
18832 if (keystore)
18833 return ExtractAddressInner(scriptPubKey, keystore, addressRet);
18834 else
18835 return ExtractAddressInner(scriptPubKey, NULL, addressRet);
18836 return false;
18837 }
18838
18839
18840 bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, int nHashType)
18841 {
18842 vector<vector<unsigned char> > stack;
18843 if (!EvalScript(stack, scriptSig, txTo, nIn, nHashType))
18844 return false;
18845 if (!EvalScript(stack, scriptPubKey, txTo, nIn, nHashType))
18846 return false;
18847 if (stack.empty())
18848 return false;
18849 return CastToBool(stack.back());
18850 }
18851
18852
18853 bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType, CScript scriptPrereq)
18854 {
18855 assert(nIn < txTo.vin.size());
18856 CTxIn& txin = txTo.vin[nIn];
18857 assert(txin.prevout.n < txFrom.vout.size());
18858 const CTxOut& txout = txFrom.vout[txin.prevout.n];
18859
18860 // Leave out the signature from the hash, since a signature can't sign itself.
18861 // The checksig op will also drop the signatures from its hash.
18862 uint256 hash = SignatureHash(scriptPrereq + txout.scriptPubKey, txTo, nIn, nHashType);
18863
18864 if (!Solver(keystore, txout.scriptPubKey, hash, nHashType, txin.scriptSig))
18865 return false;
18866
18867 txin.scriptSig = scriptPrereq + txin.scriptSig;
18868
18869 // Test solution
18870 if (scriptPrereq.empty())
18871 if (!VerifyScript(txin.scriptSig, txout.scriptPubKey, txTo, nIn, 0))
18872 return false;
18873
18874 return true;
18875 }
18876
18877
18878 bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, int nHashType)
18879 {
18880 assert(nIn < txTo.vin.size());
18881 const CTxIn& txin = txTo.vin[nIn];
18882 if (txin.prevout.n >= txFrom.vout.size())
18883 return false;
18884 const CTxOut& txout = txFrom.vout[txin.prevout.n];
18885
18886 if (txin.prevout.hash != txFrom.GetHash())
18887 return false;
18888
18889 if (!VerifyScript(txin.scriptSig, txout.scriptPubKey, txTo, nIn, nHashType))
18890 return false;
18891
18892 return true;
18893 }
-
+ 6D3CD409EEE6A9F7689A3CBBC8AF5207E314B39F4B16F8C82F350FFB1AFD42B8025EFFA2C1D2E6F5F511B2C0FDD87BF008206AE6809490E0DD8D06E9B3430EA4
bitcoin/src/script.h
(0 . 0)(1 . 703)
18898 // Copyright (c) 2009-2010 Satoshi Nakamoto
18899 // Copyright (c) 2011 The Bitcoin developers
18900 // Distributed under the MIT/X11 software license, see the accompanying
18901 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
18902 #ifndef H_BITCOIN_SCRIPT
18903 #define H_BITCOIN_SCRIPT
18904
18905 #include "base58.h"
18906 #include "keystore.h"
18907
18908 #include <string>
18909 #include <vector>
18910
18911 #include <boost/foreach.hpp>
18912
18913 class CTransaction;
18914
18915 enum
18916 {
18917 SIGHASH_ALL = 1,
18918 SIGHASH_NONE = 2,
18919 SIGHASH_SINGLE = 3,
18920 SIGHASH_ANYONECANPAY = 0x80,
18921 };
18922
18923
18924
18925 enum opcodetype
18926 {
18927 // push value
18928 OP_0=0,
18929 OP_FALSE=OP_0,
18930 OP_PUSHDATA1=76,
18931 OP_PUSHDATA2,
18932 OP_PUSHDATA4,
18933 OP_1NEGATE,
18934 OP_RESERVED,
18935 OP_1,
18936 OP_TRUE=OP_1,
18937 OP_2,
18938 OP_3,
18939 OP_4,
18940 OP_5,
18941 OP_6,
18942 OP_7,
18943 OP_8,
18944 OP_9,
18945 OP_10,
18946 OP_11,
18947 OP_12,
18948 OP_13,
18949 OP_14,
18950 OP_15,
18951 OP_16,
18952
18953 // control
18954 OP_NOP,
18955 OP_VER,
18956 OP_IF,
18957 OP_NOTIF,
18958 OP_VERIF,
18959 OP_VERNOTIF,
18960 OP_ELSE,
18961 OP_ENDIF,
18962 OP_VERIFY,
18963 OP_RETURN,
18964
18965 // stack ops
18966 OP_TOALTSTACK,
18967 OP_FROMALTSTACK,
18968 OP_2DROP,
18969 OP_2DUP,
18970 OP_3DUP,
18971 OP_2OVER,
18972 OP_2ROT,
18973 OP_2SWAP,
18974 OP_IFDUP,
18975 OP_DEPTH,
18976 OP_DROP,
18977 OP_DUP,
18978 OP_NIP,
18979 OP_OVER,
18980 OP_PICK,
18981 OP_ROLL,
18982 OP_ROT,
18983 OP_SWAP,
18984 OP_TUCK,
18985
18986 // splice ops
18987 OP_CAT,
18988 OP_SUBSTR,
18989 OP_LEFT,
18990 OP_RIGHT,
18991 OP_SIZE,
18992
18993 // bit logic
18994 OP_INVERT,
18995 OP_AND,
18996 OP_OR,
18997 OP_XOR,
18998 OP_EQUAL,
18999 OP_EQUALVERIFY,
19000 OP_RESERVED1,
19001 OP_RESERVED2,
19002
19003 // numeric
19004 OP_1ADD,
19005 OP_1SUB,
19006 OP_2MUL,
19007 OP_2DIV,
19008 OP_NEGATE,
19009 OP_ABS,
19010 OP_NOT,
19011 OP_0NOTEQUAL,
19012
19013 OP_ADD,
19014 OP_SUB,
19015 OP_MUL,
19016 OP_DIV,
19017 OP_MOD,
19018 OP_LSHIFT,
19019 OP_RSHIFT,
19020
19021 OP_BOOLAND,
19022 OP_BOOLOR,
19023 OP_NUMEQUAL,
19024 OP_NUMEQUALVERIFY,
19025 OP_NUMNOTEQUAL,
19026 OP_LESSTHAN,
19027 OP_GREATERTHAN,
19028 OP_LESSTHANOREQUAL,
19029 OP_GREATERTHANOREQUAL,
19030 OP_MIN,
19031 OP_MAX,
19032
19033 OP_WITHIN,
19034
19035 // crypto
19036 OP_RIPEMD160,
19037 OP_SHA1,
19038 OP_SHA256,
19039 OP_HASH160,
19040 OP_HASH256,
19041 OP_CODESEPARATOR,
19042 OP_CHECKSIG,
19043 OP_CHECKSIGVERIFY,
19044 OP_CHECKMULTISIG,
19045 OP_CHECKMULTISIGVERIFY,
19046
19047 // expansion
19048 OP_NOP1,
19049 OP_NOP2,
19050 OP_NOP3,
19051 OP_NOP4,
19052 OP_NOP5,
19053 OP_NOP6,
19054 OP_NOP7,
19055 OP_NOP8,
19056 OP_NOP9,
19057 OP_NOP10,
19058
19059
19060
19061 // template matching params
19062 OP_PUBKEYHASH = 0xfd,
19063 OP_PUBKEY = 0xfe,
19064
19065 OP_INVALIDOPCODE = 0xff,
19066 };
19067
19068
19069
19070
19071
19072
19073
19074
19075 inline const char* GetOpName(opcodetype opcode)
19076 {
19077 switch (opcode)
19078 {
19079 // push value
19080 case OP_0 : return "0";
19081 case OP_PUSHDATA1 : return "OP_PUSHDATA1";
19082 case OP_PUSHDATA2 : return "OP_PUSHDATA2";
19083 case OP_PUSHDATA4 : return "OP_PUSHDATA4";
19084 case OP_1NEGATE : return "-1";
19085 case OP_RESERVED : return "OP_RESERVED";
19086 case OP_1 : return "1";
19087 case OP_2 : return "2";
19088 case OP_3 : return "3";
19089 case OP_4 : return "4";
19090 case OP_5 : return "5";
19091 case OP_6 : return "6";
19092 case OP_7 : return "7";
19093 case OP_8 : return "8";
19094 case OP_9 : return "9";
19095 case OP_10 : return "10";
19096 case OP_11 : return "11";
19097 case OP_12 : return "12";
19098 case OP_13 : return "13";
19099 case OP_14 : return "14";
19100 case OP_15 : return "15";
19101 case OP_16 : return "16";
19102
19103 // control
19104 case OP_NOP : return "OP_NOP";
19105 case OP_VER : return "OP_VER";
19106 case OP_IF : return "OP_IF";
19107 case OP_NOTIF : return "OP_NOTIF";
19108 case OP_VERIF : return "OP_VERIF";
19109 case OP_VERNOTIF : return "OP_VERNOTIF";
19110 case OP_ELSE : return "OP_ELSE";
19111 case OP_ENDIF : return "OP_ENDIF";
19112 case OP_VERIFY : return "OP_VERIFY";
19113 case OP_RETURN : return "OP_RETURN";
19114
19115 // stack ops
19116 case OP_TOALTSTACK : return "OP_TOALTSTACK";
19117 case OP_FROMALTSTACK : return "OP_FROMALTSTACK";
19118 case OP_2DROP : return "OP_2DROP";
19119 case OP_2DUP : return "OP_2DUP";
19120 case OP_3DUP : return "OP_3DUP";
19121 case OP_2OVER : return "OP_2OVER";
19122 case OP_2ROT : return "OP_2ROT";
19123 case OP_2SWAP : return "OP_2SWAP";
19124 case OP_IFDUP : return "OP_IFDUP";
19125 case OP_DEPTH : return "OP_DEPTH";
19126 case OP_DROP : return "OP_DROP";
19127 case OP_DUP : return "OP_DUP";
19128 case OP_NIP : return "OP_NIP";
19129 case OP_OVER : return "OP_OVER";
19130 case OP_PICK : return "OP_PICK";
19131 case OP_ROLL : return "OP_ROLL";
19132 case OP_ROT : return "OP_ROT";
19133 case OP_SWAP : return "OP_SWAP";
19134 case OP_TUCK : return "OP_TUCK";
19135
19136 // splice ops
19137 case OP_CAT : return "OP_CAT";
19138 case OP_SUBSTR : return "OP_SUBSTR";
19139 case OP_LEFT : return "OP_LEFT";
19140 case OP_RIGHT : return "OP_RIGHT";
19141 case OP_SIZE : return "OP_SIZE";
19142
19143 // bit logic
19144 case OP_INVERT : return "OP_INVERT";
19145 case OP_AND : return "OP_AND";
19146 case OP_OR : return "OP_OR";
19147 case OP_XOR : return "OP_XOR";
19148 case OP_EQUAL : return "OP_EQUAL";
19149 case OP_EQUALVERIFY : return "OP_EQUALVERIFY";
19150 case OP_RESERVED1 : return "OP_RESERVED1";
19151 case OP_RESERVED2 : return "OP_RESERVED2";
19152
19153 // numeric
19154 case OP_1ADD : return "OP_1ADD";
19155 case OP_1SUB : return "OP_1SUB";
19156 case OP_2MUL : return "OP_2MUL";
19157 case OP_2DIV : return "OP_2DIV";
19158 case OP_NEGATE : return "OP_NEGATE";
19159 case OP_ABS : return "OP_ABS";
19160 case OP_NOT : return "OP_NOT";
19161 case OP_0NOTEQUAL : return "OP_0NOTEQUAL";
19162 case OP_ADD : return "OP_ADD";
19163 case OP_SUB : return "OP_SUB";
19164 case OP_MUL : return "OP_MUL";
19165 case OP_DIV : return "OP_DIV";
19166 case OP_MOD : return "OP_MOD";
19167 case OP_LSHIFT : return "OP_LSHIFT";
19168 case OP_RSHIFT : return "OP_RSHIFT";
19169 case OP_BOOLAND : return "OP_BOOLAND";
19170 case OP_BOOLOR : return "OP_BOOLOR";
19171 case OP_NUMEQUAL : return "OP_NUMEQUAL";
19172 case OP_NUMEQUALVERIFY : return "OP_NUMEQUALVERIFY";
19173 case OP_NUMNOTEQUAL : return "OP_NUMNOTEQUAL";
19174 case OP_LESSTHAN : return "OP_LESSTHAN";
19175 case OP_GREATERTHAN : return "OP_GREATERTHAN";
19176 case OP_LESSTHANOREQUAL : return "OP_LESSTHANOREQUAL";
19177 case OP_GREATERTHANOREQUAL : return "OP_GREATERTHANOREQUAL";
19178 case OP_MIN : return "OP_MIN";
19179 case OP_MAX : return "OP_MAX";
19180 case OP_WITHIN : return "OP_WITHIN";
19181
19182 // crypto
19183 case OP_RIPEMD160 : return "OP_RIPEMD160";
19184 case OP_SHA1 : return "OP_SHA1";
19185 case OP_SHA256 : return "OP_SHA256";
19186 case OP_HASH160 : return "OP_HASH160";
19187 case OP_HASH256 : return "OP_HASH256";
19188 case OP_CODESEPARATOR : return "OP_CODESEPARATOR";
19189 case OP_CHECKSIG : return "OP_CHECKSIG";
19190 case OP_CHECKSIGVERIFY : return "OP_CHECKSIGVERIFY";
19191 case OP_CHECKMULTISIG : return "OP_CHECKMULTISIG";
19192 case OP_CHECKMULTISIGVERIFY : return "OP_CHECKMULTISIGVERIFY";
19193
19194 // expanson
19195 case OP_NOP1 : return "OP_NOP1";
19196 case OP_NOP2 : return "OP_NOP2";
19197 case OP_NOP3 : return "OP_NOP3";
19198 case OP_NOP4 : return "OP_NOP4";
19199 case OP_NOP5 : return "OP_NOP5";
19200 case OP_NOP6 : return "OP_NOP6";
19201 case OP_NOP7 : return "OP_NOP7";
19202 case OP_NOP8 : return "OP_NOP8";
19203 case OP_NOP9 : return "OP_NOP9";
19204 case OP_NOP10 : return "OP_NOP10";
19205
19206
19207
19208 // template matching params
19209 case OP_PUBKEYHASH : return "OP_PUBKEYHASH";
19210 case OP_PUBKEY : return "OP_PUBKEY";
19211
19212 case OP_INVALIDOPCODE : return "OP_INVALIDOPCODE";
19213 default:
19214 return "OP_UNKNOWN";
19215 }
19216 };
19217
19218
19219
19220
19221 inline std::string ValueString(const std::vector<unsigned char>& vch)
19222 {
19223 if (vch.size() <= 4)
19224 return strprintf("%d", CBigNum(vch).getint());
19225 else
19226 return HexStr(vch);
19227 }
19228
19229 inline std::string StackString(const std::vector<std::vector<unsigned char> >& vStack)
19230 {
19231 std::string str;
19232 BOOST_FOREACH(const std::vector<unsigned char>& vch, vStack)
19233 {
19234 if (!str.empty())
19235 str += " ";
19236 str += ValueString(vch);
19237 }
19238 return str;
19239 }
19240
19241
19242
19243
19244
19245
19246
19247
19248
19249 class CScript : public std::vector<unsigned char>
19250 {
19251 protected:
19252 CScript& push_int64(int64 n)
19253 {
19254 if (n == -1 || (n >= 1 && n <= 16))
19255 {
19256 push_back(n + (OP_1 - 1));
19257 }
19258 else
19259 {
19260 CBigNum bn(n);
19261 *this << bn.getvch();
19262 }
19263 return *this;
19264 }
19265
19266 CScript& push_uint64(uint64 n)
19267 {
19268 if (n >= 1 && n <= 16)
19269 {
19270 push_back(n + (OP_1 - 1));
19271 }
19272 else
19273 {
19274 CBigNum bn(n);
19275 *this << bn.getvch();
19276 }
19277 return *this;
19278 }
19279
19280 public:
19281 CScript() { }
19282 CScript(const CScript& b) : std::vector<unsigned char>(b.begin(), b.end()) { }
19283 CScript(const_iterator pbegin, const_iterator pend) : std::vector<unsigned char>(pbegin, pend) { }
19284 #ifndef _MSC_VER
19285 CScript(const unsigned char* pbegin, const unsigned char* pend) : std::vector<unsigned char>(pbegin, pend) { }
19286 #endif
19287
19288 CScript& operator+=(const CScript& b)
19289 {
19290 insert(end(), b.begin(), b.end());
19291 return *this;
19292 }
19293
19294 friend CScript operator+(const CScript& a, const CScript& b)
19295 {
19296 CScript ret = a;
19297 ret += b;
19298 return ret;
19299 }
19300
19301
19302 explicit CScript(char b) { operator<<(b); }
19303 explicit CScript(short b) { operator<<(b); }
19304 explicit CScript(int b) { operator<<(b); }
19305 explicit CScript(long b) { operator<<(b); }
19306 explicit CScript(int64 b) { operator<<(b); }
19307 explicit CScript(unsigned char b) { operator<<(b); }
19308 explicit CScript(unsigned int b) { operator<<(b); }
19309 explicit CScript(unsigned short b) { operator<<(b); }
19310 explicit CScript(unsigned long b) { operator<<(b); }
19311 explicit CScript(uint64 b) { operator<<(b); }
19312
19313 explicit CScript(opcodetype b) { operator<<(b); }
19314 explicit CScript(const uint256& b) { operator<<(b); }
19315 explicit CScript(const CBigNum& b) { operator<<(b); }
19316 explicit CScript(const std::vector<unsigned char>& b) { operator<<(b); }
19317
19318
19319 CScript& operator<<(char b) { return push_int64(b); }
19320 CScript& operator<<(short b) { return push_int64(b); }
19321 CScript& operator<<(int b) { return push_int64(b); }
19322 CScript& operator<<(long b) { return push_int64(b); }
19323 CScript& operator<<(int64 b) { return push_int64(b); }
19324 CScript& operator<<(unsigned char b) { return push_uint64(b); }
19325 CScript& operator<<(unsigned int b) { return push_uint64(b); }
19326 CScript& operator<<(unsigned short b) { return push_uint64(b); }
19327 CScript& operator<<(unsigned long b) { return push_uint64(b); }
19328 CScript& operator<<(uint64 b) { return push_uint64(b); }
19329
19330 CScript& operator<<(opcodetype opcode)
19331 {
19332 if (opcode < 0 || opcode > 0xff)
19333 throw std::runtime_error("CScript::operator<<() : invalid opcode");
19334 insert(end(), (unsigned char)opcode);
19335 return *this;
19336 }
19337
19338 CScript& operator<<(const uint160& b)
19339 {
19340 insert(end(), sizeof(b));
19341 insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b));
19342 return *this;
19343 }
19344
19345 CScript& operator<<(const uint256& b)
19346 {
19347 insert(end(), sizeof(b));
19348 insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b));
19349 return *this;
19350 }
19351
19352 CScript& operator<<(const CBigNum& b)
19353 {
19354 *this << b.getvch();
19355 return *this;
19356 }
19357
19358 CScript& operator<<(const std::vector<unsigned char>& b)
19359 {
19360 if (b.size() < OP_PUSHDATA1)
19361 {
19362 insert(end(), (unsigned char)b.size());
19363 }
19364 else if (b.size() <= 0xff)
19365 {
19366 insert(end(), OP_PUSHDATA1);
19367 insert(end(), (unsigned char)b.size());
19368 }
19369 else if (b.size() <= 0xffff)
19370 {
19371 insert(end(), OP_PUSHDATA2);
19372 unsigned short nSize = b.size();
19373 insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize));
19374 }
19375 else
19376 {
19377 insert(end(), OP_PUSHDATA4);
19378 unsigned int nSize = b.size();
19379 insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize));
19380 }
19381 insert(end(), b.begin(), b.end());
19382 return *this;
19383 }
19384
19385 CScript& operator<<(const CScript& b)
19386 {
19387 // I'm not sure if this should push the script or concatenate scripts.
19388 // If there's ever a use for pushing a script onto a script, delete this member fn
19389 assert(!"warning: pushing a CScript onto a CScript with << is probably not intended, use + to concatenate");
19390 return *this;
19391 }
19392
19393
19394 bool GetOp(iterator& pc, opcodetype& opcodeRet, std::vector<unsigned char>& vchRet)
19395 {
19396 // Wrapper so it can be called with either iterator or const_iterator
19397 const_iterator pc2 = pc;
19398 bool fRet = GetOp2(pc2, opcodeRet, &vchRet);
19399 pc = begin() + (pc2 - begin());
19400 return fRet;
19401 }
19402
19403 bool GetOp(iterator& pc, opcodetype& opcodeRet)
19404 {
19405 const_iterator pc2 = pc;
19406 bool fRet = GetOp2(pc2, opcodeRet, NULL);
19407 pc = begin() + (pc2 - begin());
19408 return fRet;
19409 }
19410
19411 bool GetOp(const_iterator& pc, opcodetype& opcodeRet, std::vector<unsigned char>& vchRet) const
19412 {
19413 return GetOp2(pc, opcodeRet, &vchRet);
19414 }
19415
19416 bool GetOp(const_iterator& pc, opcodetype& opcodeRet) const
19417 {
19418 return GetOp2(pc, opcodeRet, NULL);
19419 }
19420
19421 bool GetOp2(const_iterator& pc, opcodetype& opcodeRet, std::vector<unsigned char>* pvchRet) const
19422 {
19423 opcodeRet = OP_INVALIDOPCODE;
19424 if (pvchRet)
19425 pvchRet->clear();
19426 if (pc >= end())
19427 return false;
19428
19429 // Read instruction
19430 if (end() - pc < 1)
19431 return false;
19432 unsigned int opcode = *pc++;
19433
19434 // Immediate operand
19435 if (opcode <= OP_PUSHDATA4)
19436 {
19437 unsigned int nSize;
19438 if (opcode < OP_PUSHDATA1)
19439 {
19440 nSize = opcode;
19441 }
19442 else if (opcode == OP_PUSHDATA1)
19443 {
19444 if (end() - pc < 1)
19445 return false;
19446 nSize = *pc++;
19447 }
19448 else if (opcode == OP_PUSHDATA2)
19449 {
19450 if (end() - pc < 2)
19451 return false;
19452 nSize = 0;
19453 memcpy(&nSize, &pc[0], 2);
19454 pc += 2;
19455 }
19456 else if (opcode == OP_PUSHDATA4)
19457 {
19458 if (end() - pc < 4)
19459 return false;
19460 memcpy(&nSize, &pc[0], 4);
19461 pc += 4;
19462 }
19463 if (end() - pc < nSize)
19464 return false;
19465 if (pvchRet)
19466 pvchRet->assign(pc, pc + nSize);
19467 pc += nSize;
19468 }
19469
19470 opcodeRet = (opcodetype)opcode;
19471 return true;
19472 }
19473
19474
19475 void FindAndDelete(const CScript& b)
19476 {
19477 if (b.empty())
19478 return;
19479 iterator pc = begin();
19480 opcodetype opcode;
19481 do
19482 {
19483 while (end() - pc >= b.size() && memcmp(&pc[0], &b[0], b.size()) == 0)
19484 erase(pc, pc + b.size());
19485 }
19486 while (GetOp(pc, opcode));
19487 }
19488
19489
19490 int GetSigOpCount() const
19491 {
19492 int n = 0;
19493 const_iterator pc = begin();
19494 while (pc < end())
19495 {
19496 opcodetype opcode;
19497 if (!GetOp(pc, opcode))
19498 break;
19499 if (opcode == OP_CHECKSIG || opcode == OP_CHECKSIGVERIFY)
19500 n++;
19501 else if (opcode == OP_CHECKMULTISIG || opcode == OP_CHECKMULTISIGVERIFY)
19502 n += 20;
19503 }
19504 return n;
19505 }
19506
19507
19508 bool IsPushOnly() const
19509 {
19510 if (size() > 200)
19511 return false;
19512 const_iterator pc = begin();
19513 while (pc < end())
19514 {
19515 opcodetype opcode;
19516 if (!GetOp(pc, opcode))
19517 return false;
19518 if (opcode > OP_16)
19519 return false;
19520 }
19521 return true;
19522 }
19523
19524
19525 CBitcoinAddress GetBitcoinAddress() const
19526 {
19527 opcodetype opcode;
19528 std::vector<unsigned char> vch;
19529 CScript::const_iterator pc = begin();
19530 if (!GetOp(pc, opcode, vch) || opcode != OP_DUP) return 0;
19531 if (!GetOp(pc, opcode, vch) || opcode != OP_HASH160) return 0;
19532 if (!GetOp(pc, opcode, vch) || vch.size() != sizeof(uint160)) return 0;
19533 uint160 hash160 = uint160(vch);
19534 if (!GetOp(pc, opcode, vch) || opcode != OP_EQUALVERIFY) return 0;
19535 if (!GetOp(pc, opcode, vch) || opcode != OP_CHECKSIG) return 0;
19536 if (pc != end()) return 0;
19537 return CBitcoinAddress(hash160);
19538 }
19539
19540 void SetBitcoinAddress(const CBitcoinAddress& address)
19541 {
19542 this->clear();
19543 *this << OP_DUP << OP_HASH160 << address.GetHash160() << OP_EQUALVERIFY << OP_CHECKSIG;
19544 }
19545
19546 void SetBitcoinAddress(const std::vector<unsigned char>& vchPubKey)
19547 {
19548 SetBitcoinAddress(CBitcoinAddress(vchPubKey));
19549 }
19550
19551
19552 void PrintHex() const
19553 {
19554 printf("CScript(%s)\n", HexStr(begin(), end(), true).c_str());
19555 }
19556
19557 std::string ToString() const
19558 {
19559 std::string str;
19560 opcodetype opcode;
19561 std::vector<unsigned char> vch;
19562 const_iterator pc = begin();
19563 while (pc < end())
19564 {
19565 if (!str.empty())
19566 str += " ";
19567 if (!GetOp(pc, opcode, vch))
19568 {
19569 str += "[error]";
19570 return str;
19571 }
19572 if (0 <= opcode && opcode <= OP_PUSHDATA4)
19573 str += ValueString(vch);
19574 else
19575 str += GetOpName(opcode);
19576 }
19577 return str;
19578 }
19579
19580 void print() const
19581 {
19582 printf("%s\n", ToString().c_str());
19583 }
19584 };
19585
19586
19587
19588
19589
19590
19591
19592 bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType);
19593
19594 bool IsStandard(const CScript& scriptPubKey);
19595 bool IsMine(const CKeyStore& keystore, const CScript& scriptPubKey);
19596 bool ExtractAddress(const CScript& scriptPubKey, const CKeyStore* pkeystore, CBitcoinAddress& addressRet);
19597 bool SignSignature(const CKeyStore& keystore, const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL, CScript scriptPrereq=CScript());
19598 bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, int nHashType=0);
19599
19600 #endif
-
+ 0C9BC8280A5657728CB63DA6F822999A40C0791D9C81DAAA779181A5A1B241B1130A088B280A0A74777D27DB144978D15E43BA21BCCE68CE4D202767BD19E297
bitcoin/src/serialize.h
(0 . 0)(1 . 1349)
19605 // Copyright (c) 2009-2010 Satoshi Nakamoto
19606 // Copyright (c) 2009-2012 The Bitcoin developers
19607 // Distributed under the MIT/X11 software license, see the accompanying
19608 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
19609 #ifndef BITCOIN_SERIALIZE_H
19610 #define BITCOIN_SERIALIZE_H
19611
19612 #include <string>
19613 #include <vector>
19614 #include <map>
19615 #include <set>
19616 #include <cassert>
19617 #include <climits>
19618 #include <cstring>
19619 #include <cstdio>
19620
19621 #include <boost/type_traits/is_fundamental.hpp>
19622 #include <boost/tuple/tuple.hpp>
19623 #include <boost/tuple/tuple_comparison.hpp>
19624 #include <boost/tuple/tuple_io.hpp>
19625
19626 #if defined(_MSC_VER) || defined(__BORLANDC__)
19627 typedef __int64 int64;
19628 typedef unsigned __int64 uint64;
19629 #else
19630 typedef long long int64;
19631 typedef unsigned long long uint64;
19632 #endif
19633 #if defined(_MSC_VER) && _MSC_VER < 1300
19634 #define for if (false) ; else for
19635 #endif
19636
19637 #ifdef WIN32
19638 #include <windows.h>
19639 // This is used to attempt to keep keying material out of swap
19640 // Note that VirtualLock does not provide this as a guarantee on Windows,
19641 // but, in practice, memory that has been VirtualLock'd almost never gets written to
19642 // the pagefile except in rare circumstances where memory is extremely low.
19643 #include <windows.h>
19644 #define mlock(p, n) VirtualLock((p), (n));
19645 #define munlock(p, n) VirtualUnlock((p), (n));
19646 #else
19647 #include <sys/mman.h>
19648 #include <limits.h>
19649 /* This comes from limits.h if it's not defined there set a sane default */
19650 #ifndef PAGESIZE
19651 #include <unistd.h>
19652 #define PAGESIZE sysconf(_SC_PAGESIZE)
19653 #endif
19654 #define mlock(a,b) \
19655 mlock(((void *)(((size_t)(a)) & (~((PAGESIZE)-1)))),\
19656 (((((size_t)(a)) + (b) - 1) | ((PAGESIZE) - 1)) + 1) - (((size_t)(a)) & (~((PAGESIZE) - 1))))
19657 #define munlock(a,b) \
19658 munlock(((void *)(((size_t)(a)) & (~((PAGESIZE)-1)))),\
19659 (((((size_t)(a)) + (b) - 1) | ((PAGESIZE) - 1)) + 1) - (((size_t)(a)) & (~((PAGESIZE) - 1))))
19660 #endif
19661
19662 class CScript;
19663 class CDataStream;
19664 class CAutoFile;
19665 static const unsigned int MAX_SIZE = 0x02000000;
19666
19667 static const int VERSION = 50300;
19668 static const char* pszSubVer = "";
19669 static const bool VERSION_IS_BETA = true;
19670
19671 // Used to bypass the rule against non-const reference to temporary
19672 // where it makes sense with wrappers such as CFlatData or CTxDB
19673 template<typename T>
19674 inline T& REF(const T& val)
19675 {
19676 return const_cast<T&>(val);
19677 }
19678
19679 /////////////////////////////////////////////////////////////////
19680 //
19681 // Templates for serializing to anything that looks like a stream,
19682 // i.e. anything that supports .read(char*, int) and .write(char*, int)
19683 //
19684
19685 enum
19686 {
19687 // primary actions
19688 SER_NETWORK = (1 << 0),
19689 SER_DISK = (1 << 1),
19690 SER_GETHASH = (1 << 2),
19691
19692 // modifiers
19693 SER_SKIPSIG = (1 << 16),
19694 SER_BLOCKHEADERONLY = (1 << 17),
19695 };
19696
19697 #define IMPLEMENT_SERIALIZE(statements) \
19698 unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const \
19699 { \
19700 CSerActionGetSerializeSize ser_action; \
19701 const bool fGetSize = true; \
19702 const bool fWrite = false; \
19703 const bool fRead = false; \
19704 unsigned int nSerSize = 0; \
19705 ser_streamplaceholder s; \
19706 assert(fGetSize||fWrite||fRead); /* suppress warning */ \
19707 s.nType = nType; \
19708 s.nVersion = nVersion; \
19709 {statements} \
19710 return nSerSize; \
19711 } \
19712 template<typename Stream> \
19713 void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const \
19714 { \
19715 CSerActionSerialize ser_action; \
19716 const bool fGetSize = false; \
19717 const bool fWrite = true; \
19718 const bool fRead = false; \
19719 unsigned int nSerSize = 0; \
19720 assert(fGetSize||fWrite||fRead); /* suppress warning */ \
19721 {statements} \
19722 } \
19723 template<typename Stream> \
19724 void Unserialize(Stream& s, int nType=0, int nVersion=VERSION) \
19725 { \
19726 CSerActionUnserialize ser_action; \
19727 const bool fGetSize = false; \
19728 const bool fWrite = false; \
19729 const bool fRead = true; \
19730 unsigned int nSerSize = 0; \
19731 assert(fGetSize||fWrite||fRead); /* suppress warning */ \
19732 {statements} \
19733 }
19734
19735 #define READWRITE(obj) (nSerSize += ::SerReadWrite(s, (obj), nType, nVersion, ser_action))
19736
19737
19738
19739
19740
19741
19742 //
19743 // Basic types
19744 //
19745 #define WRITEDATA(s, obj) s.write((char*)&(obj), sizeof(obj))
19746 #define READDATA(s, obj) s.read((char*)&(obj), sizeof(obj))
19747
19748 inline unsigned int GetSerializeSize(char a, int, int=0) { return sizeof(a); }
19749 inline unsigned int GetSerializeSize(signed char a, int, int=0) { return sizeof(a); }
19750 inline unsigned int GetSerializeSize(unsigned char a, int, int=0) { return sizeof(a); }
19751 inline unsigned int GetSerializeSize(signed short a, int, int=0) { return sizeof(a); }
19752 inline unsigned int GetSerializeSize(unsigned short a, int, int=0) { return sizeof(a); }
19753 inline unsigned int GetSerializeSize(signed int a, int, int=0) { return sizeof(a); }
19754 inline unsigned int GetSerializeSize(unsigned int a, int, int=0) { return sizeof(a); }
19755 inline unsigned int GetSerializeSize(signed long a, int, int=0) { return sizeof(a); }
19756 inline unsigned int GetSerializeSize(unsigned long a, int, int=0) { return sizeof(a); }
19757 inline unsigned int GetSerializeSize(int64 a, int, int=0) { return sizeof(a); }
19758 inline unsigned int GetSerializeSize(uint64 a, int, int=0) { return sizeof(a); }
19759 inline unsigned int GetSerializeSize(float a, int, int=0) { return sizeof(a); }
19760 inline unsigned int GetSerializeSize(double a, int, int=0) { return sizeof(a); }
19761
19762 template<typename Stream> inline void Serialize(Stream& s, char a, int, int=0) { WRITEDATA(s, a); }
19763 template<typename Stream> inline void Serialize(Stream& s, signed char a, int, int=0) { WRITEDATA(s, a); }
19764 template<typename Stream> inline void Serialize(Stream& s, unsigned char a, int, int=0) { WRITEDATA(s, a); }
19765 template<typename Stream> inline void Serialize(Stream& s, signed short a, int, int=0) { WRITEDATA(s, a); }
19766 template<typename Stream> inline void Serialize(Stream& s, unsigned short a, int, int=0) { WRITEDATA(s, a); }
19767 template<typename Stream> inline void Serialize(Stream& s, signed int a, int, int=0) { WRITEDATA(s, a); }
19768 template<typename Stream> inline void Serialize(Stream& s, unsigned int a, int, int=0) { WRITEDATA(s, a); }
19769 template<typename Stream> inline void Serialize(Stream& s, signed long a, int, int=0) { WRITEDATA(s, a); }
19770 template<typename Stream> inline void Serialize(Stream& s, unsigned long a, int, int=0) { WRITEDATA(s, a); }
19771 template<typename Stream> inline void Serialize(Stream& s, int64 a, int, int=0) { WRITEDATA(s, a); }
19772 template<typename Stream> inline void Serialize(Stream& s, uint64 a, int, int=0) { WRITEDATA(s, a); }
19773 template<typename Stream> inline void Serialize(Stream& s, float a, int, int=0) { WRITEDATA(s, a); }
19774 template<typename Stream> inline void Serialize(Stream& s, double a, int, int=0) { WRITEDATA(s, a); }
19775
19776 template<typename Stream> inline void Unserialize(Stream& s, char& a, int, int=0) { READDATA(s, a); }
19777 template<typename Stream> inline void Unserialize(Stream& s, signed char& a, int, int=0) { READDATA(s, a); }
19778 template<typename Stream> inline void Unserialize(Stream& s, unsigned char& a, int, int=0) { READDATA(s, a); }
19779 template<typename Stream> inline void Unserialize(Stream& s, signed short& a, int, int=0) { READDATA(s, a); }
19780 template<typename Stream> inline void Unserialize(Stream& s, unsigned short& a, int, int=0) { READDATA(s, a); }
19781 template<typename Stream> inline void Unserialize(Stream& s, signed int& a, int, int=0) { READDATA(s, a); }
19782 template<typename Stream> inline void Unserialize(Stream& s, unsigned int& a, int, int=0) { READDATA(s, a); }
19783 template<typename Stream> inline void Unserialize(Stream& s, signed long& a, int, int=0) { READDATA(s, a); }
19784 template<typename Stream> inline void Unserialize(Stream& s, unsigned long& a, int, int=0) { READDATA(s, a); }
19785 template<typename Stream> inline void Unserialize(Stream& s, int64& a, int, int=0) { READDATA(s, a); }
19786 template<typename Stream> inline void Unserialize(Stream& s, uint64& a, int, int=0) { READDATA(s, a); }
19787 template<typename Stream> inline void Unserialize(Stream& s, float& a, int, int=0) { READDATA(s, a); }
19788 template<typename Stream> inline void Unserialize(Stream& s, double& a, int, int=0) { READDATA(s, a); }
19789
19790 inline unsigned int GetSerializeSize(bool a, int, int=0) { return sizeof(char); }
19791 template<typename Stream> inline void Serialize(Stream& s, bool a, int, int=0) { char f=a; WRITEDATA(s, f); }
19792 template<typename Stream> inline void Unserialize(Stream& s, bool& a, int, int=0) { char f; READDATA(s, f); a=f; }
19793
19794
19795
19796
19797
19798
19799 //
19800 // Compact size
19801 // size < 253 -- 1 byte
19802 // size <= USHRT_MAX -- 3 bytes (253 + 2 bytes)
19803 // size <= UINT_MAX -- 5 bytes (254 + 4 bytes)
19804 // size > UINT_MAX -- 9 bytes (255 + 8 bytes)
19805 //
19806 inline unsigned int GetSizeOfCompactSize(uint64 nSize)
19807 {
19808 if (nSize < 253) return sizeof(unsigned char);
19809 else if (nSize <= USHRT_MAX) return sizeof(unsigned char) + sizeof(unsigned short);
19810 else if (nSize <= UINT_MAX) return sizeof(unsigned char) + sizeof(unsigned int);
19811 else return sizeof(unsigned char) + sizeof(uint64);
19812 }
19813
19814 template<typename Stream>
19815 void WriteCompactSize(Stream& os, uint64 nSize)
19816 {
19817 if (nSize < 253)
19818 {
19819 unsigned char chSize = nSize;
19820 WRITEDATA(os, chSize);
19821 }
19822 else if (nSize <= USHRT_MAX)
19823 {
19824 unsigned char chSize = 253;
19825 unsigned short xSize = nSize;
19826 WRITEDATA(os, chSize);
19827 WRITEDATA(os, xSize);
19828 }
19829 else if (nSize <= UINT_MAX)
19830 {
19831 unsigned char chSize = 254;
19832 unsigned int xSize = nSize;
19833 WRITEDATA(os, chSize);
19834 WRITEDATA(os, xSize);
19835 }
19836 else
19837 {
19838 unsigned char chSize = 255;
19839 uint64 xSize = nSize;
19840 WRITEDATA(os, chSize);
19841 WRITEDATA(os, xSize);
19842 }
19843 return;
19844 }
19845
19846 template<typename Stream>
19847 uint64 ReadCompactSize(Stream& is)
19848 {
19849 unsigned char chSize;
19850 READDATA(is, chSize);
19851 uint64 nSizeRet = 0;
19852 if (chSize < 253)
19853 {
19854 nSizeRet = chSize;
19855 }
19856 else if (chSize == 253)
19857 {
19858 unsigned short xSize;
19859 READDATA(is, xSize);
19860 nSizeRet = xSize;
19861 }
19862 else if (chSize == 254)
19863 {
19864 unsigned int xSize;
19865 READDATA(is, xSize);
19866 nSizeRet = xSize;
19867 }
19868 else
19869 {
19870 uint64 xSize;
19871 READDATA(is, xSize);
19872 nSizeRet = xSize;
19873 }
19874 if (nSizeRet > (uint64)MAX_SIZE)
19875 throw std::ios_base::failure("ReadCompactSize() : size too large");
19876 return nSizeRet;
19877 }
19878
19879
19880
19881 //
19882 // Wrapper for serializing arrays and POD
19883 // There's a clever template way to make arrays serialize normally, but MSVC6 doesn't support it
19884 //
19885 #define FLATDATA(obj) REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj)))
19886 class CFlatData
19887 {
19888 protected:
19889 char* pbegin;
19890 char* pend;
19891 public:
19892 CFlatData(void* pbeginIn, void* pendIn) : pbegin((char*)pbeginIn), pend((char*)pendIn) { }
19893 char* begin() { return pbegin; }
19894 const char* begin() const { return pbegin; }
19895 char* end() { return pend; }
19896 const char* end() const { return pend; }
19897
19898 unsigned int GetSerializeSize(int, int=0) const
19899 {
19900 return pend - pbegin;
19901 }
19902
19903 template<typename Stream>
19904 void Serialize(Stream& s, int, int=0) const
19905 {
19906 s.write(pbegin, pend - pbegin);
19907 }
19908
19909 template<typename Stream>
19910 void Unserialize(Stream& s, int, int=0)
19911 {
19912 s.read(pbegin, pend - pbegin);
19913 }
19914 };
19915
19916
19917
19918 //
19919 // string stored as a fixed length field
19920 //
19921 template<std::size_t LEN>
19922 class CFixedFieldString
19923 {
19924 protected:
19925 const std::string* pcstr;
19926 std::string* pstr;
19927 public:
19928 explicit CFixedFieldString(const std::string& str) : pcstr(&str), pstr(NULL) { }
19929 explicit CFixedFieldString(std::string& str) : pcstr(&str), pstr(&str) { }
19930
19931 unsigned int GetSerializeSize(int, int=0) const
19932 {
19933 return LEN;
19934 }
19935
19936 template<typename Stream>
19937 void Serialize(Stream& s, int, int=0) const
19938 {
19939 char pszBuf[LEN];
19940 strncpy(pszBuf, pcstr->c_str(), LEN);
19941 s.write(pszBuf, LEN);
19942 }
19943
19944 template<typename Stream>
19945 void Unserialize(Stream& s, int, int=0)
19946 {
19947 if (pstr == NULL)
19948 throw std::ios_base::failure("CFixedFieldString::Unserialize : trying to unserialize to const string");
19949 char pszBuf[LEN+1];
19950 s.read(pszBuf, LEN);
19951 pszBuf[LEN] = '\0';
19952 *pstr = pszBuf;
19953 }
19954 };
19955
19956
19957
19958
19959
19960 //
19961 // Forward declarations
19962 //
19963
19964 // string
19965 template<typename C> unsigned int GetSerializeSize(const std::basic_string<C>& str, int, int=0);
19966 template<typename Stream, typename C> void Serialize(Stream& os, const std::basic_string<C>& str, int, int=0);
19967 template<typename Stream, typename C> void Unserialize(Stream& is, std::basic_string<C>& str, int, int=0);
19968
19969 // vector
19970 template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&);
19971 template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&);
19972 template<typename T, typename A> inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion=VERSION);
19973 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&);
19974 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&);
19975 template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion=VERSION);
19976 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&);
19977 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&);
19978 template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion=VERSION);
19979
19980 // others derived from vector
19981 extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion=VERSION);
19982 template<typename Stream> void Serialize(Stream& os, const CScript& v, int nType, int nVersion=VERSION);
19983 template<typename Stream> void Unserialize(Stream& is, CScript& v, int nType, int nVersion=VERSION);
19984
19985 // pair
19986 template<typename K, typename T> unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion=VERSION);
19987 template<typename Stream, typename K, typename T> void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion=VERSION);
19988 template<typename Stream, typename K, typename T> void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion=VERSION);
19989
19990 // 3 tuple
19991 template<typename T0, typename T1, typename T2> unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2>& item, int nType, int nVersion=VERSION);
19992 template<typename Stream, typename T0, typename T1, typename T2> void Serialize(Stream& os, const boost::tuple<T0, T1, T2>& item, int nType, int nVersion=VERSION);
19993 template<typename Stream, typename T0, typename T1, typename T2> void Unserialize(Stream& is, boost::tuple<T0, T1, T2>& item, int nType, int nVersion=VERSION);
19994
19995 // 4 tuple
19996 template<typename T0, typename T1, typename T2, typename T3> unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion=VERSION);
19997 template<typename Stream, typename T0, typename T1, typename T2, typename T3> void Serialize(Stream& os, const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion=VERSION);
19998 template<typename Stream, typename T0, typename T1, typename T2, typename T3> void Unserialize(Stream& is, boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion=VERSION);
19999
20000 // map
20001 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);
20002 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);
20003 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);
20004
20005 // set
20006 template<typename K, typename Pred, typename A> unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion=VERSION);
20007 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);
20008 template<typename Stream, typename K, typename Pred, typename A> void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion=VERSION);
20009
20010
20011
20012
20013
20014 //
20015 // If none of the specialized versions above matched, default to calling member function.
20016 // "int nType" is changed to "long nType" to keep from getting an ambiguous overload error.
20017 // The compiler will only cast int to long if none of the other templates matched.
20018 // Thanks to Boost serialization for this idea.
20019 //
20020 template<typename T>
20021 inline unsigned int GetSerializeSize(const T& a, long nType, int nVersion=VERSION)
20022 {
20023 return a.GetSerializeSize((int)nType, nVersion);
20024 }
20025
20026 template<typename Stream, typename T>
20027 inline void Serialize(Stream& os, const T& a, long nType, int nVersion=VERSION)
20028 {
20029 a.Serialize(os, (int)nType, nVersion);
20030 }
20031
20032 template<typename Stream, typename T>
20033 inline void Unserialize(Stream& is, T& a, long nType, int nVersion=VERSION)
20034 {
20035 a.Unserialize(is, (int)nType, nVersion);
20036 }
20037
20038
20039
20040
20041
20042 //
20043 // string
20044 //
20045 template<typename C>
20046 unsigned int GetSerializeSize(const std::basic_string<C>& str, int, int)
20047 {
20048 return GetSizeOfCompactSize(str.size()) + str.size() * sizeof(str[0]);
20049 }
20050
20051 template<typename Stream, typename C>
20052 void Serialize(Stream& os, const std::basic_string<C>& str, int, int)
20053 {
20054 WriteCompactSize(os, str.size());
20055 if (!str.empty())
20056 os.write((char*)&str[0], str.size() * sizeof(str[0]));
20057 }
20058
20059 template<typename Stream, typename C>
20060 void Unserialize(Stream& is, std::basic_string<C>& str, int, int)
20061 {
20062 unsigned int nSize = ReadCompactSize(is);
20063 str.resize(nSize);
20064 if (nSize != 0)
20065 is.read((char*)&str[0], nSize * sizeof(str[0]));
20066 }
20067
20068
20069
20070 //
20071 // vector
20072 //
20073 template<typename T, typename A>
20074 unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&)
20075 {
20076 return (GetSizeOfCompactSize(v.size()) + v.size() * sizeof(T));
20077 }
20078
20079 template<typename T, typename A>
20080 unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&)
20081 {
20082 unsigned int nSize = GetSizeOfCompactSize(v.size());
20083 for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
20084 nSize += GetSerializeSize((*vi), nType, nVersion);
20085 return nSize;
20086 }
20087
20088 template<typename T, typename A>
20089 inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion)
20090 {
20091 return GetSerializeSize_impl(v, nType, nVersion, boost::is_fundamental<T>());
20092 }
20093
20094
20095 template<typename Stream, typename T, typename A>
20096 void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&)
20097 {
20098 WriteCompactSize(os, v.size());
20099 if (!v.empty())
20100 os.write((char*)&v[0], v.size() * sizeof(T));
20101 }
20102
20103 template<typename Stream, typename T, typename A>
20104 void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&)
20105 {
20106 WriteCompactSize(os, v.size());
20107 for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
20108 ::Serialize(os, (*vi), nType, nVersion);
20109 }
20110
20111 template<typename Stream, typename T, typename A>
20112 inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion)
20113 {
20114 Serialize_impl(os, v, nType, nVersion, boost::is_fundamental<T>());
20115 }
20116
20117
20118 template<typename Stream, typename T, typename A>
20119 void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&)
20120 {
20121 //unsigned int nSize = ReadCompactSize(is);
20122 //v.resize(nSize);
20123 //is.read((char*)&v[0], nSize * sizeof(T));
20124
20125 // Limit size per read so bogus size value won't cause out of memory
20126 v.clear();
20127 unsigned int nSize = ReadCompactSize(is);
20128 unsigned int i = 0;
20129 while (i < nSize)
20130 {
20131 unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
20132 v.resize(i + blk);
20133 is.read((char*)&v[i], blk * sizeof(T));
20134 i += blk;
20135 }
20136 }
20137
20138 template<typename Stream, typename T, typename A>
20139 void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&)
20140 {
20141 //unsigned int nSize = ReadCompactSize(is);
20142 //v.resize(nSize);
20143 //for (std::vector<T, A>::iterator vi = v.begin(); vi != v.end(); ++vi)
20144 // Unserialize(is, (*vi), nType, nVersion);
20145
20146 v.clear();
20147 unsigned int nSize = ReadCompactSize(is);
20148 unsigned int i = 0;
20149 unsigned int nMid = 0;
20150 while (nMid < nSize)
20151 {
20152 nMid += 5000000 / sizeof(T);
20153 if (nMid > nSize)
20154 nMid = nSize;
20155 v.resize(nMid);
20156 for (; i < nMid; i++)
20157 Unserialize(is, v[i], nType, nVersion);
20158 }
20159 }
20160
20161 template<typename Stream, typename T, typename A>
20162 inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion)
20163 {
20164 Unserialize_impl(is, v, nType, nVersion, boost::is_fundamental<T>());
20165 }
20166
20167
20168
20169 //
20170 // others derived from vector
20171 //
20172 inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion)
20173 {
20174 return GetSerializeSize((const std::vector<unsigned char>&)v, nType, nVersion);
20175 }
20176
20177 template<typename Stream>
20178 void Serialize(Stream& os, const CScript& v, int nType, int nVersion)
20179 {
20180 Serialize(os, (const std::vector<unsigned char>&)v, nType, nVersion);
20181 }
20182
20183 template<typename Stream>
20184 void Unserialize(Stream& is, CScript& v, int nType, int nVersion)
20185 {
20186 Unserialize(is, (std::vector<unsigned char>&)v, nType, nVersion);
20187 }
20188
20189
20190
20191 //
20192 // pair
20193 //
20194 template<typename K, typename T>
20195 unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion)
20196 {
20197 return GetSerializeSize(item.first, nType, nVersion) + GetSerializeSize(item.second, nType, nVersion);
20198 }
20199
20200 template<typename Stream, typename K, typename T>
20201 void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion)
20202 {
20203 Serialize(os, item.first, nType, nVersion);
20204 Serialize(os, item.second, nType, nVersion);
20205 }
20206
20207 template<typename Stream, typename K, typename T>
20208 void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion)
20209 {
20210 Unserialize(is, item.first, nType, nVersion);
20211 Unserialize(is, item.second, nType, nVersion);
20212 }
20213
20214
20215
20216 //
20217 // 3 tuple
20218 //
20219 template<typename T0, typename T1, typename T2>
20220 unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2>& item, int nType, int nVersion)
20221 {
20222 unsigned int nSize = 0;
20223 nSize += GetSerializeSize(boost::get<0>(item), nType, nVersion);
20224 nSize += GetSerializeSize(boost::get<1>(item), nType, nVersion);
20225 nSize += GetSerializeSize(boost::get<2>(item), nType, nVersion);
20226 return nSize;
20227 }
20228
20229 template<typename Stream, typename T0, typename T1, typename T2>
20230 void Serialize(Stream& os, const boost::tuple<T0, T1, T2>& item, int nType, int nVersion)
20231 {
20232 Serialize(os, boost::get<0>(item), nType, nVersion);
20233 Serialize(os, boost::get<1>(item), nType, nVersion);
20234 Serialize(os, boost::get<2>(item), nType, nVersion);
20235 }
20236
20237 template<typename Stream, typename T0, typename T1, typename T2>
20238 void Unserialize(Stream& is, boost::tuple<T0, T1, T2>& item, int nType, int nVersion)
20239 {
20240 Unserialize(is, boost::get<0>(item), nType, nVersion);
20241 Unserialize(is, boost::get<1>(item), nType, nVersion);
20242 Unserialize(is, boost::get<2>(item), nType, nVersion);
20243 }
20244
20245
20246
20247 //
20248 // 4 tuple
20249 //
20250 template<typename T0, typename T1, typename T2, typename T3>
20251 unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion)
20252 {
20253 unsigned int nSize = 0;
20254 nSize += GetSerializeSize(boost::get<0>(item), nType, nVersion);
20255 nSize += GetSerializeSize(boost::get<1>(item), nType, nVersion);
20256 nSize += GetSerializeSize(boost::get<2>(item), nType, nVersion);
20257 nSize += GetSerializeSize(boost::get<3>(item), nType, nVersion);
20258 return nSize;
20259 }
20260
20261 template<typename Stream, typename T0, typename T1, typename T2, typename T3>
20262 void Serialize(Stream& os, const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion)
20263 {
20264 Serialize(os, boost::get<0>(item), nType, nVersion);
20265 Serialize(os, boost::get<1>(item), nType, nVersion);
20266 Serialize(os, boost::get<2>(item), nType, nVersion);
20267 Serialize(os, boost::get<3>(item), nType, nVersion);
20268 }
20269
20270 template<typename Stream, typename T0, typename T1, typename T2, typename T3>
20271 void Unserialize(Stream& is, boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion)
20272 {
20273 Unserialize(is, boost::get<0>(item), nType, nVersion);
20274 Unserialize(is, boost::get<1>(item), nType, nVersion);
20275 Unserialize(is, boost::get<2>(item), nType, nVersion);
20276 Unserialize(is, boost::get<3>(item), nType, nVersion);
20277 }
20278
20279
20280
20281 //
20282 // map
20283 //
20284 template<typename K, typename T, typename Pred, typename A>
20285 unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion)
20286 {
20287 unsigned int nSize = GetSizeOfCompactSize(m.size());
20288 for (typename std::map<K, T, Pred, A>::const_iterator mi = m.begin(); mi != m.end(); ++mi)
20289 nSize += GetSerializeSize((*mi), nType, nVersion);
20290 return nSize;
20291 }
20292
20293 template<typename Stream, typename K, typename T, typename Pred, typename A>
20294 void Serialize(Stream& os, const std::map<K, T, Pred, A>& m, int nType, int nVersion)
20295 {
20296 WriteCompactSize(os, m.size());
20297 for (typename std::map<K, T, Pred, A>::const_iterator mi = m.begin(); mi != m.end(); ++mi)
20298 Serialize(os, (*mi), nType, nVersion);
20299 }
20300
20301 template<typename Stream, typename K, typename T, typename Pred, typename A>
20302 void Unserialize(Stream& is, std::map<K, T, Pred, A>& m, int nType, int nVersion)
20303 {
20304 m.clear();
20305 unsigned int nSize = ReadCompactSize(is);
20306 typename std::map<K, T, Pred, A>::iterator mi = m.begin();
20307 for (unsigned int i = 0; i < nSize; i++)
20308 {
20309 std::pair<K, T> item;
20310 Unserialize(is, item, nType, nVersion);
20311 mi = m.insert(mi, item);
20312 }
20313 }
20314
20315
20316
20317 //
20318 // set
20319 //
20320 template<typename K, typename Pred, typename A>
20321 unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion)
20322 {
20323 unsigned int nSize = GetSizeOfCompactSize(m.size());
20324 for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it)
20325 nSize += GetSerializeSize((*it), nType, nVersion);
20326 return nSize;
20327 }
20328
20329 template<typename Stream, typename K, typename Pred, typename A>
20330 void Serialize(Stream& os, const std::set<K, Pred, A>& m, int nType, int nVersion)
20331 {
20332 WriteCompactSize(os, m.size());
20333 for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it)
20334 Serialize(os, (*it), nType, nVersion);
20335 }
20336
20337 template<typename Stream, typename K, typename Pred, typename A>
20338 void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion)
20339 {
20340 m.clear();
20341 unsigned int nSize = ReadCompactSize(is);
20342 typename std::set<K, Pred, A>::iterator it = m.begin();
20343 for (unsigned int i = 0; i < nSize; i++)
20344 {
20345 K key;
20346 Unserialize(is, key, nType, nVersion);
20347 it = m.insert(it, key);
20348 }
20349 }
20350
20351
20352
20353 //
20354 // Support for IMPLEMENT_SERIALIZE and READWRITE macro
20355 //
20356 class CSerActionGetSerializeSize { };
20357 class CSerActionSerialize { };
20358 class CSerActionUnserialize { };
20359
20360 template<typename Stream, typename T>
20361 inline unsigned int SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionGetSerializeSize ser_action)
20362 {
20363 return ::GetSerializeSize(obj, nType, nVersion);
20364 }
20365
20366 template<typename Stream, typename T>
20367 inline unsigned int SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionSerialize ser_action)
20368 {
20369 ::Serialize(s, obj, nType, nVersion);
20370 return 0;
20371 }
20372
20373 template<typename Stream, typename T>
20374 inline unsigned int SerReadWrite(Stream& s, T& obj, int nType, int nVersion, CSerActionUnserialize ser_action)
20375 {
20376 ::Unserialize(s, obj, nType, nVersion);
20377 return 0;
20378 }
20379
20380 struct ser_streamplaceholder
20381 {
20382 int nType;
20383 int nVersion;
20384 };
20385
20386
20387
20388
20389
20390
20391
20392
20393
20394 //
20395 // Allocator that locks its contents from being paged
20396 // out of memory and clears its contents before deletion.
20397 //
20398 template<typename T>
20399 struct secure_allocator : public std::allocator<T>
20400 {
20401 // MSVC8 default copy constructor is broken
20402 typedef std::allocator<T> base;
20403 typedef typename base::size_type size_type;
20404 typedef typename base::difference_type difference_type;
20405 typedef typename base::pointer pointer;
20406 typedef typename base::const_pointer const_pointer;
20407 typedef typename base::reference reference;
20408 typedef typename base::const_reference const_reference;
20409 typedef typename base::value_type value_type;
20410 secure_allocator() throw() {}
20411 secure_allocator(const secure_allocator& a) throw() : base(a) {}
20412 template <typename U>
20413 secure_allocator(const secure_allocator<U>& a) throw() : base(a) {}
20414 ~secure_allocator() throw() {}
20415 template<typename _Other> struct rebind
20416 { typedef secure_allocator<_Other> other; };
20417
20418 T* allocate(std::size_t n, const void *hint = 0)
20419 {
20420 T *p;
20421 p = std::allocator<T>::allocate(n, hint);
20422 if (p != NULL)
20423 mlock(p, sizeof(T) * n);
20424 return p;
20425 }
20426
20427 void deallocate(T* p, std::size_t n)
20428 {
20429 if (p != NULL)
20430 {
20431 memset(p, 0, sizeof(T) * n);
20432 munlock(p, sizeof(T) * n);
20433 }
20434 std::allocator<T>::deallocate(p, n);
20435 }
20436 };
20437
20438
20439 //
20440 // Allocator that clears its contents before deletion.
20441 //
20442 template<typename T>
20443 struct zero_after_free_allocator : public std::allocator<T>
20444 {
20445 // MSVC8 default copy constructor is broken
20446 typedef std::allocator<T> base;
20447 typedef typename base::size_type size_type;
20448 typedef typename base::difference_type difference_type;
20449 typedef typename base::pointer pointer;
20450 typedef typename base::const_pointer const_pointer;
20451 typedef typename base::reference reference;
20452 typedef typename base::const_reference const_reference;
20453 typedef typename base::value_type value_type;
20454 zero_after_free_allocator() throw() {}
20455 zero_after_free_allocator(const zero_after_free_allocator& a) throw() : base(a) {}
20456 template <typename U>
20457 zero_after_free_allocator(const zero_after_free_allocator<U>& a) throw() : base(a) {}
20458 ~zero_after_free_allocator() throw() {}
20459 template<typename _Other> struct rebind
20460 { typedef zero_after_free_allocator<_Other> other; };
20461
20462 void deallocate(T* p, std::size_t n)
20463 {
20464 if (p != NULL)
20465 memset(p, 0, sizeof(T) * n);
20466 std::allocator<T>::deallocate(p, n);
20467 }
20468 };
20469
20470
20471
20472 //
20473 // Double ended buffer combining vector and stream-like interfaces.
20474 // >> and << read and write unformatted data using the above serialization templates.
20475 // Fills with data in linear time; some stringstream implementations take N^2 time.
20476 //
20477 class CDataStream
20478 {
20479 protected:
20480 typedef std::vector<char, zero_after_free_allocator<char> > vector_type;
20481 vector_type vch;
20482 unsigned int nReadPos;
20483 short state;
20484 short exceptmask;
20485 public:
20486 int nType;
20487 int nVersion;
20488
20489 typedef vector_type::allocator_type allocator_type;
20490 typedef vector_type::size_type size_type;
20491 typedef vector_type::difference_type difference_type;
20492 typedef vector_type::reference reference;
20493 typedef vector_type::const_reference const_reference;
20494 typedef vector_type::value_type value_type;
20495 typedef vector_type::iterator iterator;
20496 typedef vector_type::const_iterator const_iterator;
20497 typedef vector_type::reverse_iterator reverse_iterator;
20498
20499 explicit CDataStream(int nTypeIn=SER_NETWORK, int nVersionIn=VERSION)
20500 {
20501 Init(nTypeIn, nVersionIn);
20502 }
20503
20504 CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch(pbegin, pend)
20505 {
20506 Init(nTypeIn, nVersionIn);
20507 }
20508
20509 #if !defined(_MSC_VER) || _MSC_VER >= 1300
20510 CDataStream(const char* pbegin, const char* pend, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch(pbegin, pend)
20511 {
20512 Init(nTypeIn, nVersionIn);
20513 }
20514 #endif
20515
20516 CDataStream(const vector_type& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch(vchIn.begin(), vchIn.end())
20517 {
20518 Init(nTypeIn, nVersionIn);
20519 }
20520
20521 CDataStream(const std::vector<char>& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch(vchIn.begin(), vchIn.end())
20522 {
20523 Init(nTypeIn, nVersionIn);
20524 }
20525
20526 CDataStream(const std::vector<unsigned char>& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch((char*)&vchIn.begin()[0], (char*)&vchIn.end()[0])
20527 {
20528 Init(nTypeIn, nVersionIn);
20529 }
20530
20531 void Init(int nTypeIn=SER_NETWORK, int nVersionIn=VERSION)
20532 {
20533 nReadPos = 0;
20534 nType = nTypeIn;
20535 nVersion = nVersionIn;
20536 state = 0;
20537 exceptmask = std::ios::badbit | std::ios::failbit;
20538 }
20539
20540 CDataStream& operator+=(const CDataStream& b)
20541 {
20542 vch.insert(vch.end(), b.begin(), b.end());
20543 return *this;
20544 }
20545
20546 friend CDataStream operator+(const CDataStream& a, const CDataStream& b)
20547 {
20548 CDataStream ret = a;
20549 ret += b;
20550 return (ret);
20551 }
20552
20553 std::string str() const
20554 {
20555 return (std::string(begin(), end()));
20556 }
20557
20558
20559 //
20560 // Vector subset
20561 //
20562 const_iterator begin() const { return vch.begin() + nReadPos; }
20563 iterator begin() { return vch.begin() + nReadPos; }
20564 const_iterator end() const { return vch.end(); }
20565 iterator end() { return vch.end(); }
20566 size_type size() const { return vch.size() - nReadPos; }
20567 bool empty() const { return vch.size() == nReadPos; }
20568 void resize(size_type n, value_type c=0) { vch.resize(n + nReadPos, c); }
20569 void reserve(size_type n) { vch.reserve(n + nReadPos); }
20570 const_reference operator[](size_type pos) const { return vch[pos + nReadPos]; }
20571 reference operator[](size_type pos) { return vch[pos + nReadPos]; }
20572 void clear() { vch.clear(); nReadPos = 0; }
20573 iterator insert(iterator it, const char& x=char()) { return vch.insert(it, x); }
20574 void insert(iterator it, size_type n, const char& x) { vch.insert(it, n, x); }
20575
20576 void insert(iterator it, const_iterator first, const_iterator last)
20577 {
20578 if (it == vch.begin() + nReadPos && last - first <= nReadPos)
20579 {
20580 // special case for inserting at the front when there's room
20581 nReadPos -= (last - first);
20582 memcpy(&vch[nReadPos], &first[0], last - first);
20583 }
20584 else
20585 vch.insert(it, first, last);
20586 }
20587
20588 void insert(iterator it, std::vector<char>::const_iterator first, std::vector<char>::const_iterator last)
20589 {
20590 if (it == vch.begin() + nReadPos && last - first <= nReadPos)
20591 {
20592 // special case for inserting at the front when there's room
20593 nReadPos -= (last - first);
20594 memcpy(&vch[nReadPos], &first[0], last - first);
20595 }
20596 else
20597 vch.insert(it, first, last);
20598 }
20599
20600 #if !defined(_MSC_VER) || _MSC_VER >= 1300
20601 void insert(iterator it, const char* first, const char* last)
20602 {
20603 if (it == vch.begin() + nReadPos && last - first <= nReadPos)
20604 {
20605 // special case for inserting at the front when there's room
20606 nReadPos -= (last - first);
20607 memcpy(&vch[nReadPos], &first[0], last - first);
20608 }
20609 else
20610 vch.insert(it, first, last);
20611 }
20612 #endif
20613
20614 iterator erase(iterator it)
20615 {
20616 if (it == vch.begin() + nReadPos)
20617 {
20618 // special case for erasing from the front
20619 if (++nReadPos >= vch.size())
20620 {
20621 // whenever we reach the end, we take the opportunity to clear the buffer
20622 nReadPos = 0;
20623 return vch.erase(vch.begin(), vch.end());
20624 }
20625 return vch.begin() + nReadPos;
20626 }
20627 else
20628 return vch.erase(it);
20629 }
20630
20631 iterator erase(iterator first, iterator last)
20632 {
20633 if (first == vch.begin() + nReadPos)
20634 {
20635 // special case for erasing from the front
20636 if (last == vch.end())
20637 {
20638 nReadPos = 0;
20639 return vch.erase(vch.begin(), vch.end());
20640 }
20641 else
20642 {
20643 nReadPos = (last - vch.begin());
20644 return last;
20645 }
20646 }
20647 else
20648 return vch.erase(first, last);
20649 }
20650
20651 inline void Compact()
20652 {
20653 vch.erase(vch.begin(), vch.begin() + nReadPos);
20654 nReadPos = 0;
20655 }
20656
20657 bool Rewind(size_type n)
20658 {
20659 // Rewind by n characters if the buffer hasn't been compacted yet
20660 if (n > nReadPos)
20661 return false;
20662 nReadPos -= n;
20663 return true;
20664 }
20665
20666
20667 //
20668 // Stream subset
20669 //
20670 void setstate(short bits, const char* psz)
20671 {
20672 state |= bits;
20673 if (state & exceptmask)
20674 throw std::ios_base::failure(psz);
20675 }
20676
20677 bool eof() const { return size() == 0; }
20678 bool fail() const { return state & (std::ios::badbit | std::ios::failbit); }
20679 bool good() const { return !eof() && (state == 0); }
20680 void clear(short n) { state = n; } // name conflict with vector clear()
20681 short exceptions() { return exceptmask; }
20682 short exceptions(short mask) { short prev = exceptmask; exceptmask = mask; setstate(0, "CDataStream"); return prev; }
20683 CDataStream* rdbuf() { return this; }
20684 int in_avail() { return size(); }
20685
20686 void SetType(int n) { nType = n; }
20687 int GetType() { return nType; }
20688 void SetVersion(int n) { nVersion = n; }
20689 int GetVersion() { return nVersion; }
20690 void ReadVersion() { *this >> nVersion; }
20691 void WriteVersion() { *this << nVersion; }
20692
20693 CDataStream& read(char* pch, int nSize)
20694 {
20695 // Read from the beginning of the buffer
20696 assert(nSize >= 0);
20697 unsigned int nReadPosNext = nReadPos + nSize;
20698 if (nReadPosNext >= vch.size())
20699 {
20700 if (nReadPosNext > vch.size())
20701 {
20702 setstate(std::ios::failbit, "CDataStream::read() : end of data");
20703 memset(pch, 0, nSize);
20704 nSize = vch.size() - nReadPos;
20705 }
20706 memcpy(pch, &vch[nReadPos], nSize);
20707 nReadPos = 0;
20708 vch.clear();
20709 return (*this);
20710 }
20711 memcpy(pch, &vch[nReadPos], nSize);
20712 nReadPos = nReadPosNext;
20713 return (*this);
20714 }
20715
20716 CDataStream& ignore(int nSize)
20717 {
20718 // Ignore from the beginning of the buffer
20719 assert(nSize >= 0);
20720 unsigned int nReadPosNext = nReadPos + nSize;
20721 if (nReadPosNext >= vch.size())
20722 {
20723 if (nReadPosNext > vch.size())
20724 {
20725 setstate(std::ios::failbit, "CDataStream::ignore() : end of data");
20726 nSize = vch.size() - nReadPos;
20727 }
20728 nReadPos = 0;
20729 vch.clear();
20730 return (*this);
20731 }
20732 nReadPos = nReadPosNext;
20733 return (*this);
20734 }
20735
20736 CDataStream& write(const char* pch, int nSize)
20737 {
20738 // Write to the end of the buffer
20739 assert(nSize >= 0);
20740 vch.insert(vch.end(), pch, pch + nSize);
20741 return (*this);
20742 }
20743
20744 template<typename Stream>
20745 void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const
20746 {
20747 // Special case: stream << stream concatenates like stream += stream
20748 if (!vch.empty())
20749 s.write((char*)&vch[0], vch.size() * sizeof(vch[0]));
20750 }
20751
20752 template<typename T>
20753 unsigned int GetSerializeSize(const T& obj)
20754 {
20755 // Tells the size of the object if serialized to this stream
20756 return ::GetSerializeSize(obj, nType, nVersion);
20757 }
20758
20759 template<typename T>
20760 CDataStream& operator<<(const T& obj)
20761 {
20762 // Serialize to this stream
20763 ::Serialize(*this, obj, nType, nVersion);
20764 return (*this);
20765 }
20766
20767 template<typename T>
20768 CDataStream& operator>>(T& obj)
20769 {
20770 // Unserialize from this stream
20771 ::Unserialize(*this, obj, nType, nVersion);
20772 return (*this);
20773 }
20774 };
20775
20776 #ifdef TESTCDATASTREAM
20777 // VC6sp6
20778 // CDataStream:
20779 // n=1000 0 seconds
20780 // n=2000 0 seconds
20781 // n=4000 0 seconds
20782 // n=8000 0 seconds
20783 // n=16000 0 seconds
20784 // n=32000 0 seconds
20785 // n=64000 1 seconds
20786 // n=128000 1 seconds
20787 // n=256000 2 seconds
20788 // n=512000 4 seconds
20789 // n=1024000 8 seconds
20790 // n=2048000 16 seconds
20791 // n=4096000 32 seconds
20792 // stringstream:
20793 // n=1000 1 seconds
20794 // n=2000 1 seconds
20795 // n=4000 13 seconds
20796 // n=8000 87 seconds
20797 // n=16000 400 seconds
20798 // n=32000 1660 seconds
20799 // n=64000 6749 seconds
20800 // n=128000 27241 seconds
20801 // n=256000 109804 seconds
20802 #include <iostream>
20803 int main(int argc, char *argv[])
20804 {
20805 vector<unsigned char> vch(0xcc, 250);
20806 printf("CDataStream:\n");
20807 for (int n = 1000; n <= 4500000; n *= 2)
20808 {
20809 CDataStream ss;
20810 time_t nStart = time(NULL);
20811 for (int i = 0; i < n; i++)
20812 ss.write((char*)&vch[0], vch.size());
20813 printf("n=%-10d %d seconds\n", n, time(NULL) - nStart);
20814 }
20815 printf("stringstream:\n");
20816 for (int n = 1000; n <= 4500000; n *= 2)
20817 {
20818 stringstream ss;
20819 time_t nStart = time(NULL);
20820 for (int i = 0; i < n; i++)
20821 ss.write((char*)&vch[0], vch.size());
20822 printf("n=%-10d %d seconds\n", n, time(NULL) - nStart);
20823 }
20824 }
20825 #endif
20826
20827
20828
20829
20830
20831
20832
20833
20834
20835
20836 //
20837 // Automatic closing wrapper for FILE*
20838 // - Will automatically close the file when it goes out of scope if not null.
20839 // - If you're returning the file pointer, return file.release().
20840 // - If you need to close the file early, use file.fclose() instead of fclose(file).
20841 //
20842 class CAutoFile
20843 {
20844 protected:
20845 FILE* file;
20846 short state;
20847 short exceptmask;
20848 public:
20849 int nType;
20850 int nVersion;
20851
20852 typedef FILE element_type;
20853
20854 CAutoFile(FILE* filenew=NULL, int nTypeIn=SER_DISK, int nVersionIn=VERSION)
20855 {
20856 file = filenew;
20857 nType = nTypeIn;
20858 nVersion = nVersionIn;
20859 state = 0;
20860 exceptmask = std::ios::badbit | std::ios::failbit;
20861 }
20862
20863 ~CAutoFile()
20864 {
20865 fclose();
20866 }
20867
20868 void fclose()
20869 {
20870 if (file != NULL && file != stdin && file != stdout && file != stderr)
20871 ::fclose(file);
20872 file = NULL;
20873 }
20874
20875 FILE* release() { FILE* ret = file; file = NULL; return ret; }
20876 operator FILE*() { return file; }
20877 FILE* operator->() { return file; }
20878 FILE& operator*() { return *file; }
20879 FILE** operator&() { return &file; }
20880 FILE* operator=(FILE* pnew) { return file = pnew; }
20881 bool operator!() { return (file == NULL); }
20882
20883
20884 //
20885 // Stream subset
20886 //
20887 void setstate(short bits, const char* psz)
20888 {
20889 state |= bits;
20890 if (state & exceptmask)
20891 throw std::ios_base::failure(psz);
20892 }
20893
20894 bool fail() const { return state & (std::ios::badbit | std::ios::failbit); }
20895 bool good() const { return state == 0; }
20896 void clear(short n = 0) { state = n; }
20897 short exceptions() { return exceptmask; }
20898 short exceptions(short mask) { short prev = exceptmask; exceptmask = mask; setstate(0, "CAutoFile"); return prev; }
20899
20900 void SetType(int n) { nType = n; }
20901 int GetType() { return nType; }
20902 void SetVersion(int n) { nVersion = n; }
20903 int GetVersion() { return nVersion; }
20904 void ReadVersion() { *this >> nVersion; }
20905 void WriteVersion() { *this << nVersion; }
20906
20907 CAutoFile& read(char* pch, int nSize)
20908 {
20909 if (!file)
20910 throw std::ios_base::failure("CAutoFile::read : file handle is NULL");
20911 if (fread(pch, 1, nSize, file) != nSize)
20912 setstate(std::ios::failbit, feof(file) ? "CAutoFile::read : end of file" : "CAutoFile::read : fread failed");
20913 return (*this);
20914 }
20915
20916 CAutoFile& write(const char* pch, int nSize)
20917 {
20918 if (!file)
20919 throw std::ios_base::failure("CAutoFile::write : file handle is NULL");
20920 if (fwrite(pch, 1, nSize, file) != nSize)
20921 setstate(std::ios::failbit, "CAutoFile::write : write failed");
20922 return (*this);
20923 }
20924
20925 template<typename T>
20926 unsigned int GetSerializeSize(const T& obj)
20927 {
20928 // Tells the size of the object if serialized to this stream
20929 return ::GetSerializeSize(obj, nType, nVersion);
20930 }
20931
20932 template<typename T>
20933 CAutoFile& operator<<(const T& obj)
20934 {
20935 // Serialize to this stream
20936 if (!file)
20937 throw std::ios_base::failure("CAutoFile::operator<< : file handle is NULL");
20938 ::Serialize(*this, obj, nType, nVersion);
20939 return (*this);
20940 }
20941
20942 template<typename T>
20943 CAutoFile& operator>>(T& obj)
20944 {
20945 // Unserialize from this stream
20946 if (!file)
20947 throw std::ios_base::failure("CAutoFile::operator>> : file handle is NULL");
20948 ::Unserialize(*this, obj, nType, nVersion);
20949 return (*this);
20950 }
20951 };
20952
20953 #endif
-
+ 6184E61CD8740055811EF3B1E662C5A0161F9F209F85EC79287C5391D66FB91ECD625D9D7F9327C751AB1D799821409AFC9552147C45A2BD636574DBA2B78955
bitcoin/src/strlcpy.h
(0 . 0)(1 . 86)
20958 /*
20959 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
20960 *
20961 * Permission to use, copy, modify, and distribute this software for any
20962 * purpose with or without fee is hereby granted, provided that the above
20963 * copyright notice and this permission notice appear in all copies.
20964 *
20965 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
20966 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
20967 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
20968 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20969 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20970 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
20971 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20972 */
20973 #ifndef BITCOIN_STRLCPY_H
20974 #define BITCOIN_STRLCPY_H
20975 /*
20976 * Copy src to string dst of size siz. At most siz-1 characters
20977 * will be copied. Always NUL terminates (unless siz == 0).
20978 * Returns strlen(src); if retval >= siz, truncation occurred.
20979 */
20980 inline size_t strlcpy(char *dst, const char *src, size_t siz)
20981 {
20982 char *d = dst;
20983 const char *s = src;
20984 size_t n = siz;
20985
20986 /* Copy as many bytes as will fit */
20987 if (n != 0)
20988 {
20989 while (--n != 0)
20990 {
20991 if ((*d++ = *s++) == '\0')
20992 break;
20993 }
20994 }
20995
20996 /* Not enough room in dst, add NUL and traverse rest of src */
20997 if (n == 0)
20998 {
20999 if (siz != 0)
21000 *d = '\0'; /* NUL-terminate dst */
21001 while (*s++)
21002 ;
21003 }
21004
21005 return(s - src - 1); /* count does not include NUL */
21006 }
21007
21008 /*
21009 * Appends src to string dst of size siz (unlike strncat, siz is the
21010 * full size of dst, not space left). At most siz-1 characters
21011 * will be copied. Always NUL terminates (unless siz <= strlen(dst)).
21012 * Returns strlen(src) + MIN(siz, strlen(initial dst)).
21013 * If retval >= siz, truncation occurred.
21014 */
21015 inline size_t strlcat(char *dst, const char *src, size_t siz)
21016 {
21017 char *d = dst;
21018 const char *s = src;
21019 size_t n = siz;
21020 size_t dlen;
21021
21022 /* Find the end of dst and adjust bytes left but don't go past end */
21023 while (n-- != 0 && *d != '\0')
21024 d++;
21025 dlen = d - dst;
21026 n = siz - dlen;
21027
21028 if (n == 0)
21029 return(dlen + strlen(s));
21030 while (*s != '\0')
21031 {
21032 if (n != 1)
21033 {
21034 *d++ = *s;
21035 n--;
21036 }
21037 s++;
21038 }
21039 *d = '\0';
21040
21041 return(dlen + (s - src)); /* count does not include NUL */
21042 }
21043 #endif
-
+ E067EDB9BA652729FF0A427FE7E8817AA741A011A640F2CA72242AC94E5E99FB650D68CF79109050B2796FC846EA3E912C7C2B3BBC3AEB6D1FE72459652F4BD7
bitcoin/src/test/Checkpoints_tests.cpp
(0 . 0)(1 . 34)
21048 //
21049 // Unit tests for block-chain checkpoints
21050 //
21051 #include <boost/assign/list_of.hpp> // for 'map_list_of()'
21052 #include <boost/test/unit_test.hpp>
21053 #include <boost/foreach.hpp>
21054
21055 #include "../checkpoints.h"
21056 #include "../util.h"
21057
21058 using namespace std;
21059
21060 BOOST_AUTO_TEST_SUITE(Checkpoints_tests)
21061
21062 BOOST_AUTO_TEST_CASE(sanity)
21063 {
21064 uint256 p11111 = uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d");
21065 uint256 p140700 = uint256("0x000000000000033b512028abb90e1626d8b346fd0ed598ac0a3c371138dce2bd");
21066 BOOST_CHECK(Checkpoints::CheckBlock(11111, p11111));
21067 BOOST_CHECK(Checkpoints::CheckBlock(140700, p140700));
21068
21069
21070 // Wrong hashes at checkpoints should fail:
21071 BOOST_CHECK(!Checkpoints::CheckBlock(11111, p140700));
21072 BOOST_CHECK(!Checkpoints::CheckBlock(140700, p11111));
21073
21074 // ... but any hash not at a checkpoint should succeed:
21075 BOOST_CHECK(Checkpoints::CheckBlock(11111+1, p140700));
21076 BOOST_CHECK(Checkpoints::CheckBlock(140700+1, p11111));
21077
21078 BOOST_CHECK(Checkpoints::GetTotalBlocksEstimate() >= 140700);
21079 }
21080
21081 BOOST_AUTO_TEST_SUITE_END()
-
+ 659A2051587B7FBDA983483D663335742029D73C9461311C97C14619E4BB1DAECC700086D308AC3D03C77987FF76D8E4317B5686CB93809FACD9D968827310C9
bitcoin/src/test/DoS_tests.cpp
(0 . 0)(1 . 118)
21086 //
21087 // Unit tests for denial-of-service detection/prevention code
21088 //
21089 #include <boost/assign/list_of.hpp> // for 'map_list_of()'
21090 #include <boost/test/unit_test.hpp>
21091 #include <boost/foreach.hpp>
21092
21093 #include "../main.h"
21094 #include "../net.h"
21095 #include "../util.h"
21096
21097 using namespace std;
21098
21099 BOOST_AUTO_TEST_SUITE(DoS_tests)
21100
21101 BOOST_AUTO_TEST_CASE(DoS_banning)
21102 {
21103 CNode::ClearBanned();
21104 CAddress addr1(0xa0b0c001);
21105 CNode dummyNode1(INVALID_SOCKET, addr1, true);
21106 dummyNode1.Misbehaving(100); // Should get banned
21107 BOOST_CHECK(CNode::IsBanned(addr1.ip));
21108 BOOST_CHECK(!CNode::IsBanned(addr1.ip|0x0000ff00)); // Different ip, not banned
21109
21110 CAddress addr2(0xa0b0c002);
21111 CNode dummyNode2(INVALID_SOCKET, addr2, true);
21112 dummyNode2.Misbehaving(50);
21113 BOOST_CHECK(!CNode::IsBanned(addr2.ip)); // 2 not banned yet...
21114 BOOST_CHECK(CNode::IsBanned(addr1.ip)); // ... but 1 still should be
21115 dummyNode2.Misbehaving(50);
21116 BOOST_CHECK(CNode::IsBanned(addr2.ip));
21117 }
21118
21119 BOOST_AUTO_TEST_CASE(DoS_banscore)
21120 {
21121 CNode::ClearBanned();
21122 mapArgs["-banscore"] = "111"; // because 11 is my favorite number
21123 CAddress addr1(0xa0b0c001);
21124 CNode dummyNode1(INVALID_SOCKET, addr1, true);
21125 dummyNode1.Misbehaving(100);
21126 BOOST_CHECK(!CNode::IsBanned(addr1.ip));
21127 dummyNode1.Misbehaving(10);
21128 BOOST_CHECK(!CNode::IsBanned(addr1.ip));
21129 dummyNode1.Misbehaving(1);
21130 BOOST_CHECK(CNode::IsBanned(addr1.ip));
21131 mapArgs["-banscore"] = "100";
21132 }
21133
21134 BOOST_AUTO_TEST_CASE(DoS_bantime)
21135 {
21136 CNode::ClearBanned();
21137 int64 nStartTime = GetTime();
21138 SetMockTime(nStartTime); // Overrides future calls to GetTime()
21139
21140 CAddress addr(0xa0b0c001);
21141 CNode dummyNode(INVALID_SOCKET, addr, true);
21142
21143 dummyNode.Misbehaving(100);
21144 BOOST_CHECK(CNode::IsBanned(addr.ip));
21145
21146 SetMockTime(nStartTime+60*60);
21147 BOOST_CHECK(CNode::IsBanned(addr.ip));
21148
21149 SetMockTime(nStartTime+60*60*24+1);
21150 BOOST_CHECK(!CNode::IsBanned(addr.ip));
21151 }
21152
21153 static bool CheckNBits(unsigned int nbits1, int64 time1, unsigned int nbits2, int64 time2)
21154 {
21155 if (time1 > time2)
21156 return CheckNBits(nbits2, time2, nbits1, time1);
21157 int64 deltaTime = time2-time1;
21158
21159 CBigNum required;
21160 required.SetCompact(ComputeMinWork(nbits1, deltaTime));
21161 CBigNum have;
21162 have.SetCompact(nbits2);
21163 return (have <= required);
21164 }
21165
21166 BOOST_AUTO_TEST_CASE(DoS_checknbits)
21167 {
21168 using namespace boost::assign; // for 'map_list_of()'
21169
21170 // Timestamps,nBits from the bitcoin blockchain.
21171 // These are the block-chain checkpoint blocks
21172 typedef std::map<int64, unsigned int> BlockData;
21173 BlockData chainData =
21174 map_list_of(1239852051,486604799)(1262749024,486594666)
21175 (1279305360,469854461)(1280200847,469830746)(1281678674,469809688)
21176 (1296207707,453179945)(1302624061,453036989)(1309640330,437004818)
21177 (1313172719,436789733);
21178
21179 // Make sure CheckNBits considers every combination of block-chain-lock-in-points
21180 // "sane":
21181 BOOST_FOREACH(const BlockData::value_type& i, chainData)
21182 {
21183 BOOST_FOREACH(const BlockData::value_type& j, chainData)
21184 {
21185 BOOST_CHECK(CheckNBits(i.second, i.first, j.second, j.first));
21186 }
21187 }
21188
21189 // Test a couple of insane combinations:
21190 BlockData::value_type firstcheck = *(chainData.begin());
21191 BlockData::value_type lastcheck = *(chainData.rbegin());
21192
21193 // First checkpoint difficulty at or a while after the last checkpoint time should fail when
21194 // compared to last checkpoint
21195 BOOST_CHECK(!CheckNBits(firstcheck.second, lastcheck.first+60*10, lastcheck.second, lastcheck.first));
21196 BOOST_CHECK(!CheckNBits(firstcheck.second, lastcheck.first+60*60*24*14, lastcheck.second, lastcheck.first));
21197
21198 // ... but OK if enough time passed for difficulty to adjust downward:
21199 BOOST_CHECK(CheckNBits(firstcheck.second, lastcheck.first+60*60*24*365*4, lastcheck.second, lastcheck.first));
21200
21201 }
21202
21203 BOOST_AUTO_TEST_SUITE_END()
-
+ 4B87B83C415AA00E319AC929F7C41302D5D7236C2FD9AB74C284E54C9A9377CBD3D326D2C8AAB33F17F6450B89A15E82D634C72CFAB185687E6E0DF55545509C
bitcoin/src/test/README
(0 . 0)(1 . 21)
21208 The sources in this directory are unit test cases. Boost includes a
21209 unit testing framework, and since bitcoin already uses boost, it makes
21210 sense to simply use this framework rather than require developers to
21211 configure some other framework (we want as few impediments to creating
21212 unit tests as possible).
21213
21214 The build system is setup to compile an executable called "test_bitcoin"
21215 that runs all of the unit tests. The main source file is called
21216 test_bitcoin.cpp, which simply includes other files that contain the
21217 actual unit tests (outside of a couple required preprocessor
21218 directives). The pattern is to create one test file for each class or
21219 source file for which you want to create unit tests. The file naming
21220 convention is "<source_filename>_tests.cpp" and such files should wrap
21221 their tests in a test suite called "<source_filename>_tests". For an
21222 examples of this pattern, examine uint160_tests.cpp and
21223 uint256_tests.cpp.
21224
21225 For further reading, I found the following website to be helpful in
21226 explaining how the boost unit test framework works:
21227
21228 http://www.alittlemadness.com/2009/03/31/c-unit-testing-with-boosttest/
-
+ 6DE87EB22BA89C5304298FDF96627B4581D5C7C5CA10C200B35032E042AB513CD6023CF1B0EFAC215309E9DFEAA5F7171A45C7557137F4FD36BD3B0EBAA6A569
bitcoin/src/test/base58_tests.cpp
(0 . 0)(1 . 87)
21233 #include <boost/test/unit_test.hpp>
21234
21235 #include "../util.h"
21236
21237 BOOST_AUTO_TEST_SUITE(base58_tests)
21238
21239 // TODO:
21240 // EncodeBase58Check
21241 // DecodeBase58Check
21242 // CBase58Data
21243 // bool SetString(const char* psz)
21244 // bool SetString(const std::string& str)
21245 // std::string ToString() const
21246 // int CompareTo(const CBase58Data& b58) const
21247 // bool operator==(const CBase58Data& b58) const
21248 // bool operator<=(const CBase58Data& b58) const
21249 // bool operator>=(const CBase58Data& b58) const
21250 // bool operator< (const CBase58Data& b58) const
21251 // bool operator> (const CBase58Data& b58) const
21252
21253 // CBitcoinAddress
21254 // bool SetHash160(const uint160& hash160)
21255 // bool SetPubKey(const std::vector<unsigned char>& vchPubKey)
21256 // bool IsValid() const
21257 // CBitcoinAddress()
21258 // CBitcoinAddress(uint160 hash160In)
21259 // CBitcoinAddress(const std::vector<unsigned char>& vchPubKey)
21260 // CBitcoinAddress(const std::string& strAddress)
21261 // CBitcoinAddress(const char* pszAddress)
21262 // uint160 GetHash160() const
21263
21264 #define U(x) (reinterpret_cast<const unsigned char*>(x))
21265 static struct {
21266 const unsigned char *data;
21267 int size;
21268 } vstrIn[] = {
21269 {U(""), 0},
21270 {U("\x61"), 1},
21271 {U("\x62\x62\x62"), 3},
21272 {U("\x63\x63\x63"), 3},
21273 {U("\x73\x69\x6d\x70\x6c\x79\x20\x61\x20\x6c\x6f\x6e\x67\x20\x73\x74\x72\x69\x6e\x67"), 20},
21274 {U("\x00\xeb\x15\x23\x1d\xfc\xeb\x60\x92\x58\x86\xb6\x7d\x06\x52\x99\x92\x59\x15\xae\xb1\x72\xc0\x66\x47"), 25},
21275 {U("\x51\x6b\x6f\xcd\x0f"), 5},
21276 {U("\xbf\x4f\x89\x00\x1e\x67\x02\x74\xdd"), 9},
21277 {U("\x57\x2e\x47\x94"), 4},
21278 {U("\xec\xac\x89\xca\xd9\x39\x23\xc0\x23\x21"), 10},
21279 {U("\x10\xc8\x51\x1e"), 4},
21280 {U("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"), 10},
21281 };
21282
21283 const char *vstrOut[] = {
21284 "",
21285 "2g",
21286 "a3gV",
21287 "aPEr",
21288 "2cFupjhnEsSn59qHXstmK2ffpLv2",
21289 "1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L",
21290 "ABnLTmg",
21291 "3SEo3LWLoPntC",
21292 "3EFU7m",
21293 "EJDM8drfXA6uyA",
21294 "Rt5zm",
21295 "1111111111"
21296 };
21297
21298 BOOST_AUTO_TEST_CASE(base58_EncodeBase58)
21299 {
21300 for (int i=0; i<sizeof(vstrIn)/sizeof(vstrIn[0]); i++)
21301 {
21302 BOOST_CHECK_EQUAL(EncodeBase58(vstrIn[i].data, vstrIn[i].data + vstrIn[i].size), vstrOut[i]);
21303 }
21304 }
21305
21306 BOOST_AUTO_TEST_CASE(base58_DecodeBase58)
21307 {
21308 std::vector<unsigned char> result;
21309 for (int i=0; i<sizeof(vstrIn)/sizeof(vstrIn[0]); i++)
21310 {
21311 std::vector<unsigned char> expected(vstrIn[i].data, vstrIn[i].data + vstrIn[i].size);
21312 BOOST_CHECK(DecodeBase58(vstrOut[i], result));
21313 BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
21314 }
21315 BOOST_CHECK(!DecodeBase58("invalid", result));
21316 }
21317
21318 BOOST_AUTO_TEST_SUITE_END()
21319
-
+ D647D343641733DDF8D90510972D54CF8D9D5B6C5B18DC36D2DF0B4C125628DCD12EEC9E82B66FF6E3333C811B18DB84F47816D65A8CCA487ECD0276CCA581D9
bitcoin/src/test/base64_tests.cpp
(0 . 0)(1 . 20)
21324 #include <boost/test/unit_test.hpp>
21325
21326 #include "../util.h"
21327
21328 BOOST_AUTO_TEST_SUITE(base64_tests)
21329
21330 BOOST_AUTO_TEST_CASE(base64_testvectors)
21331 {
21332 static const string vstrIn[] = {"","f","fo","foo","foob","fooba","foobar"};
21333 static const string vstrOut[] = {"","Zg==","Zm8=","Zm9v","Zm9vYg==","Zm9vYmE=","Zm9vYmFy"};
21334 for (int i=0; i<sizeof(vstrIn)/sizeof(vstrIn[0]); i++)
21335 {
21336 string strEnc = EncodeBase64(vstrIn[i]);
21337 BOOST_CHECK(strEnc == vstrOut[i]);
21338 string strDec = DecodeBase64(strEnc);
21339 BOOST_CHECK(strDec == vstrIn[i]);
21340 }
21341 }
21342
21343 BOOST_AUTO_TEST_SUITE_END()
-
+ 2A9EF7188884C3709442DF17B980E688E5CAC6ECC456A093710B20C238C115238BCD243D8BE5E7684978B1BFB287E6CAD84688180DB6A4BB432DBA449E471420
bitcoin/src/test/miner_tests.cpp
(0 . 0)(1 . 35)
21348 #include <boost/test/unit_test.hpp>
21349
21350 #include "../uint256.h"
21351
21352 extern void SHA256Transform(void* pstate, void* pinput, const void* pinit);
21353
21354 BOOST_AUTO_TEST_SUITE(miner_tests)
21355
21356 BOOST_AUTO_TEST_CASE(sha256transform_equality)
21357 {
21358 unsigned int pSHA256InitState[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
21359
21360
21361 unsigned char pstate[32];
21362 unsigned char pinput[64];
21363
21364 int i;
21365
21366 for (i = 0; i < 32; i++) {
21367 pinput[i] = i;
21368 pinput[i+32] = 0;
21369 }
21370
21371 uint256 hash;
21372
21373 SHA256Transform(&hash, pinput, pSHA256InitState);
21374
21375 BOOST_TEST_MESSAGE(hash.GetHex());
21376
21377 uint256 hash_reference("0x2df5e1c65ef9f8cde240d23cae2ec036d31a15ec64bc68f64be242b1da6631f3");
21378
21379 BOOST_CHECK(hash == hash_reference);
21380 }
21381
21382 BOOST_AUTO_TEST_SUITE_END()
-
+ 1672C86E35D81A41CA3043FEC45BCD3A6278D29FD6C7E040EC84E969839639AA40E4ABD5D7096F10AC37D46E41479E219BC4747872768DDEBF4173521CCBEC75
bitcoin/src/test/script_tests.cpp
(0 . 0)(1 . 173)
21387 #include <vector>
21388 #include <boost/test/unit_test.hpp>
21389 #include <boost/foreach.hpp>
21390
21391 #include "../main.h"
21392 #include "../wallet.h"
21393
21394 using namespace std;
21395 extern uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType);
21396 extern bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, int nHashType);
21397 extern bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, int nHashType);
21398
21399 BOOST_AUTO_TEST_SUITE(script_tests)
21400
21401 BOOST_AUTO_TEST_CASE(script_PushData)
21402 {
21403 // Check that PUSHDATA1, PUSHDATA2, and PUSHDATA4 create the same value on
21404 // the stack as the 1-75 opcodes do.
21405 static const unsigned char direct[] = { 1, 0x5a };
21406 static const unsigned char pushdata1[] = { OP_PUSHDATA1, 1, 0x5a };
21407 static const unsigned char pushdata2[] = { OP_PUSHDATA2, 1, 0, 0x5a };
21408 static const unsigned char pushdata4[] = { OP_PUSHDATA4, 1, 0, 0, 0, 0x5a };
21409
21410 vector<vector<unsigned char> > directStack;
21411 BOOST_CHECK(EvalScript(directStack, CScript(&direct[0], &direct[sizeof(direct)]), CTransaction(), 0, 0));
21412
21413 vector<vector<unsigned char> > pushdata1Stack;
21414 BOOST_CHECK(EvalScript(pushdata1Stack, CScript(&pushdata1[0], &pushdata1[sizeof(pushdata1)]), CTransaction(), 0, 0));
21415 BOOST_CHECK(pushdata1Stack == directStack);
21416
21417 vector<vector<unsigned char> > pushdata2Stack;
21418 BOOST_CHECK(EvalScript(pushdata2Stack, CScript(&pushdata2[0], &pushdata2[sizeof(pushdata2)]), CTransaction(), 0, 0));
21419 BOOST_CHECK(pushdata2Stack == directStack);
21420
21421 vector<vector<unsigned char> > pushdata4Stack;
21422 BOOST_CHECK(EvalScript(pushdata4Stack, CScript(&pushdata4[0], &pushdata4[sizeof(pushdata4)]), CTransaction(), 0, 0));
21423 BOOST_CHECK(pushdata4Stack == directStack);
21424 }
21425
21426 CScript
21427 sign_multisig(CScript scriptPubKey, std::vector<CKey> keys, CTransaction transaction)
21428 {
21429 uint256 hash = SignatureHash(scriptPubKey, transaction, 0, SIGHASH_ALL);
21430
21431 CScript result;
21432 //
21433 // NOTE: CHECKMULTISIG has an unfortunate bug; it requires
21434 // one extra item on the stack, before the signatures.
21435 // Putting OP_0 on the stack is the workaround;
21436 // fixing the bug would mean splitting the blockchain (old
21437 // clients would not accept new CHECKMULTISIG transactions,
21438 // and vice-versa)
21439 //
21440 result << OP_0;
21441 BOOST_FOREACH(CKey key, keys)
21442 {
21443 vector<unsigned char> vchSig;
21444 BOOST_CHECK(key.Sign(hash, vchSig));
21445 vchSig.push_back((unsigned char)SIGHASH_ALL);
21446 result << vchSig;
21447 }
21448 return result;
21449 }
21450 CScript
21451 sign_multisig(CScript scriptPubKey, CKey key, CTransaction transaction)
21452 {
21453 std::vector<CKey> keys;
21454 keys.push_back(key);
21455 return sign_multisig(scriptPubKey, keys, transaction);
21456 }
21457
21458 BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG12)
21459 {
21460 CKey key1, key2, key3;
21461 key1.MakeNewKey();
21462 key2.MakeNewKey();
21463 key3.MakeNewKey();
21464
21465 CScript scriptPubKey12;
21466 scriptPubKey12 << OP_1 << key1.GetPubKey() << key2.GetPubKey() << OP_2 << OP_CHECKMULTISIG;
21467
21468 CTransaction txFrom12;
21469 txFrom12.vout.resize(1);
21470 txFrom12.vout[0].scriptPubKey = scriptPubKey12;
21471
21472 CTransaction txTo12;
21473 txTo12.vin.resize(1);
21474 txTo12.vout.resize(1);
21475 txTo12.vin[0].prevout.n = 0;
21476 txTo12.vin[0].prevout.hash = txFrom12.GetHash();
21477 txTo12.vout[0].nValue = 1;
21478
21479 CScript goodsig1 = sign_multisig(scriptPubKey12, key1, txTo12);
21480 BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, txTo12, 0, 0));
21481 txTo12.vout[0].nValue = 2;
21482 BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, txTo12, 0, 0));
21483
21484 CScript goodsig2 = sign_multisig(scriptPubKey12, key2, txTo12);
21485 BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, txTo12, 0, 0));
21486
21487 CScript badsig1 = sign_multisig(scriptPubKey12, key3, txTo12);
21488 BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, txTo12, 0, 0));
21489 }
21490
21491 BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23)
21492 {
21493 CKey key1, key2, key3, key4;
21494 key1.MakeNewKey();
21495 key2.MakeNewKey();
21496 key3.MakeNewKey();
21497 key4.MakeNewKey();
21498
21499 CScript scriptPubKey23;
21500 scriptPubKey23 << OP_2 << key1.GetPubKey() << key2.GetPubKey() << key3.GetPubKey() << OP_3 << OP_CHECKMULTISIG;
21501
21502 CTransaction txFrom23;
21503 txFrom23.vout.resize(1);
21504 txFrom23.vout[0].scriptPubKey = scriptPubKey23;
21505
21506 CTransaction txTo23;
21507 txTo23.vin.resize(1);
21508 txTo23.vout.resize(1);
21509 txTo23.vin[0].prevout.n = 0;
21510 txTo23.vin[0].prevout.hash = txFrom23.GetHash();
21511 txTo23.vout[0].nValue = 1;
21512
21513 std::vector<CKey> keys;
21514 keys.push_back(key1); keys.push_back(key2);
21515 CScript goodsig1 = sign_multisig(scriptPubKey23, keys, txTo23);
21516 BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, txTo23, 0, 0));
21517
21518 keys.clear();
21519 keys.push_back(key1); keys.push_back(key3);
21520 CScript goodsig2 = sign_multisig(scriptPubKey23, keys, txTo23);
21521 BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, txTo23, 0, 0));
21522
21523 keys.clear();
21524 keys.push_back(key2); keys.push_back(key3);
21525 CScript goodsig3 = sign_multisig(scriptPubKey23, keys, txTo23);
21526 BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, txTo23, 0, 0));
21527
21528 keys.clear();
21529 keys.push_back(key2); keys.push_back(key2); // Can't re-use sig
21530 CScript badsig1 = sign_multisig(scriptPubKey23, keys, txTo23);
21531 BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, txTo23, 0, 0));
21532
21533 keys.clear();
21534 keys.push_back(key2); keys.push_back(key1); // sigs must be in correct order
21535 CScript badsig2 = sign_multisig(scriptPubKey23, keys, txTo23);
21536 BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, txTo23, 0, 0));
21537
21538 keys.clear();
21539 keys.push_back(key3); keys.push_back(key2); // sigs must be in correct order
21540 CScript badsig3 = sign_multisig(scriptPubKey23, keys, txTo23);
21541 BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, txTo23, 0, 0));
21542
21543 keys.clear();
21544 keys.push_back(key4); keys.push_back(key2); // sigs must match pubkeys
21545 CScript badsig4 = sign_multisig(scriptPubKey23, keys, txTo23);
21546 BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, txTo23, 0, 0));
21547
21548 keys.clear();
21549 keys.push_back(key1); keys.push_back(key4); // sigs must match pubkeys
21550 CScript badsig5 = sign_multisig(scriptPubKey23, keys, txTo23);
21551 BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, txTo23, 0, 0));
21552
21553 keys.clear(); // Must have signatures
21554 CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23);
21555 BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, txTo23, 0, 0));
21556 }
21557
21558
21559 BOOST_AUTO_TEST_SUITE_END()
-
+ 4D8A50D4A2E7F073B219665C6022D68AB1A8AA4D9ADC991E253357F5A6BDFB6A091BE5EECCD376DC86491442A2F20D4598D721F3732C102D22918ABFFD27F30F
bitcoin/src/test/test_bitcoin.cpp
(0 . 0)(1 . 23)
21564 #define BOOST_TEST_MODULE Bitcoin Test Suite
21565 #include <boost/test/unit_test.hpp>
21566
21567 #include "../main.h"
21568 #include "../wallet.h"
21569
21570 #include "uint160_tests.cpp"
21571 #include "uint256_tests.cpp"
21572 #include "script_tests.cpp"
21573 #include "transaction_tests.cpp"
21574 #include "DoS_tests.cpp"
21575 #include "base64_tests.cpp"
21576 #include "util_tests.cpp"
21577 #include "base58_tests.cpp"
21578 #include "miner_tests.cpp"
21579 #include "Checkpoints_tests.cpp"
21580
21581 CWallet* pwalletMain;
21582
21583 void Shutdown(void* parg)
21584 {
21585 exit(0);
21586 }
-
+ 518FC23E03FD9F69F7999186A1C11FCB3624F6782E94184633A4E6ABBCC048281F92B18A71F23CB025D28059F90F377C747BC06DD4AB5DA77FA246966570E552
bitcoin/src/test/transaction_tests.cpp
(0 . 0)(1 . 25)
21591 #include <boost/test/unit_test.hpp>
21592
21593 #include "../main.h"
21594 #include "../wallet.h"
21595
21596 using namespace std;
21597
21598 BOOST_AUTO_TEST_SUITE(transaction_tests)
21599
21600 BOOST_AUTO_TEST_CASE(basic_transaction_tests)
21601 {
21602 // Random real transaction (e2769b09e784f32f62ef849763d4f45b98e07ba658647343b915ff832b110436)
21603 unsigned char ch[] = {0x01, 0x00, 0x00, 0x00, 0x01, 0x6b, 0xff, 0x7f, 0xcd, 0x4f, 0x85, 0x65, 0xef, 0x40, 0x6d, 0xd5, 0xd6, 0x3d, 0x4f, 0xf9, 0x4f, 0x31, 0x8f, 0xe8, 0x20, 0x27, 0xfd, 0x4d, 0xc4, 0x51, 0xb0, 0x44, 0x74, 0x01, 0x9f, 0x74, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x49, 0x30, 0x46, 0x02, 0x21, 0x00, 0xda, 0x0d, 0xc6, 0xae, 0xce, 0xfe, 0x1e, 0x06, 0xef, 0xdf, 0x05, 0x77, 0x37, 0x57, 0xde, 0xb1, 0x68, 0x82, 0x09, 0x30, 0xe3, 0xb0, 0xd0, 0x3f, 0x46, 0xf5, 0xfc, 0xf1, 0x50, 0xbf, 0x99, 0x0c, 0x02, 0x21, 0x00, 0xd2, 0x5b, 0x5c, 0x87, 0x04, 0x00, 0x76, 0xe4, 0xf2, 0x53, 0xf8, 0x26, 0x2e, 0x76, 0x3e, 0x2d, 0xd5, 0x1e, 0x7f, 0xf0, 0xbe, 0x15, 0x77, 0x27, 0xc4, 0xbc, 0x42, 0x80, 0x7f, 0x17, 0xbd, 0x39, 0x01, 0x41, 0x04, 0xe6, 0xc2, 0x6e, 0xf6, 0x7d, 0xc6, 0x10, 0xd2, 0xcd, 0x19, 0x24, 0x84, 0x78, 0x9a, 0x6c, 0xf9, 0xae, 0xa9, 0x93, 0x0b, 0x94, 0x4b, 0x7e, 0x2d, 0xb5, 0x34, 0x2b, 0x9d, 0x9e, 0x5b, 0x9f, 0xf7, 0x9a, 0xff, 0x9a, 0x2e, 0xe1, 0x97, 0x8d, 0xd7, 0xfd, 0x01, 0xdf, 0xc5, 0x22, 0xee, 0x02, 0x28, 0x3d, 0x3b, 0x06, 0xa9, 0xd0, 0x3a, 0xcf, 0x80, 0x96, 0x96, 0x8d, 0x7d, 0xbb, 0x0f, 0x91, 0x78, 0xff, 0xff, 0xff, 0xff, 0x02, 0x8b, 0xa7, 0x94, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x19, 0x76, 0xa9, 0x14, 0xba, 0xde, 0xec, 0xfd, 0xef, 0x05, 0x07, 0x24, 0x7f, 0xc8, 0xf7, 0x42, 0x41, 0xd7, 0x3b, 0xc0, 0x39, 0x97, 0x2d, 0x7b, 0x88, 0xac, 0x40, 0x94, 0xa8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x19, 0x76, 0xa9, 0x14, 0xc1, 0x09, 0x32, 0x48, 0x3f, 0xec, 0x93, 0xed, 0x51, 0xf5, 0xfe, 0x95, 0xe7, 0x25, 0x59, 0xf2, 0xcc, 0x70, 0x43, 0xf9, 0x88, 0xac, 0x00, 0x00, 0x00, 0x00, 0x00};
21604 vector<unsigned char> vch(ch, ch + sizeof(ch) -1);
21605 CDataStream stream(vch);
21606 CTransaction tx;
21607 stream >> tx;
21608 BOOST_CHECK_MESSAGE(tx.CheckTransaction(), "Simple deserialized transaction should be valid.");
21609
21610 // Check that duplicate txins fail
21611 tx.vin.push_back(tx.vin[0]);
21612 BOOST_CHECK_MESSAGE(!tx.CheckTransaction(), "Transaction with duplicate txins should be invalid.");
21613 }
21614
21615 BOOST_AUTO_TEST_SUITE_END()
-
+ C669BDFF752536F49C95ADFF8EF6DCB6102BA297C4C2D0EFB01AA454B9C212FFE0DDC013794AEC26FD60E1F01EC6DA3D4836525A3C57A7C71F3A6E981BD7BAC0
bitcoin/src/test/uint160_tests.cpp
(0 . 0)(1 . 18)
21620 #include <boost/test/unit_test.hpp>
21621
21622 #include "../uint256.h"
21623
21624 BOOST_AUTO_TEST_SUITE(uint160_tests)
21625
21626 BOOST_AUTO_TEST_CASE(uint160_equality)
21627 {
21628 uint160 num1 = 10;
21629 uint160 num2 = 11;
21630 BOOST_CHECK(num1+1 == num2);
21631
21632 uint64 num3 = 10;
21633 BOOST_CHECK(num1 == num3);
21634 BOOST_CHECK(num1+num2 == num3+num2);
21635 }
21636
21637 BOOST_AUTO_TEST_SUITE_END()
-
+ 62D6C2620B9399D55B907E767D8A0B4DBFED44E015127827CA1E1E776EBF9935633B00D124BD1E7EBEAD43239F3C7128593E4027C0A81F91A181D20E4AD77AEC
bitcoin/src/test/uint256_tests.cpp
(0 . 0)(1 . 18)
21642 #include <boost/test/unit_test.hpp>
21643
21644 #include "../uint256.h"
21645
21646 BOOST_AUTO_TEST_SUITE(uint256_tests)
21647
21648 BOOST_AUTO_TEST_CASE(uint256_equality)
21649 {
21650 uint256 num1 = 10;
21651 uint256 num2 = 11;
21652 BOOST_CHECK(num1+1 == num2);
21653
21654 uint64 num3 = 10;
21655 BOOST_CHECK(num1 == num3);
21656 BOOST_CHECK(num1+num2 == num3+num2);
21657 }
21658
21659 BOOST_AUTO_TEST_SUITE_END()
-
+ 0F95DE27B30D40D0DB4D730405C40EBCF0E8184F4DBECCAE0C0E893552DEA8145434639300EFF8C8C0759DF588BA111BB32096FAA73B8C2C521984819E1B202A
bitcoin/src/test/util_tests.cpp
(0 . 0)(1 . 233)
21664 #include <vector>
21665 #include <boost/test/unit_test.hpp>
21666 #include <boost/foreach.hpp>
21667
21668 #include "../util.h"
21669
21670 using namespace std;
21671
21672 BOOST_AUTO_TEST_SUITE(util_tests)
21673
21674 BOOST_AUTO_TEST_CASE(util_criticalsection)
21675 {
21676 CCriticalSection cs;
21677
21678 do {
21679 CRITICAL_BLOCK(cs)
21680 break;
21681
21682 BOOST_ERROR("break was swallowed!");
21683 } while(0);
21684
21685 do {
21686 TRY_CRITICAL_BLOCK(cs)
21687 break;
21688
21689 BOOST_ERROR("break was swallowed!");
21690 } while(0);
21691 }
21692
21693 BOOST_AUTO_TEST_CASE(util_MedianFilter)
21694 {
21695 CMedianFilter<int> filter(5, 15);
21696
21697 BOOST_CHECK_EQUAL(filter.median(), 15);
21698
21699 filter.input(20); // [15 20]
21700 BOOST_CHECK_EQUAL(filter.median(), 17);
21701
21702 filter.input(30); // [15 20 30]
21703 BOOST_CHECK_EQUAL(filter.median(), 20);
21704
21705 filter.input(3); // [3 15 20 30]
21706 BOOST_CHECK_EQUAL(filter.median(), 17);
21707
21708 filter.input(7); // [3 7 15 20 30]
21709 BOOST_CHECK_EQUAL(filter.median(), 15);
21710
21711 filter.input(18); // [3 7 18 20 30]
21712 BOOST_CHECK_EQUAL(filter.median(), 18);
21713
21714 filter.input(0); // [0 3 7 18 30]
21715 BOOST_CHECK_EQUAL(filter.median(), 7);
21716 }
21717
21718 static const unsigned char ParseHex_expected[65] = {
21719 0x04, 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, 0x48, 0x27, 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, 0xb7,
21720 0x10, 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, 0x09, 0xa6, 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, 0xde,
21721 0xb6, 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, 0x38, 0xc4, 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, 0x12,
21722 0xde, 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, 0x8d, 0x57, 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, 0x1d,
21723 0x5f
21724 };
21725 BOOST_AUTO_TEST_CASE(util_ParseHex)
21726 {
21727 std::vector<unsigned char> result;
21728 std::vector<unsigned char> expected(ParseHex_expected, ParseHex_expected + sizeof(ParseHex_expected));
21729 // Basic test vector
21730 result = ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f");
21731 BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
21732
21733 // Spaces between bytes must be supported
21734 result = ParseHex("12 34 56 78");
21735 BOOST_CHECK(result.size() == 4 && result[0] == 0x12 && result[1] == 0x34 && result[2] == 0x56 && result[3] == 0x78);
21736
21737 // Stop parsing at invalid value
21738 result = ParseHex("1234 invalid 1234");
21739 BOOST_CHECK(result.size() == 2 && result[0] == 0x12 && result[1] == 0x34);
21740 }
21741
21742 BOOST_AUTO_TEST_CASE(util_HexStr)
21743 {
21744 BOOST_CHECK_EQUAL(
21745 HexStr(ParseHex_expected, ParseHex_expected + sizeof(ParseHex_expected)),
21746 "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f");
21747
21748 BOOST_CHECK_EQUAL(
21749 HexStr(ParseHex_expected, ParseHex_expected + 5, true),
21750 "04 67 8a fd b0");
21751 }
21752
21753 BOOST_AUTO_TEST_CASE(util_DateTimeStrFormat)
21754 {
21755 BOOST_CHECK_EQUAL(DateTimeStrFormat("%x %H:%M:%S", 0), "01/01/70 00:00:00");
21756 BOOST_CHECK_EQUAL(DateTimeStrFormat("%x %H:%M:%S", 0x7FFFFFFF), "01/19/38 03:14:07");
21757 // Formats used within bitcoin
21758 BOOST_CHECK_EQUAL(DateTimeStrFormat("%x %H:%M:%S", 1317425777), "09/30/11 23:36:17");
21759 BOOST_CHECK_EQUAL(DateTimeStrFormat("%x %H:%M", 1317425777), "09/30/11 23:36");
21760 }
21761
21762 BOOST_AUTO_TEST_CASE(util_ParseParameters)
21763 {
21764 const char *argv_test[] = {"-ignored", "-a", "-b", "-ccc=argument", "-ccc=multiple", "f", "-d=e"};
21765
21766 ParseParameters(0, (char**)argv_test);
21767 BOOST_CHECK(mapArgs.empty() && mapMultiArgs.empty());
21768
21769 ParseParameters(1, (char**)argv_test);
21770 BOOST_CHECK(mapArgs.empty() && mapMultiArgs.empty());
21771
21772 ParseParameters(5, (char**)argv_test);
21773 // expectation: -ignored is ignored (program name argument),
21774 // -a, -b and -ccc end up in map, -d ignored because it is after
21775 // a non-option argument (non-GNU option parsing)
21776 BOOST_CHECK(mapArgs.size() == 3 && mapMultiArgs.size() == 3);
21777 BOOST_CHECK(mapArgs.count("-a") && mapArgs.count("-b") && mapArgs.count("-ccc")
21778 && !mapArgs.count("f") && !mapArgs.count("-d"));
21779 BOOST_CHECK(mapMultiArgs.count("-a") && mapMultiArgs.count("-b") && mapMultiArgs.count("-ccc")
21780 && !mapMultiArgs.count("f") && !mapMultiArgs.count("-d"));
21781
21782 BOOST_CHECK(mapArgs["-a"] == "" && mapArgs["-ccc"] == "multiple");
21783 BOOST_CHECK(mapMultiArgs["-ccc"].size() == 2);
21784 }
21785
21786 BOOST_AUTO_TEST_CASE(util_GetArg)
21787 {
21788 mapArgs.clear();
21789 mapArgs["strtest1"] = "string...";
21790 // strtest2 undefined on purpose
21791 mapArgs["inttest1"] = "12345";
21792 mapArgs["inttest2"] = "81985529216486895";
21793 // inttest3 undefined on purpose
21794 mapArgs["booltest1"] = "";
21795 // booltest2 undefined on purpose
21796 mapArgs["booltest3"] = "0";
21797 mapArgs["booltest4"] = "1";
21798
21799 BOOST_CHECK_EQUAL(GetArg("strtest1", "default"), "string...");
21800 BOOST_CHECK_EQUAL(GetArg("strtest2", "default"), "default");
21801 BOOST_CHECK_EQUAL(GetArg("inttest1", -1), 12345);
21802 BOOST_CHECK_EQUAL(GetArg("inttest2", -1), 81985529216486895LL);
21803 BOOST_CHECK_EQUAL(GetArg("inttest3", -1), -1);
21804 BOOST_CHECK_EQUAL(GetBoolArg("booltest1"), true);
21805 BOOST_CHECK_EQUAL(GetBoolArg("booltest2"), false);
21806 BOOST_CHECK_EQUAL(GetBoolArg("booltest3"), false);
21807 BOOST_CHECK_EQUAL(GetBoolArg("booltest4"), true);
21808 }
21809
21810 BOOST_AUTO_TEST_CASE(util_WildcardMatch)
21811 {
21812 BOOST_CHECK(WildcardMatch("127.0.0.1", "*"));
21813 BOOST_CHECK(WildcardMatch("127.0.0.1", "127.*"));
21814 BOOST_CHECK(WildcardMatch("abcdef", "a?cde?"));
21815 BOOST_CHECK(!WildcardMatch("abcdef", "a?cde??"));
21816 BOOST_CHECK(WildcardMatch("abcdef", "a*f"));
21817 BOOST_CHECK(!WildcardMatch("abcdef", "a*x"));
21818 BOOST_CHECK(WildcardMatch("", "*"));
21819 }
21820
21821 BOOST_AUTO_TEST_CASE(util_FormatMoney)
21822 {
21823 BOOST_CHECK_EQUAL(FormatMoney(0, false), "0.00");
21824 BOOST_CHECK_EQUAL(FormatMoney((COIN/10000)*123456789, false), "12345.6789");
21825 BOOST_CHECK_EQUAL(FormatMoney(COIN, true), "+1.00");
21826 BOOST_CHECK_EQUAL(FormatMoney(-COIN, false), "-1.00");
21827 BOOST_CHECK_EQUAL(FormatMoney(-COIN, true), "-1.00");
21828
21829 BOOST_CHECK_EQUAL(FormatMoney(COIN*100000000, false), "100000000.00");
21830 BOOST_CHECK_EQUAL(FormatMoney(COIN*10000000, false), "10000000.00");
21831 BOOST_CHECK_EQUAL(FormatMoney(COIN*1000000, false), "1000000.00");
21832 BOOST_CHECK_EQUAL(FormatMoney(COIN*100000, false), "100000.00");
21833 BOOST_CHECK_EQUAL(FormatMoney(COIN*10000, false), "10000.00");
21834 BOOST_CHECK_EQUAL(FormatMoney(COIN*1000, false), "1000.00");
21835 BOOST_CHECK_EQUAL(FormatMoney(COIN*100, false), "100.00");
21836 BOOST_CHECK_EQUAL(FormatMoney(COIN*10, false), "10.00");
21837 BOOST_CHECK_EQUAL(FormatMoney(COIN, false), "1.00");
21838 BOOST_CHECK_EQUAL(FormatMoney(COIN/10, false), "0.10");
21839 BOOST_CHECK_EQUAL(FormatMoney(COIN/100, false), "0.01");
21840 BOOST_CHECK_EQUAL(FormatMoney(COIN/1000, false), "0.001");
21841 BOOST_CHECK_EQUAL(FormatMoney(COIN/10000, false), "0.0001");
21842 BOOST_CHECK_EQUAL(FormatMoney(COIN/100000, false), "0.00001");
21843 BOOST_CHECK_EQUAL(FormatMoney(COIN/1000000, false), "0.000001");
21844 BOOST_CHECK_EQUAL(FormatMoney(COIN/10000000, false), "0.0000001");
21845 BOOST_CHECK_EQUAL(FormatMoney(COIN/100000000, false), "0.00000001");
21846 }
21847
21848 BOOST_AUTO_TEST_CASE(util_ParseMoney)
21849 {
21850 int64 ret = 0;
21851 BOOST_CHECK(ParseMoney("0.0", ret));
21852 BOOST_CHECK_EQUAL(ret, 0);
21853
21854 BOOST_CHECK(ParseMoney("12345.6789", ret));
21855 BOOST_CHECK_EQUAL(ret, (COIN/10000)*123456789);
21856
21857 BOOST_CHECK(ParseMoney("100000000.00", ret));
21858 BOOST_CHECK_EQUAL(ret, COIN*100000000);
21859 BOOST_CHECK(ParseMoney("10000000.00", ret));
21860 BOOST_CHECK_EQUAL(ret, COIN*10000000);
21861 BOOST_CHECK(ParseMoney("1000000.00", ret));
21862 BOOST_CHECK_EQUAL(ret, COIN*1000000);
21863 BOOST_CHECK(ParseMoney("100000.00", ret));
21864 BOOST_CHECK_EQUAL(ret, COIN*100000);
21865 BOOST_CHECK(ParseMoney("10000.00", ret));
21866 BOOST_CHECK_EQUAL(ret, COIN*10000);
21867 BOOST_CHECK(ParseMoney("1000.00", ret));
21868 BOOST_CHECK_EQUAL(ret, COIN*1000);
21869 BOOST_CHECK(ParseMoney("100.00", ret));
21870 BOOST_CHECK_EQUAL(ret, COIN*100);
21871 BOOST_CHECK(ParseMoney("10.00", ret));
21872 BOOST_CHECK_EQUAL(ret, COIN*10);
21873 BOOST_CHECK(ParseMoney("1.00", ret));
21874 BOOST_CHECK_EQUAL(ret, COIN);
21875 BOOST_CHECK(ParseMoney("0.1", ret));
21876 BOOST_CHECK_EQUAL(ret, COIN/10);
21877 BOOST_CHECK(ParseMoney("0.01", ret));
21878 BOOST_CHECK_EQUAL(ret, COIN/100);
21879 BOOST_CHECK(ParseMoney("0.001", ret));
21880 BOOST_CHECK_EQUAL(ret, COIN/1000);
21881 BOOST_CHECK(ParseMoney("0.0001", ret));
21882 BOOST_CHECK_EQUAL(ret, COIN/10000);
21883 BOOST_CHECK(ParseMoney("0.00001", ret));
21884 BOOST_CHECK_EQUAL(ret, COIN/100000);
21885 BOOST_CHECK(ParseMoney("0.000001", ret));
21886 BOOST_CHECK_EQUAL(ret, COIN/1000000);
21887 BOOST_CHECK(ParseMoney("0.0000001", ret));
21888 BOOST_CHECK_EQUAL(ret, COIN/10000000);
21889 BOOST_CHECK(ParseMoney("0.00000001", ret));
21890 BOOST_CHECK_EQUAL(ret, COIN/100000000);
21891
21892 // Attempted 63 bit overflow should fail
21893 BOOST_CHECK(!ParseMoney("92233720368.54775808", ret));
21894 }
21895
21896 BOOST_AUTO_TEST_SUITE_END()
-
+ 821F3AF7A2CE7BB860659E1B5833DA377C539C5E6207FFB48C042673DADA79B37002E6BD336E54C940CEE120BDB132B62966D30732E4AFEFDD46261EFF889BF8
bitcoin/src/uint256.h
(0 . 0)(1 . 759)
21901 // Copyright (c) 2009-2010 Satoshi Nakamoto
21902 // Copyright (c) 2011 The Bitcoin developers
21903 // Distributed under the MIT/X11 software license, see the accompanying
21904 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
21905 #ifndef BITCOIN_UINT256_H
21906 #define BITCOIN_UINT256_H
21907
21908 #include "serialize.h"
21909
21910 #include <limits.h>
21911 #include <string>
21912 #include <vector>
21913
21914 #if defined(_MSC_VER) || defined(__BORLANDC__)
21915 typedef __int64 int64;
21916 typedef unsigned __int64 uint64;
21917 #else
21918 typedef long long int64;
21919 typedef unsigned long long uint64;
21920 #endif
21921 #if defined(_MSC_VER) && _MSC_VER < 1300
21922 #define for if (false) ; else for
21923 #endif
21924
21925
21926 inline int Testuint256AdHoc(std::vector<std::string> vArg);
21927
21928
21929
21930 // We have to keep a separate base class without constructors
21931 // so the compiler will let us use it in a union
21932 template<unsigned int BITS>
21933 class base_uint
21934 {
21935 protected:
21936 enum { WIDTH=BITS/32 };
21937 unsigned int pn[WIDTH];
21938 public:
21939
21940 bool operator!() const
21941 {
21942 for (int i = 0; i < WIDTH; i++)
21943 if (pn[i] != 0)
21944 return false;
21945 return true;
21946 }
21947
21948 const base_uint operator~() const
21949 {
21950 base_uint ret;
21951 for (int i = 0; i < WIDTH; i++)
21952 ret.pn[i] = ~pn[i];
21953 return ret;
21954 }
21955
21956 const base_uint operator-() const
21957 {
21958 base_uint ret;
21959 for (int i = 0; i < WIDTH; i++)
21960 ret.pn[i] = ~pn[i];
21961 ret++;
21962 return ret;
21963 }
21964
21965
21966 base_uint& operator=(uint64 b)
21967 {
21968 pn[0] = (unsigned int)b;
21969 pn[1] = (unsigned int)(b >> 32);
21970 for (int i = 2; i < WIDTH; i++)
21971 pn[i] = 0;
21972 return *this;
21973 }
21974
21975 base_uint& operator^=(const base_uint& b)
21976 {
21977 for (int i = 0; i < WIDTH; i++)
21978 pn[i] ^= b.pn[i];
21979 return *this;
21980 }
21981
21982 base_uint& operator&=(const base_uint& b)
21983 {
21984 for (int i = 0; i < WIDTH; i++)
21985 pn[i] &= b.pn[i];
21986 return *this;
21987 }
21988
21989 base_uint& operator|=(const base_uint& b)
21990 {
21991 for (int i = 0; i < WIDTH; i++)
21992 pn[i] |= b.pn[i];
21993 return *this;
21994 }
21995
21996 base_uint& operator^=(uint64 b)
21997 {
21998 pn[0] ^= (unsigned int)b;
21999 pn[1] ^= (unsigned int)(b >> 32);
22000 return *this;
22001 }
22002
22003 base_uint& operator|=(uint64 b)
22004 {
22005 pn[0] |= (unsigned int)b;
22006 pn[1] |= (unsigned int)(b >> 32);
22007 return *this;
22008 }
22009
22010 base_uint& operator<<=(unsigned int shift)
22011 {
22012 base_uint a(*this);
22013 for (int i = 0; i < WIDTH; i++)
22014 pn[i] = 0;
22015 int k = shift / 32;
22016 shift = shift % 32;
22017 for (int i = 0; i < WIDTH; i++)
22018 {
22019 if (i+k+1 < WIDTH && shift != 0)
22020 pn[i+k+1] |= (a.pn[i] >> (32-shift));
22021 if (i+k < WIDTH)
22022 pn[i+k] |= (a.pn[i] << shift);
22023 }
22024 return *this;
22025 }
22026
22027 base_uint& operator>>=(unsigned int shift)
22028 {
22029 base_uint a(*this);
22030 for (int i = 0; i < WIDTH; i++)
22031 pn[i] = 0;
22032 int k = shift / 32;
22033 shift = shift % 32;
22034 for (int i = 0; i < WIDTH; i++)
22035 {
22036 if (i-k-1 >= 0 && shift != 0)
22037 pn[i-k-1] |= (a.pn[i] << (32-shift));
22038 if (i-k >= 0)
22039 pn[i-k] |= (a.pn[i] >> shift);
22040 }
22041 return *this;
22042 }
22043
22044 base_uint& operator+=(const base_uint& b)
22045 {
22046 uint64 carry = 0;
22047 for (int i = 0; i < WIDTH; i++)
22048 {
22049 uint64 n = carry + pn[i] + b.pn[i];
22050 pn[i] = n & 0xffffffff;
22051 carry = n >> 32;
22052 }
22053 return *this;
22054 }
22055
22056 base_uint& operator-=(const base_uint& b)
22057 {
22058 *this += -b;
22059 return *this;
22060 }
22061
22062 base_uint& operator+=(uint64 b64)
22063 {
22064 base_uint b;
22065 b = b64;
22066 *this += b;
22067 return *this;
22068 }
22069
22070 base_uint& operator-=(uint64 b64)
22071 {
22072 base_uint b;
22073 b = b64;
22074 *this += -b;
22075 return *this;
22076 }
22077
22078
22079 base_uint& operator++()
22080 {
22081 // prefix operator
22082 int i = 0;
22083 while (++pn[i] == 0 && i < WIDTH-1)
22084 i++;
22085 return *this;
22086 }
22087
22088 const base_uint operator++(int)
22089 {
22090 // postfix operator
22091 const base_uint ret = *this;
22092 ++(*this);
22093 return ret;
22094 }
22095
22096 base_uint& operator--()
22097 {
22098 // prefix operator
22099 int i = 0;
22100 while (--pn[i] == -1 && i < WIDTH-1)
22101 i++;
22102 return *this;
22103 }
22104
22105 const base_uint operator--(int)
22106 {
22107 // postfix operator
22108 const base_uint ret = *this;
22109 --(*this);
22110 return ret;
22111 }
22112
22113
22114 friend inline bool operator<(const base_uint& a, const base_uint& b)
22115 {
22116 for (int i = base_uint::WIDTH-1; i >= 0; i--)
22117 {
22118 if (a.pn[i] < b.pn[i])
22119 return true;
22120 else if (a.pn[i] > b.pn[i])
22121 return false;
22122 }
22123 return false;
22124 }
22125
22126 friend inline bool operator<=(const base_uint& a, const base_uint& b)
22127 {
22128 for (int i = base_uint::WIDTH-1; i >= 0; i--)
22129 {
22130 if (a.pn[i] < b.pn[i])
22131 return true;
22132 else if (a.pn[i] > b.pn[i])
22133 return false;
22134 }
22135 return true;
22136 }
22137
22138 friend inline bool operator>(const base_uint& a, const base_uint& b)
22139 {
22140 for (int i = base_uint::WIDTH-1; i >= 0; i--)
22141 {
22142 if (a.pn[i] > b.pn[i])
22143 return true;
22144 else if (a.pn[i] < b.pn[i])
22145 return false;
22146 }
22147 return false;
22148 }
22149
22150 friend inline bool operator>=(const base_uint& a, const base_uint& b)
22151 {
22152 for (int i = base_uint::WIDTH-1; i >= 0; i--)
22153 {
22154 if (a.pn[i] > b.pn[i])
22155 return true;
22156 else if (a.pn[i] < b.pn[i])
22157 return false;
22158 }
22159 return true;
22160 }
22161
22162 friend inline bool operator==(const base_uint& a, const base_uint& b)
22163 {
22164 for (int i = 0; i < base_uint::WIDTH; i++)
22165 if (a.pn[i] != b.pn[i])
22166 return false;
22167 return true;
22168 }
22169
22170 friend inline bool operator==(const base_uint& a, uint64 b)
22171 {
22172 if (a.pn[0] != (unsigned int)b)
22173 return false;
22174 if (a.pn[1] != (unsigned int)(b >> 32))
22175 return false;
22176 for (int i = 2; i < base_uint::WIDTH; i++)
22177 if (a.pn[i] != 0)
22178 return false;
22179 return true;
22180 }
22181
22182 friend inline bool operator!=(const base_uint& a, const base_uint& b)
22183 {
22184 return (!(a == b));
22185 }
22186
22187 friend inline bool operator!=(const base_uint& a, uint64 b)
22188 {
22189 return (!(a == b));
22190 }
22191
22192
22193
22194 std::string GetHex() const
22195 {
22196 char psz[sizeof(pn)*2 + 1];
22197 for (int i = 0; i < sizeof(pn); i++)
22198 sprintf(psz + i*2, "%02x", ((unsigned char*)pn)[sizeof(pn) - i - 1]);
22199 return std::string(psz, psz + sizeof(pn)*2);
22200 }
22201
22202 void SetHex(const char* psz)
22203 {
22204 for (int i = 0; i < WIDTH; i++)
22205 pn[i] = 0;
22206
22207 // skip leading spaces
22208 while (isspace(*psz))
22209 psz++;
22210
22211 // skip 0x
22212 if (psz[0] == '0' && tolower(psz[1]) == 'x')
22213 psz += 2;
22214
22215 // hex string to uint
22216 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 };
22217 const char* pbegin = psz;
22218 while (phexdigit[*psz] || *psz == '0')
22219 psz++;
22220 psz--;
22221 unsigned char* p1 = (unsigned char*)pn;
22222 unsigned char* pend = p1 + WIDTH * 4;
22223 while (psz >= pbegin && p1 < pend)
22224 {
22225 *p1 = phexdigit[(unsigned char)*psz--];
22226 if (psz >= pbegin)
22227 {
22228 *p1 |= (phexdigit[(unsigned char)*psz--] << 4);
22229 p1++;
22230 }
22231 }
22232 }
22233
22234 void SetHex(const std::string& str)
22235 {
22236 SetHex(str.c_str());
22237 }
22238
22239 std::string ToString() const
22240 {
22241 return (GetHex());
22242 }
22243
22244 unsigned char* begin()
22245 {
22246 return (unsigned char*)&pn[0];
22247 }
22248
22249 unsigned char* end()
22250 {
22251 return (unsigned char*)&pn[WIDTH];
22252 }
22253
22254 unsigned int size()
22255 {
22256 return sizeof(pn);
22257 }
22258
22259
22260 unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const
22261 {
22262 return sizeof(pn);
22263 }
22264
22265 template<typename Stream>
22266 void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const
22267 {
22268 s.write((char*)pn, sizeof(pn));
22269 }
22270
22271 template<typename Stream>
22272 void Unserialize(Stream& s, int nType=0, int nVersion=VERSION)
22273 {
22274 s.read((char*)pn, sizeof(pn));
22275 }
22276
22277
22278 friend class uint160;
22279 friend class uint256;
22280 friend inline int Testuint256AdHoc(std::vector<std::string> vArg);
22281 };
22282
22283 typedef base_uint<160> base_uint160;
22284 typedef base_uint<256> base_uint256;
22285
22286
22287
22288 //
22289 // uint160 and uint256 could be implemented as templates, but to keep
22290 // compile errors and debugging cleaner, they're copy and pasted.
22291 //
22292
22293
22294
22295 //////////////////////////////////////////////////////////////////////////////
22296 //
22297 // uint160
22298 //
22299
22300 class uint160 : public base_uint160
22301 {
22302 public:
22303 typedef base_uint160 basetype;
22304
22305 uint160()
22306 {
22307 for (int i = 0; i < WIDTH; i++)
22308 pn[i] = 0;
22309 }
22310
22311 uint160(const basetype& b)
22312 {
22313 for (int i = 0; i < WIDTH; i++)
22314 pn[i] = b.pn[i];
22315 }
22316
22317 uint160& operator=(const basetype& b)
22318 {
22319 for (int i = 0; i < WIDTH; i++)
22320 pn[i] = b.pn[i];
22321 return *this;
22322 }
22323
22324 uint160(uint64 b)
22325 {
22326 pn[0] = (unsigned int)b;
22327 pn[1] = (unsigned int)(b >> 32);
22328 for (int i = 2; i < WIDTH; i++)
22329 pn[i] = 0;
22330 }
22331
22332 uint160& operator=(uint64 b)
22333 {
22334 pn[0] = (unsigned int)b;
22335 pn[1] = (unsigned int)(b >> 32);
22336 for (int i = 2; i < WIDTH; i++)
22337 pn[i] = 0;
22338 return *this;
22339 }
22340
22341 explicit uint160(const std::string& str)
22342 {
22343 SetHex(str);
22344 }
22345
22346 explicit uint160(const std::vector<unsigned char>& vch)
22347 {
22348 if (vch.size() == sizeof(pn))
22349 memcpy(pn, &vch[0], sizeof(pn));
22350 else
22351 *this = 0;
22352 }
22353 };
22354
22355 inline bool operator==(const uint160& a, uint64 b) { return (base_uint160)a == b; }
22356 inline bool operator!=(const uint160& a, uint64 b) { return (base_uint160)a != b; }
22357 inline const uint160 operator<<(const base_uint160& a, unsigned int shift) { return uint160(a) <<= shift; }
22358 inline const uint160 operator>>(const base_uint160& a, unsigned int shift) { return uint160(a) >>= shift; }
22359 inline const uint160 operator<<(const uint160& a, unsigned int shift) { return uint160(a) <<= shift; }
22360 inline const uint160 operator>>(const uint160& a, unsigned int shift) { return uint160(a) >>= shift; }
22361
22362 inline const uint160 operator^(const base_uint160& a, const base_uint160& b) { return uint160(a) ^= b; }
22363 inline const uint160 operator&(const base_uint160& a, const base_uint160& b) { return uint160(a) &= b; }
22364 inline const uint160 operator|(const base_uint160& a, const base_uint160& b) { return uint160(a) |= b; }
22365 inline const uint160 operator+(const base_uint160& a, const base_uint160& b) { return uint160(a) += b; }
22366 inline const uint160 operator-(const base_uint160& a, const base_uint160& b) { return uint160(a) -= b; }
22367
22368 inline bool operator<(const base_uint160& a, const uint160& b) { return (base_uint160)a < (base_uint160)b; }
22369 inline bool operator<=(const base_uint160& a, const uint160& b) { return (base_uint160)a <= (base_uint160)b; }
22370 inline bool operator>(const base_uint160& a, const uint160& b) { return (base_uint160)a > (base_uint160)b; }
22371 inline bool operator>=(const base_uint160& a, const uint160& b) { return (base_uint160)a >= (base_uint160)b; }
22372 inline bool operator==(const base_uint160& a, const uint160& b) { return (base_uint160)a == (base_uint160)b; }
22373 inline bool operator!=(const base_uint160& a, const uint160& b) { return (base_uint160)a != (base_uint160)b; }
22374 inline const uint160 operator^(const base_uint160& a, const uint160& b) { return (base_uint160)a ^ (base_uint160)b; }
22375 inline const uint160 operator&(const base_uint160& a, const uint160& b) { return (base_uint160)a & (base_uint160)b; }
22376 inline const uint160 operator|(const base_uint160& a, const uint160& b) { return (base_uint160)a | (base_uint160)b; }
22377 inline const uint160 operator+(const base_uint160& a, const uint160& b) { return (base_uint160)a + (base_uint160)b; }
22378 inline const uint160 operator-(const base_uint160& a, const uint160& b) { return (base_uint160)a - (base_uint160)b; }
22379
22380 inline bool operator<(const uint160& a, const base_uint160& b) { return (base_uint160)a < (base_uint160)b; }
22381 inline bool operator<=(const uint160& a, const base_uint160& b) { return (base_uint160)a <= (base_uint160)b; }
22382 inline bool operator>(const uint160& a, const base_uint160& b) { return (base_uint160)a > (base_uint160)b; }
22383 inline bool operator>=(const uint160& a, const base_uint160& b) { return (base_uint160)a >= (base_uint160)b; }
22384 inline bool operator==(const uint160& a, const base_uint160& b) { return (base_uint160)a == (base_uint160)b; }
22385 inline bool operator!=(const uint160& a, const base_uint160& b) { return (base_uint160)a != (base_uint160)b; }
22386 inline const uint160 operator^(const uint160& a, const base_uint160& b) { return (base_uint160)a ^ (base_uint160)b; }
22387 inline const uint160 operator&(const uint160& a, const base_uint160& b) { return (base_uint160)a & (base_uint160)b; }
22388 inline const uint160 operator|(const uint160& a, const base_uint160& b) { return (base_uint160)a | (base_uint160)b; }
22389 inline const uint160 operator+(const uint160& a, const base_uint160& b) { return (base_uint160)a + (base_uint160)b; }
22390 inline const uint160 operator-(const uint160& a, const base_uint160& b) { return (base_uint160)a - (base_uint160)b; }
22391
22392 inline bool operator<(const uint160& a, const uint160& b) { return (base_uint160)a < (base_uint160)b; }
22393 inline bool operator<=(const uint160& a, const uint160& b) { return (base_uint160)a <= (base_uint160)b; }
22394 inline bool operator>(const uint160& a, const uint160& b) { return (base_uint160)a > (base_uint160)b; }
22395 inline bool operator>=(const uint160& a, const uint160& b) { return (base_uint160)a >= (base_uint160)b; }
22396 inline bool operator==(const uint160& a, const uint160& b) { return (base_uint160)a == (base_uint160)b; }
22397 inline bool operator!=(const uint160& a, const uint160& b) { return (base_uint160)a != (base_uint160)b; }
22398 inline const uint160 operator^(const uint160& a, const uint160& b) { return (base_uint160)a ^ (base_uint160)b; }
22399 inline const uint160 operator&(const uint160& a, const uint160& b) { return (base_uint160)a & (base_uint160)b; }
22400 inline const uint160 operator|(const uint160& a, const uint160& b) { return (base_uint160)a | (base_uint160)b; }
22401 inline const uint160 operator+(const uint160& a, const uint160& b) { return (base_uint160)a + (base_uint160)b; }
22402 inline const uint160 operator-(const uint160& a, const uint160& b) { return (base_uint160)a - (base_uint160)b; }
22403
22404
22405
22406
22407
22408
22409 //////////////////////////////////////////////////////////////////////////////
22410 //
22411 // uint256
22412 //
22413
22414 class uint256 : public base_uint256
22415 {
22416 public:
22417 typedef base_uint256 basetype;
22418
22419 uint256()
22420 {
22421 for (int i = 0; i < WIDTH; i++)
22422 pn[i] = 0;
22423 }
22424
22425 uint256(const basetype& b)
22426 {
22427 for (int i = 0; i < WIDTH; i++)
22428 pn[i] = b.pn[i];
22429 }
22430
22431 uint256& operator=(const basetype& b)
22432 {
22433 for (int i = 0; i < WIDTH; i++)
22434 pn[i] = b.pn[i];
22435 return *this;
22436 }
22437
22438 uint256(uint64 b)
22439 {
22440 pn[0] = (unsigned int)b;
22441 pn[1] = (unsigned int)(b >> 32);
22442 for (int i = 2; i < WIDTH; i++)
22443 pn[i] = 0;
22444 }
22445
22446 uint256& operator=(uint64 b)
22447 {
22448 pn[0] = (unsigned int)b;
22449 pn[1] = (unsigned int)(b >> 32);
22450 for (int i = 2; i < WIDTH; i++)
22451 pn[i] = 0;
22452 return *this;
22453 }
22454
22455 explicit uint256(const std::string& str)
22456 {
22457 SetHex(str);
22458 }
22459
22460 explicit uint256(const std::vector<unsigned char>& vch)
22461 {
22462 if (vch.size() == sizeof(pn))
22463 memcpy(pn, &vch[0], sizeof(pn));
22464 else
22465 *this = 0;
22466 }
22467 };
22468
22469 inline bool operator==(const uint256& a, uint64 b) { return (base_uint256)a == b; }
22470 inline bool operator!=(const uint256& a, uint64 b) { return (base_uint256)a != b; }
22471 inline const uint256 operator<<(const base_uint256& a, unsigned int shift) { return uint256(a) <<= shift; }
22472 inline const uint256 operator>>(const base_uint256& a, unsigned int shift) { return uint256(a) >>= shift; }
22473 inline const uint256 operator<<(const uint256& a, unsigned int shift) { return uint256(a) <<= shift; }
22474 inline const uint256 operator>>(const uint256& a, unsigned int shift) { return uint256(a) >>= shift; }
22475
22476 inline const uint256 operator^(const base_uint256& a, const base_uint256& b) { return uint256(a) ^= b; }
22477 inline const uint256 operator&(const base_uint256& a, const base_uint256& b) { return uint256(a) &= b; }
22478 inline const uint256 operator|(const base_uint256& a, const base_uint256& b) { return uint256(a) |= b; }
22479 inline const uint256 operator+(const base_uint256& a, const base_uint256& b) { return uint256(a) += b; }
22480 inline const uint256 operator-(const base_uint256& a, const base_uint256& b) { return uint256(a) -= b; }
22481
22482 inline bool operator<(const base_uint256& a, const uint256& b) { return (base_uint256)a < (base_uint256)b; }
22483 inline bool operator<=(const base_uint256& a, const uint256& b) { return (base_uint256)a <= (base_uint256)b; }
22484 inline bool operator>(const base_uint256& a, const uint256& b) { return (base_uint256)a > (base_uint256)b; }
22485 inline bool operator>=(const base_uint256& a, const uint256& b) { return (base_uint256)a >= (base_uint256)b; }
22486 inline bool operator==(const base_uint256& a, const uint256& b) { return (base_uint256)a == (base_uint256)b; }
22487 inline bool operator!=(const base_uint256& a, const uint256& b) { return (base_uint256)a != (base_uint256)b; }
22488 inline const uint256 operator^(const base_uint256& a, const uint256& b) { return (base_uint256)a ^ (base_uint256)b; }
22489 inline const uint256 operator&(const base_uint256& a, const uint256& b) { return (base_uint256)a & (base_uint256)b; }
22490 inline const uint256 operator|(const base_uint256& a, const uint256& b) { return (base_uint256)a | (base_uint256)b; }
22491 inline const uint256 operator+(const base_uint256& a, const uint256& b) { return (base_uint256)a + (base_uint256)b; }
22492 inline const uint256 operator-(const base_uint256& a, const uint256& b) { return (base_uint256)a - (base_uint256)b; }
22493
22494 inline bool operator<(const uint256& a, const base_uint256& b) { return (base_uint256)a < (base_uint256)b; }
22495 inline bool operator<=(const uint256& a, const base_uint256& b) { return (base_uint256)a <= (base_uint256)b; }
22496 inline bool operator>(const uint256& a, const base_uint256& b) { return (base_uint256)a > (base_uint256)b; }
22497 inline bool operator>=(const uint256& a, const base_uint256& b) { return (base_uint256)a >= (base_uint256)b; }
22498 inline bool operator==(const uint256& a, const base_uint256& b) { return (base_uint256)a == (base_uint256)b; }
22499 inline bool operator!=(const uint256& a, const base_uint256& b) { return (base_uint256)a != (base_uint256)b; }
22500 inline const uint256 operator^(const uint256& a, const base_uint256& b) { return (base_uint256)a ^ (base_uint256)b; }
22501 inline const uint256 operator&(const uint256& a, const base_uint256& b) { return (base_uint256)a & (base_uint256)b; }
22502 inline const uint256 operator|(const uint256& a, const base_uint256& b) { return (base_uint256)a | (base_uint256)b; }
22503 inline const uint256 operator+(const uint256& a, const base_uint256& b) { return (base_uint256)a + (base_uint256)b; }
22504 inline const uint256 operator-(const uint256& a, const base_uint256& b) { return (base_uint256)a - (base_uint256)b; }
22505
22506 inline bool operator<(const uint256& a, const uint256& b) { return (base_uint256)a < (base_uint256)b; }
22507 inline bool operator<=(const uint256& a, const uint256& b) { return (base_uint256)a <= (base_uint256)b; }
22508 inline bool operator>(const uint256& a, const uint256& b) { return (base_uint256)a > (base_uint256)b; }
22509 inline bool operator>=(const uint256& a, const uint256& b) { return (base_uint256)a >= (base_uint256)b; }
22510 inline bool operator==(const uint256& a, const uint256& b) { return (base_uint256)a == (base_uint256)b; }
22511 inline bool operator!=(const uint256& a, const uint256& b) { return (base_uint256)a != (base_uint256)b; }
22512 inline const uint256 operator^(const uint256& a, const uint256& b) { return (base_uint256)a ^ (base_uint256)b; }
22513 inline const uint256 operator&(const uint256& a, const uint256& b) { return (base_uint256)a & (base_uint256)b; }
22514 inline const uint256 operator|(const uint256& a, const uint256& b) { return (base_uint256)a | (base_uint256)b; }
22515 inline const uint256 operator+(const uint256& a, const uint256& b) { return (base_uint256)a + (base_uint256)b; }
22516 inline const uint256 operator-(const uint256& a, const uint256& b) { return (base_uint256)a - (base_uint256)b; }
22517
22518
22519
22520
22521
22522
22523
22524
22525
22526
22527
22528
22529 inline int Testuint256AdHoc(std::vector<std::string> vArg)
22530 {
22531 uint256 g(0);
22532
22533
22534 printf("%s\n", g.ToString().c_str());
22535 g--; printf("g--\n");
22536 printf("%s\n", g.ToString().c_str());
22537 g--; printf("g--\n");
22538 printf("%s\n", g.ToString().c_str());
22539 g++; printf("g++\n");
22540 printf("%s\n", g.ToString().c_str());
22541 g++; printf("g++\n");
22542 printf("%s\n", g.ToString().c_str());
22543 g++; printf("g++\n");
22544 printf("%s\n", g.ToString().c_str());
22545 g++; printf("g++\n");
22546 printf("%s\n", g.ToString().c_str());
22547
22548
22549
22550 uint256 a(7);
22551 printf("a=7\n");
22552 printf("%s\n", a.ToString().c_str());
22553
22554 uint256 b;
22555 printf("b undefined\n");
22556 printf("%s\n", b.ToString().c_str());
22557 int c = 3;
22558
22559 a = c;
22560 a.pn[3] = 15;
22561 printf("%s\n", a.ToString().c_str());
22562 uint256 k(c);
22563
22564 a = 5;
22565 a.pn[3] = 15;
22566 printf("%s\n", a.ToString().c_str());
22567 b = 1;
22568 b <<= 52;
22569
22570 a |= b;
22571
22572 a ^= 0x500;
22573
22574 printf("a %s\n", a.ToString().c_str());
22575
22576 a = a | b | (uint256)0x1000;
22577
22578
22579 printf("a %s\n", a.ToString().c_str());
22580 printf("b %s\n", b.ToString().c_str());
22581
22582 a = 0xfffffffe;
22583 a.pn[4] = 9;
22584
22585 printf("%s\n", a.ToString().c_str());
22586 a++;
22587 printf("%s\n", a.ToString().c_str());
22588 a++;
22589 printf("%s\n", a.ToString().c_str());
22590 a++;
22591 printf("%s\n", a.ToString().c_str());
22592 a++;
22593 printf("%s\n", a.ToString().c_str());
22594
22595 a--;
22596 printf("%s\n", a.ToString().c_str());
22597 a--;
22598 printf("%s\n", a.ToString().c_str());
22599 a--;
22600 printf("%s\n", a.ToString().c_str());
22601 uint256 d = a--;
22602 printf("%s\n", d.ToString().c_str());
22603 printf("%s\n", a.ToString().c_str());
22604 a--;
22605 printf("%s\n", a.ToString().c_str());
22606 a--;
22607 printf("%s\n", a.ToString().c_str());
22608
22609 d = a;
22610
22611 printf("%s\n", d.ToString().c_str());
22612 for (int i = uint256::WIDTH-1; i >= 0; i--) printf("%08x", d.pn[i]); printf("\n");
22613
22614 uint256 neg = d;
22615 neg = ~neg;
22616 printf("%s\n", neg.ToString().c_str());
22617
22618
22619 uint256 e = uint256("0xABCDEF123abcdef12345678909832180000011111111");
22620 printf("\n");
22621 printf("%s\n", e.ToString().c_str());
22622
22623
22624 printf("\n");
22625 uint256 x1 = uint256("0xABCDEF123abcdef12345678909832180000011111111");
22626 uint256 x2;
22627 printf("%s\n", x1.ToString().c_str());
22628 for (int i = 0; i < 270; i += 4)
22629 {
22630 x2 = x1 << i;
22631 printf("%s\n", x2.ToString().c_str());
22632 }
22633
22634 printf("\n");
22635 printf("%s\n", x1.ToString().c_str());
22636 for (int i = 0; i < 270; i += 4)
22637 {
22638 x2 = x1;
22639 x2 >>= i;
22640 printf("%s\n", x2.ToString().c_str());
22641 }
22642
22643
22644 for (int i = 0; i < 100; i++)
22645 {
22646 uint256 k = (~uint256(0) >> i);
22647 printf("%s\n", k.ToString().c_str());
22648 }
22649
22650 for (int i = 0; i < 100; i++)
22651 {
22652 uint256 k = (~uint256(0) << i);
22653 printf("%s\n", k.ToString().c_str());
22654 }
22655
22656 return (0);
22657 }
22658
22659 #endif
-
+ C7F92359243328F815311AD714EFD61CF038A265AAB7F69160CAF9ADD62F0A061807C1B9DA4474660C7BCB05800BA0E5265CF92E3934EADA359B7B70B42C8786
bitcoin/src/util.cpp
(0 . 0)(1 . 1177)
22664 // Copyright (c) 2009-2010 Satoshi Nakamoto
22665 // Copyright (c) 2009-2012 The Bitcoin developers
22666 // Distributed under the MIT/X11 software license, see the accompanying
22667 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
22668 #include "headers.h"
22669 #include "strlcpy.h"
22670 #include <boost/program_options/detail/config_file.hpp>
22671 #include <boost/program_options/parsers.hpp>
22672 #include <boost/filesystem.hpp>
22673 #include <boost/filesystem/fstream.hpp>
22674 #include <boost/interprocess/sync/interprocess_mutex.hpp>
22675 #include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
22676 #include <boost/foreach.hpp>
22677
22678 using namespace std;
22679 using namespace boost;
22680
22681 map<string, string> mapArgs;
22682 map<string, vector<string> > mapMultiArgs;
22683 bool fDebug = false;
22684 bool fPrintToConsole = false;
22685 bool fPrintToDebugger = false;
22686 char pszSetDataDir[MAX_PATH] = "";
22687 bool fRequestShutdown = false;
22688 bool fShutdown = false;
22689 bool fDaemon = false;
22690 bool fServer = false;
22691 bool fCommandLine = false;
22692 string strMiscWarning;
22693 bool fTestNet = false;
22694 bool fNoListen = false;
22695 bool fLogTimestamps = false;
22696
22697
22698
22699
22700 // Workaround for "multiple definition of `_tls_used'"
22701 // http://svn.boost.org/trac/boost/ticket/4258
22702 extern "C" void tss_cleanup_implemented() { }
22703
22704
22705
22706
22707
22708 // Init openssl library multithreading support
22709 static boost::interprocess::interprocess_mutex** ppmutexOpenSSL;
22710 void locking_callback(int mode, int i, const char* file, int line)
22711 {
22712 if (mode & CRYPTO_LOCK)
22713 ppmutexOpenSSL[i]->lock();
22714 else
22715 ppmutexOpenSSL[i]->unlock();
22716 }
22717
22718 // Init
22719 class CInit
22720 {
22721 public:
22722 CInit()
22723 {
22724 // Init openssl library multithreading support
22725 ppmutexOpenSSL = (boost::interprocess::interprocess_mutex**)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(boost::interprocess::interprocess_mutex*));
22726 for (int i = 0; i < CRYPTO_num_locks(); i++)
22727 ppmutexOpenSSL[i] = new boost::interprocess::interprocess_mutex();
22728 CRYPTO_set_locking_callback(locking_callback);
22729
22730 #ifdef WIN32
22731 // Seed random number generator with screen scrape and other hardware sources
22732 RAND_screen();
22733 #endif
22734
22735 // Seed random number generator with performance counter
22736 RandAddSeed();
22737 }
22738 ~CInit()
22739 {
22740 // Shutdown openssl library multithreading support
22741 CRYPTO_set_locking_callback(NULL);
22742 for (int i = 0; i < CRYPTO_num_locks(); i++)
22743 delete ppmutexOpenSSL[i];
22744 OPENSSL_free(ppmutexOpenSSL);
22745 }
22746 }
22747 instance_of_cinit;
22748
22749
22750
22751
22752
22753
22754
22755
22756 void RandAddSeed()
22757 {
22758 // Seed with CPU performance counter
22759 int64 nCounter = GetPerformanceCounter();
22760 RAND_add(&nCounter, sizeof(nCounter), 1.5);
22761 memset(&nCounter, 0, sizeof(nCounter));
22762 }
22763
22764 void RandAddSeedPerfmon()
22765 {
22766 RandAddSeed();
22767
22768 // This can take up to 2 seconds, so only do it every 10 minutes
22769 static int64 nLastPerfmon;
22770 if (GetTime() < nLastPerfmon + 10 * 60)
22771 return;
22772 nLastPerfmon = GetTime();
22773
22774 #ifdef WIN32
22775 // Don't need this on Linux, OpenSSL automatically uses /dev/urandom
22776 // Seed with the entire set of perfmon data
22777 unsigned char pdata[250000];
22778 memset(pdata, 0, sizeof(pdata));
22779 unsigned long nSize = sizeof(pdata);
22780 long ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize);
22781 RegCloseKey(HKEY_PERFORMANCE_DATA);
22782 if (ret == ERROR_SUCCESS)
22783 {
22784 RAND_add(pdata, nSize, nSize/100.0);
22785 memset(pdata, 0, nSize);
22786 printf("%s RandAddSeed() %d bytes\n", DateTimeStrFormat("%x %H:%M", GetTime()).c_str(), nSize);
22787 }
22788 #endif
22789 }
22790
22791 uint64 GetRand(uint64 nMax)
22792 {
22793 if (nMax == 0)
22794 return 0;
22795
22796 // The range of the random source must be a multiple of the modulus
22797 // to give every possible output value an equal possibility
22798 uint64 nRange = (UINT64_MAX / nMax) * nMax;
22799 uint64 nRand = 0;
22800 do
22801 RAND_bytes((unsigned char*)&nRand, sizeof(nRand));
22802 while (nRand >= nRange);
22803 return (nRand % nMax);
22804 }
22805
22806 int GetRandInt(int nMax)
22807 {
22808 return GetRand(nMax);
22809 }
22810
22811
22812
22813
22814
22815
22816
22817
22818
22819
22820
22821 inline int OutputDebugStringF(const char* pszFormat, ...)
22822 {
22823 int ret = 0;
22824 if (fPrintToConsole)
22825 {
22826 // print to console
22827 va_list arg_ptr;
22828 va_start(arg_ptr, pszFormat);
22829 ret = vprintf(pszFormat, arg_ptr);
22830 va_end(arg_ptr);
22831 }
22832 else
22833 {
22834 // print to debug.log
22835 static FILE* fileout = NULL;
22836
22837 if (!fileout)
22838 {
22839 char pszFile[MAX_PATH+100];
22840 GetDataDir(pszFile);
22841 strlcat(pszFile, "/debug.log", sizeof(pszFile));
22842 fileout = fopen(pszFile, "a");
22843 if (fileout) setbuf(fileout, NULL); // unbuffered
22844 }
22845 if (fileout)
22846 {
22847 static bool fStartedNewLine = true;
22848
22849 // Debug print useful for profiling
22850 if (fLogTimestamps && fStartedNewLine)
22851 fprintf(fileout, "%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
22852 if (pszFormat[strlen(pszFormat) - 1] == '\n')
22853 fStartedNewLine = true;
22854 else
22855 fStartedNewLine = false;
22856
22857 va_list arg_ptr;
22858 va_start(arg_ptr, pszFormat);
22859 ret = vfprintf(fileout, pszFormat, arg_ptr);
22860 va_end(arg_ptr);
22861 }
22862 }
22863
22864 #ifdef WIN32
22865 if (fPrintToDebugger)
22866 {
22867 static CCriticalSection cs_OutputDebugStringF;
22868
22869 // accumulate a line at a time
22870 CRITICAL_BLOCK(cs_OutputDebugStringF)
22871 {
22872 static char pszBuffer[50000];
22873 static char* pend;
22874 if (pend == NULL)
22875 pend = pszBuffer;
22876 va_list arg_ptr;
22877 va_start(arg_ptr, pszFormat);
22878 int limit = END(pszBuffer) - pend - 2;
22879 int ret = _vsnprintf(pend, limit, pszFormat, arg_ptr);
22880 va_end(arg_ptr);
22881 if (ret < 0 || ret >= limit)
22882 {
22883 pend = END(pszBuffer) - 2;
22884 *pend++ = '\n';
22885 }
22886 else
22887 pend += ret;
22888 *pend = '\0';
22889 char* p1 = pszBuffer;
22890 char* p2;
22891 while (p2 = strchr(p1, '\n'))
22892 {
22893 p2++;
22894 char c = *p2;
22895 *p2 = '\0';
22896 OutputDebugStringA(p1);
22897 *p2 = c;
22898 p1 = p2;
22899 }
22900 if (p1 != pszBuffer)
22901 memmove(pszBuffer, p1, pend - p1 + 1);
22902 pend -= (p1 - pszBuffer);
22903 }
22904 }
22905 #endif
22906 return ret;
22907 }
22908
22909
22910 // Safer snprintf
22911 // - prints up to limit-1 characters
22912 // - output string is always null terminated even if limit reached
22913 // - return value is the number of characters actually printed
22914 int my_snprintf(char* buffer, size_t limit, const char* format, ...)
22915 {
22916 if (limit == 0)
22917 return 0;
22918 va_list arg_ptr;
22919 va_start(arg_ptr, format);
22920 int ret = _vsnprintf(buffer, limit, format, arg_ptr);
22921 va_end(arg_ptr);
22922 if (ret < 0 || ret >= limit)
22923 {
22924 ret = limit - 1;
22925 buffer[limit-1] = 0;
22926 }
22927 return ret;
22928 }
22929
22930 string strprintf(const std::string &format, ...)
22931 {
22932 char buffer[50000];
22933 char* p = buffer;
22934 int limit = sizeof(buffer);
22935 int ret;
22936 loop
22937 {
22938 va_list arg_ptr;
22939 va_start(arg_ptr, format);
22940 ret = _vsnprintf(p, limit, format.c_str(), arg_ptr);
22941 va_end(arg_ptr);
22942 if (ret >= 0 && ret < limit)
22943 break;
22944 if (p != buffer)
22945 delete[] p;
22946 limit *= 2;
22947 p = new char[limit];
22948 if (p == NULL)
22949 throw std::bad_alloc();
22950 }
22951 string str(p, p+ret);
22952 if (p != buffer)
22953 delete[] p;
22954 return str;
22955 }
22956
22957 bool error(const std::string &format, ...)
22958 {
22959 char buffer[50000];
22960 int limit = sizeof(buffer);
22961 va_list arg_ptr;
22962 va_start(arg_ptr, format);
22963 int ret = _vsnprintf(buffer, limit, format.c_str(), arg_ptr);
22964 va_end(arg_ptr);
22965 if (ret < 0 || ret >= limit)
22966 {
22967 ret = limit - 1;
22968 buffer[limit-1] = 0;
22969 }
22970 printf("ERROR: %s\n", buffer);
22971 return false;
22972 }
22973
22974
22975 void ParseString(const string& str, char c, vector<string>& v)
22976 {
22977 if (str.empty())
22978 return;
22979 string::size_type i1 = 0;
22980 string::size_type i2;
22981 loop
22982 {
22983 i2 = str.find(c, i1);
22984 if (i2 == str.npos)
22985 {
22986 v.push_back(str.substr(i1));
22987 return;
22988 }
22989 v.push_back(str.substr(i1, i2-i1));
22990 i1 = i2+1;
22991 }
22992 }
22993
22994
22995 string FormatMoney(int64 n, bool fPlus)
22996 {
22997 // Note: not using straight sprintf here because we do NOT want
22998 // localized number formatting.
22999 int64 n_abs = (n > 0 ? n : -n);
23000 int64 quotient = n_abs/COIN;
23001 int64 remainder = n_abs%COIN;
23002 string str = strprintf("%"PRI64d".%08"PRI64d, quotient, remainder);
23003
23004 // Right-trim excess 0's before the decimal point:
23005 int nTrim = 0;
23006 for (int i = str.size()-1; (str[i] == '0' && isdigit(str[i-2])); --i)
23007 ++nTrim;
23008 if (nTrim)
23009 str.erase(str.size()-nTrim, nTrim);
23010
23011 if (n < 0)
23012 str.insert((unsigned int)0, 1, '-');
23013 else if (fPlus && n > 0)
23014 str.insert((unsigned int)0, 1, '+');
23015 return str;
23016 }
23017
23018
23019 bool ParseMoney(const string& str, int64& nRet)
23020 {
23021 return ParseMoney(str.c_str(), nRet);
23022 }
23023
23024 bool ParseMoney(const char* pszIn, int64& nRet)
23025 {
23026 string strWhole;
23027 int64 nUnits = 0;
23028 const char* p = pszIn;
23029 while (isspace(*p))
23030 p++;
23031 for (; *p; p++)
23032 {
23033 if (*p == '.')
23034 {
23035 p++;
23036 int64 nMult = CENT*10;
23037 while (isdigit(*p) && (nMult > 0))
23038 {
23039 nUnits += nMult * (*p++ - '0');
23040 nMult /= 10;
23041 }
23042 break;
23043 }
23044 if (isspace(*p))
23045 break;
23046 if (!isdigit(*p))
23047 return false;
23048 strWhole.insert(strWhole.end(), *p);
23049 }
23050 for (; *p; p++)
23051 if (!isspace(*p))
23052 return false;
23053 if (strWhole.size() > 10) // guard against 63 bit overflow
23054 return false;
23055 if (nUnits < 0 || nUnits > COIN)
23056 return false;
23057 int64 nWhole = atoi64(strWhole);
23058 int64 nValue = nWhole*COIN + nUnits;
23059
23060 nRet = nValue;
23061 return true;
23062 }
23063
23064
23065 vector<unsigned char> ParseHex(const char* psz)
23066 {
23067 static char phexdigit[256] =
23068 { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
23069 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
23070 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
23071 0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1,
23072 -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1,
23073 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
23074 -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1
23075 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
23076 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
23077 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
23078 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
23079 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
23080 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
23081 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
23082 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
23083 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, };
23084
23085 // convert hex dump to vector
23086 vector<unsigned char> vch;
23087 loop
23088 {
23089 while (isspace(*psz))
23090 psz++;
23091 char c = phexdigit[(unsigned char)*psz++];
23092 if (c == (char)-1)
23093 break;
23094 unsigned char n = (c << 4);
23095 c = phexdigit[(unsigned char)*psz++];
23096 if (c == (char)-1)
23097 break;
23098 n |= c;
23099 vch.push_back(n);
23100 }
23101 return vch;
23102 }
23103
23104 vector<unsigned char> ParseHex(const string& str)
23105 {
23106 return ParseHex(str.c_str());
23107 }
23108
23109 void ParseParameters(int argc, char* argv[])
23110 {
23111 mapArgs.clear();
23112 mapMultiArgs.clear();
23113 for (int i = 1; i < argc; i++)
23114 {
23115 char psz[10000];
23116 strlcpy(psz, argv[i], sizeof(psz));
23117 char* pszValue = (char*)"";
23118 if (strchr(psz, '='))
23119 {
23120 pszValue = strchr(psz, '=');
23121 *pszValue++ = '\0';
23122 }
23123 #ifdef WIN32
23124 _strlwr(psz);
23125 if (psz[0] == '/')
23126 psz[0] = '-';
23127 #endif
23128 if (psz[0] != '-')
23129 break;
23130 mapArgs[psz] = pszValue;
23131 mapMultiArgs[psz].push_back(pszValue);
23132 }
23133 }
23134
23135 bool SoftSetArg(const std::string& strArg, const std::string& strValue)
23136 {
23137 if (mapArgs.count(strArg))
23138 return false;
23139 mapArgs[strArg] = strValue;
23140 return true;
23141 }
23142
23143 bool SoftSetArg(const std::string& strArg, bool fValue)
23144 {
23145 if (fValue)
23146 return SoftSetArg(strArg, std::string("1"));
23147 else
23148 return SoftSetArg(strArg, std::string("0"));
23149 }
23150
23151
23152 string EncodeBase64(const unsigned char* pch, size_t len)
23153 {
23154 static const char *pbase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
23155
23156 string strRet="";
23157 strRet.reserve((len+2)/3*4);
23158
23159 int mode=0, left=0;
23160 const unsigned char *pchEnd = pch+len;
23161
23162 while (pch<pchEnd)
23163 {
23164 int enc = *(pch++);
23165 switch (mode)
23166 {
23167 case 0: // we have no bits
23168 strRet += pbase64[enc >> 2];
23169 left = (enc & 3) << 4;
23170 mode = 1;
23171 break;
23172
23173 case 1: // we have two bits
23174 strRet += pbase64[left | (enc >> 4)];
23175 left = (enc & 15) << 2;
23176 mode = 2;
23177 break;
23178
23179 case 2: // we have four bits
23180 strRet += pbase64[left | (enc >> 6)];
23181 strRet += pbase64[enc & 63];
23182 mode = 0;
23183 break;
23184 }
23185 }
23186
23187 if (mode)
23188 {
23189 strRet += pbase64[left];
23190 strRet += '=';
23191 if (mode == 1)
23192 strRet += '=';
23193 }
23194
23195 return strRet;
23196 }
23197
23198 string EncodeBase64(const string& str)
23199 {
23200 return EncodeBase64((const unsigned char*)str.c_str(), str.size());
23201 }
23202
23203 vector<unsigned char> DecodeBase64(const char* p, bool* pfInvalid)
23204 {
23205 static const int decode64_table[256] =
23206 {
23207 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
23208 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
23209 -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1,
23210 -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
23211 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28,
23212 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
23213 49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
23214 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
23215 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
23216 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
23217 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
23218 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
23219 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
23220 };
23221
23222 if (pfInvalid)
23223 *pfInvalid = false;
23224
23225 vector<unsigned char> vchRet;
23226 vchRet.reserve(strlen(p)*3/4);
23227
23228 int mode = 0;
23229 int left = 0;
23230
23231 while (1)
23232 {
23233 int dec = decode64_table[*p];
23234 if (dec == -1) break;
23235 p++;
23236 switch (mode)
23237 {
23238 case 0: // we have no bits and get 6
23239 left = dec;
23240 mode = 1;
23241 break;
23242
23243 case 1: // we have 6 bits and keep 4
23244 vchRet.push_back((left<<2) | (dec>>4));
23245 left = dec & 15;
23246 mode = 2;
23247 break;
23248
23249 case 2: // we have 4 bits and get 6, we keep 2
23250 vchRet.push_back((left<<4) | (dec>>2));
23251 left = dec & 3;
23252 mode = 3;
23253 break;
23254
23255 case 3: // we have 2 bits and get 6
23256 vchRet.push_back((left<<6) | dec);
23257 mode = 0;
23258 break;
23259 }
23260 }
23261
23262 if (pfInvalid)
23263 switch (mode)
23264 {
23265 case 0: // 4n base64 characters processed: ok
23266 break;
23267
23268 case 1: // 4n+1 base64 character processed: impossible
23269 *pfInvalid = true;
23270 break;
23271
23272 case 2: // 4n+2 base64 characters processed: require '=='
23273 if (left || p[0] != '=' || p[1] != '=' || decode64_table[p[2]] != -1)
23274 *pfInvalid = true;
23275 break;
23276
23277 case 3: // 4n+3 base64 characters processed: require '='
23278 if (left || p[0] != '=' || decode64_table[p[1]] != -1)
23279 *pfInvalid = true;
23280 break;
23281 }
23282
23283 return vchRet;
23284 }
23285
23286 string DecodeBase64(const string& str)
23287 {
23288 vector<unsigned char> vchRet = DecodeBase64(str.c_str());
23289 return string((const char*)&vchRet[0], vchRet.size());
23290 }
23291
23292
23293 bool WildcardMatch(const char* psz, const char* mask)
23294 {
23295 loop
23296 {
23297 switch (*mask)
23298 {
23299 case '\0':
23300 return (*psz == '\0');
23301 case '*':
23302 return WildcardMatch(psz, mask+1) || (*psz && WildcardMatch(psz+1, mask));
23303 case '?':
23304 if (*psz == '\0')
23305 return false;
23306 break;
23307 default:
23308 if (*psz != *mask)
23309 return false;
23310 break;
23311 }
23312 psz++;
23313 mask++;
23314 }
23315 }
23316
23317 bool WildcardMatch(const string& str, const string& mask)
23318 {
23319 return WildcardMatch(str.c_str(), mask.c_str());
23320 }
23321
23322
23323
23324
23325
23326
23327
23328
23329 void FormatException(char* pszMessage, std::exception* pex, const char* pszThread)
23330 {
23331 #ifdef WIN32
23332 char pszModule[MAX_PATH];
23333 pszModule[0] = '\0';
23334 GetModuleFileNameA(NULL, pszModule, sizeof(pszModule));
23335 #else
23336 const char* pszModule = "bitcoin";
23337 #endif
23338 if (pex)
23339 snprintf(pszMessage, 1000,
23340 "EXCEPTION: %s \n%s \n%s in %s \n", typeid(*pex).name(), pex->what(), pszModule, pszThread);
23341 else
23342 snprintf(pszMessage, 1000,
23343 "UNKNOWN EXCEPTION \n%s in %s \n", pszModule, pszThread);
23344 }
23345
23346 void LogException(std::exception* pex, const char* pszThread)
23347 {
23348 char pszMessage[10000];
23349 FormatException(pszMessage, pex, pszThread);
23350 printf("\n%s", pszMessage);
23351 }
23352
23353 void PrintException(std::exception* pex, const char* pszThread)
23354 {
23355 char pszMessage[10000];
23356 FormatException(pszMessage, pex, pszThread);
23357 printf("\n\n************************\n%s\n", pszMessage);
23358 fprintf(stderr, "\n\n************************\n%s\n", pszMessage);
23359 strMiscWarning = pszMessage;
23360 throw;
23361 }
23362
23363 void ThreadOneMessageBox(string strMessage)
23364 {
23365 // Skip message boxes if one is already open
23366 static bool fMessageBoxOpen;
23367 if (fMessageBoxOpen)
23368 return;
23369 fMessageBoxOpen = true;
23370 ThreadSafeMessageBox(strMessage, "Bitcoin", wxOK | wxICON_EXCLAMATION);
23371 fMessageBoxOpen = false;
23372 }
23373
23374 void PrintExceptionContinue(std::exception* pex, const char* pszThread)
23375 {
23376 char pszMessage[10000];
23377 FormatException(pszMessage, pex, pszThread);
23378 printf("\n\n************************\n%s\n", pszMessage);
23379 fprintf(stderr, "\n\n************************\n%s\n", pszMessage);
23380 strMiscWarning = pszMessage;
23381 }
23382
23383
23384
23385
23386
23387
23388
23389
23390 #ifdef WIN32
23391 typedef WINSHELLAPI BOOL (WINAPI *PSHGETSPECIALFOLDERPATHA)(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate);
23392
23393 string MyGetSpecialFolderPath(int nFolder, bool fCreate)
23394 {
23395 char pszPath[MAX_PATH+100] = "";
23396
23397 // SHGetSpecialFolderPath isn't always available on old Windows versions
23398 HMODULE hShell32 = LoadLibraryA("shell32.dll");
23399 if (hShell32)
23400 {
23401 PSHGETSPECIALFOLDERPATHA pSHGetSpecialFolderPath =
23402 (PSHGETSPECIALFOLDERPATHA)GetProcAddress(hShell32, "SHGetSpecialFolderPathA");
23403 bool fSuccess = false;
23404 if (pSHGetSpecialFolderPath)
23405 fSuccess =
23406 (*pSHGetSpecialFolderPath)(NULL, pszPath, nFolder, fCreate);
23407 FreeModule(hShell32);
23408 if (fSuccess)
23409 return pszPath;
23410 }
23411
23412 // Backup option
23413 std::string strPath;
23414 {
23415 const char *pszEnv;
23416 if (nFolder == CSIDL_STARTUP)
23417 {
23418 pszEnv = getenv("USERPROFILE");
23419 if (pszEnv)
23420 strPath = pszEnv;
23421 strPath += "\\Start Menu\\Programs\\Startup";
23422 }
23423 else if (nFolder == CSIDL_APPDATA)
23424 {
23425 pszEnv = getenv("APPDATA");
23426 if (pszEnv)
23427 strPath = pszEnv;
23428 }
23429 }
23430
23431 return strPath;
23432 }
23433 #endif
23434
23435 string GetDefaultDataDir()
23436 {
23437 // Windows: C:\Documents and Settings\username\Application Data\Bitcoin
23438 // Mac: ~/Library/Application Support/Bitcoin
23439 // Unix: ~/.bitcoin
23440 #ifdef WIN32
23441 // Windows
23442 return MyGetSpecialFolderPath(CSIDL_APPDATA, true) + "\\Bitcoin";
23443 #else
23444 char* pszHome = getenv("HOME");
23445 if (pszHome == NULL || strlen(pszHome) == 0)
23446 pszHome = (char*)"/";
23447 string strHome = pszHome;
23448 if (strHome[strHome.size()-1] != '/')
23449 strHome += '/';
23450 #ifdef MAC_OSX
23451 // Mac
23452 strHome += "Library/Application Support/";
23453 filesystem::create_directory(strHome.c_str());
23454 return strHome + "Bitcoin";
23455 #else
23456 // Unix
23457 return strHome + ".bitcoin";
23458 #endif
23459 #endif
23460 }
23461
23462 void GetDataDir(char* pszDir)
23463 {
23464 // pszDir must be at least MAX_PATH length.
23465 int nVariation;
23466 if (pszSetDataDir[0] != 0)
23467 {
23468 strlcpy(pszDir, pszSetDataDir, MAX_PATH);
23469 nVariation = 0;
23470 }
23471 else
23472 {
23473 // This can be called during exceptions by printf, so we cache the
23474 // value so we don't have to do memory allocations after that.
23475 static char pszCachedDir[MAX_PATH];
23476 if (pszCachedDir[0] == 0)
23477 strlcpy(pszCachedDir, GetDefaultDataDir().c_str(), sizeof(pszCachedDir));
23478 strlcpy(pszDir, pszCachedDir, MAX_PATH);
23479 nVariation = 1;
23480 }
23481 if (fTestNet)
23482 {
23483 char* p = pszDir + strlen(pszDir);
23484 if (p > pszDir && p[-1] != '/' && p[-1] != '\\')
23485 *p++ = '/';
23486 strcpy(p, "testnet");
23487 nVariation += 2;
23488 }
23489 static bool pfMkdir[4];
23490 if (!pfMkdir[nVariation])
23491 {
23492 pfMkdir[nVariation] = true;
23493 boost::filesystem::create_directory(pszDir);
23494 }
23495 }
23496
23497 string GetDataDir()
23498 {
23499 char pszDir[MAX_PATH];
23500 GetDataDir(pszDir);
23501 return pszDir;
23502 }
23503
23504 string GetConfigFile()
23505 {
23506 namespace fs = boost::filesystem;
23507 fs::path pathConfig(GetArg("-conf", "bitcoin.conf"));
23508 if (!pathConfig.is_complete())
23509 pathConfig = fs::path(GetDataDir()) / pathConfig;
23510 return pathConfig.string();
23511 }
23512
23513 void ReadConfigFile(map<string, string>& mapSettingsRet,
23514 map<string, vector<string> >& mapMultiSettingsRet)
23515 {
23516 namespace fs = boost::filesystem;
23517 namespace pod = boost::program_options::detail;
23518
23519 fs::ifstream streamConfig(GetConfigFile());
23520 if (!streamConfig.good())
23521 return;
23522
23523 set<string> setOptions;
23524 setOptions.insert("*");
23525
23526 for (pod::config_file_iterator it(streamConfig, setOptions), end; it != end; ++it)
23527 {
23528 // Don't overwrite existing settings so command line settings override bitcoin.conf
23529 string strKey = string("-") + it->string_key;
23530 if (mapSettingsRet.count(strKey) == 0)
23531 mapSettingsRet[strKey] = it->value[0];
23532 mapMultiSettingsRet[strKey].push_back(it->value[0]);
23533 }
23534 }
23535
23536 string GetPidFile()
23537 {
23538 namespace fs = boost::filesystem;
23539 fs::path pathConfig(GetArg("-pid", "bitcoind.pid"));
23540 if (!pathConfig.is_complete())
23541 pathConfig = fs::path(GetDataDir()) / pathConfig;
23542 return pathConfig.string();
23543 }
23544
23545 void CreatePidFile(string pidFile, pid_t pid)
23546 {
23547 FILE* file = fopen(pidFile.c_str(), "w");
23548 if (file)
23549 {
23550 fprintf(file, "%d\n", pid);
23551 fclose(file);
23552 }
23553 }
23554
23555 int GetFilesize(FILE* file)
23556 {
23557 int nSavePos = ftell(file);
23558 int nFilesize = -1;
23559 if (fseek(file, 0, SEEK_END) == 0)
23560 nFilesize = ftell(file);
23561 fseek(file, nSavePos, SEEK_SET);
23562 return nFilesize;
23563 }
23564
23565 void ShrinkDebugFile()
23566 {
23567 // Scroll debug.log if it's getting too big
23568 string strFile = GetDataDir() + "/debug.log";
23569 FILE* file = fopen(strFile.c_str(), "r");
23570 if (file && GetFilesize(file) > 10 * 1000000)
23571 {
23572 // Restart the file with some of the end
23573 char pch[200000];
23574 fseek(file, -sizeof(pch), SEEK_END);
23575 int nBytes = fread(pch, 1, sizeof(pch), file);
23576 fclose(file);
23577
23578 file = fopen(strFile.c_str(), "w");
23579 if (file)
23580 {
23581 fwrite(pch, 1, nBytes, file);
23582 fclose(file);
23583 }
23584 }
23585 }
23586
23587
23588
23589
23590
23591
23592
23593
23594 //
23595 // "Never go to sea with two chronometers; take one or three."
23596 // Our three time sources are:
23597 // - System clock
23598 // - Median of other nodes's clocks
23599 // - The user (asking the user to fix the system clock if the first two disagree)
23600 //
23601 static int64 nMockTime = 0; // For unit testing
23602
23603 int64 GetTime()
23604 {
23605 if (nMockTime) return nMockTime;
23606
23607 return time(NULL);
23608 }
23609
23610 void SetMockTime(int64 nMockTimeIn)
23611 {
23612 nMockTime = nMockTimeIn;
23613 }
23614
23615 static int64 nTimeOffset = 0;
23616
23617 int64 GetAdjustedTime()
23618 {
23619 return GetTime() + nTimeOffset;
23620 }
23621
23622 void AddTimeData(unsigned int ip, int64 nTime)
23623 {
23624 int64 nOffsetSample = nTime - GetTime();
23625
23626 // Ignore duplicates
23627 static set<unsigned int> setKnown;
23628 if (!setKnown.insert(ip).second)
23629 return;
23630
23631 // Add data
23632 static vector<int64> vTimeOffsets;
23633 if (vTimeOffsets.empty())
23634 vTimeOffsets.push_back(0);
23635 vTimeOffsets.push_back(nOffsetSample);
23636 printf("Added time data, samples %d, offset %+"PRI64d" (%+"PRI64d" minutes)\n", vTimeOffsets.size(), vTimeOffsets.back(), vTimeOffsets.back()/60);
23637 if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1)
23638 {
23639 sort(vTimeOffsets.begin(), vTimeOffsets.end());
23640 int64 nMedian = vTimeOffsets[vTimeOffsets.size()/2];
23641 // Only let other nodes change our time by so much
23642 if (abs64(nMedian) < 70 * 60)
23643 {
23644 nTimeOffset = nMedian;
23645 }
23646 else
23647 {
23648 nTimeOffset = 0;
23649
23650 static bool fDone;
23651 if (!fDone)
23652 {
23653 // If nobody has a time different than ours but within 5 minutes of ours, give a warning
23654 bool fMatch = false;
23655 BOOST_FOREACH(int64 nOffset, vTimeOffsets)
23656 if (nOffset != 0 && abs64(nOffset) < 5 * 60)
23657 fMatch = true;
23658
23659 if (!fMatch)
23660 {
23661 fDone = true;
23662 string strMessage = _("Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly.");
23663 strMiscWarning = strMessage;
23664 printf("*** %s\n", strMessage.c_str());
23665 boost::thread(boost::bind(ThreadSafeMessageBox, strMessage+" ", string("Bitcoin"), wxOK | wxICON_EXCLAMATION, (wxWindow*)NULL, -1, -1));
23666 }
23667 }
23668 }
23669 BOOST_FOREACH(int64 n, vTimeOffsets)
23670 printf("%+"PRI64d" ", n);
23671 printf("| nTimeOffset = %+"PRI64d" (%+"PRI64d" minutes)\n", nTimeOffset, nTimeOffset/60);
23672 }
23673 }
23674
23675
23676
23677
23678
23679
23680
23681
23682
23683 string FormatVersion(int nVersion)
23684 {
23685 if (nVersion%100 == 0)
23686 return strprintf("%d.%d.%d", nVersion/1000000, (nVersion/10000)%100, (nVersion/100)%100);
23687 else
23688 return strprintf("%d.%d.%d.%d", nVersion/1000000, (nVersion/10000)%100, (nVersion/100)%100, nVersion%100);
23689 }
23690
23691 string FormatFullVersion()
23692 {
23693 string s = FormatVersion(VERSION) + pszSubVer;
23694 if (VERSION_IS_BETA) {
23695 s += "-";
23696 s += _("beta");
23697 }
23698 return s;
23699 }
23700
23701
23702
23703
23704 #ifdef DEBUG_LOCKORDER
23705 //
23706 // Early deadlock detection.
23707 // Problem being solved:
23708 // Thread 1 locks A, then B, then C
23709 // Thread 2 locks D, then C, then A
23710 // --> may result in deadlock between the two threads, depending on when they run.
23711 // Solution implemented here:
23712 // Keep track of pairs of locks: (A before B), (A before C), etc.
23713 // Complain if any thread trys to lock in a different order.
23714 //
23715
23716 struct CLockLocation
23717 {
23718 CLockLocation(const char* pszName, const char* pszFile, int nLine)
23719 {
23720 mutexName = pszName;
23721 sourceFile = pszFile;
23722 sourceLine = nLine;
23723 }
23724
23725 std::string ToString() const
23726 {
23727 return mutexName+" "+sourceFile+":"+itostr(sourceLine);
23728 }
23729
23730 private:
23731 std::string mutexName;
23732 std::string sourceFile;
23733 int sourceLine;
23734 };
23735
23736 typedef std::vector< std::pair<CCriticalSection*, CLockLocation> > LockStack;
23737
23738 static boost::interprocess::interprocess_mutex dd_mutex;
23739 static std::map<std::pair<CCriticalSection*, CCriticalSection*>, LockStack> lockorders;
23740 static boost::thread_specific_ptr<LockStack> lockstack;
23741
23742
23743 static void potential_deadlock_detected(const std::pair<CCriticalSection*, CCriticalSection*>& mismatch, const LockStack& s1, const LockStack& s2)
23744 {
23745 printf("POTENTIAL DEADLOCK DETECTED\n");
23746 printf("Previous lock order was:\n");
23747 BOOST_FOREACH(const PAIRTYPE(CCriticalSection*, CLockLocation)& i, s2)
23748 {
23749 if (i.first == mismatch.first) printf(" (1)");
23750 if (i.first == mismatch.second) printf(" (2)");
23751 printf(" %s\n", i.second.ToString().c_str());
23752 }
23753 printf("Current lock order is:\n");
23754 BOOST_FOREACH(const PAIRTYPE(CCriticalSection*, CLockLocation)& i, s1)
23755 {
23756 if (i.first == mismatch.first) printf(" (1)");
23757 if (i.first == mismatch.second) printf(" (2)");
23758 printf(" %s\n", i.second.ToString().c_str());
23759 }
23760 }
23761
23762 static void push_lock(CCriticalSection* c, const CLockLocation& locklocation)
23763 {
23764 bool fOrderOK = true;
23765 if (lockstack.get() == NULL)
23766 lockstack.reset(new LockStack);
23767
23768 if (fDebug) printf("Locking: %s\n", locklocation.ToString().c_str());
23769 dd_mutex.lock();
23770
23771 (*lockstack).push_back(std::make_pair(c, locklocation));
23772
23773 BOOST_FOREACH(const PAIRTYPE(CCriticalSection*, CLockLocation)& i, (*lockstack))
23774 {
23775 if (i.first == c) break;
23776
23777 std::pair<CCriticalSection*, CCriticalSection*> p1 = std::make_pair(i.first, c);
23778 if (lockorders.count(p1))
23779 continue;
23780 lockorders[p1] = (*lockstack);
23781
23782 std::pair<CCriticalSection*, CCriticalSection*> p2 = std::make_pair(c, i.first);
23783 if (lockorders.count(p2))
23784 {
23785 potential_deadlock_detected(p1, lockorders[p2], lockorders[p1]);
23786 break;
23787 }
23788 }
23789 dd_mutex.unlock();
23790 }
23791
23792 static void pop_lock()
23793 {
23794 if (fDebug)
23795 {
23796 const CLockLocation& locklocation = (*lockstack).rbegin()->second;
23797 printf("Unlocked: %s\n", locklocation.ToString().c_str());
23798 }
23799 dd_mutex.lock();
23800 (*lockstack).pop_back();
23801 dd_mutex.unlock();
23802 }
23803
23804 void CCriticalSection::Enter(const char* pszName, const char* pszFile, int nLine)
23805 {
23806 push_lock(this, CLockLocation(pszName, pszFile, nLine));
23807 mutex.lock();
23808 }
23809 void CCriticalSection::Leave()
23810 {
23811 mutex.unlock();
23812 pop_lock();
23813 }
23814 bool CCriticalSection::TryEnter(const char* pszName, const char* pszFile, int nLine)
23815 {
23816 push_lock(this, CLockLocation(pszName, pszFile, nLine));
23817 bool result = mutex.try_lock();
23818 if (!result) pop_lock();
23819 return result;
23820 }
23821
23822 #else
23823
23824 void CCriticalSection::Enter(const char*, const char*, int)
23825 {
23826 mutex.lock();
23827 }
23828
23829 void CCriticalSection::Leave()
23830 {
23831 mutex.unlock();
23832 }
23833
23834 bool CCriticalSection::TryEnter(const char*, const char*, int)
23835 {
23836 bool result = mutex.try_lock();
23837 return result;
23838 }
23839
23840 #endif /* DEBUG_LOCKORDER */
-
+ 75BC498BF713D76D2E9A489C71604DBB77792673C7F87343D4C6FCF5F20FAC57CDFFD5F15513B00F21F9DE257ADBEB3CA581147F41A8BE96D69379269021C723
bitcoin/src/util.h
(0 . 0)(1 . 774)
23845 // Copyright (c) 2009-2010 Satoshi Nakamoto
23846 // Copyright (c) 2009-2012 The Bitcoin developers
23847 // Distributed under the MIT/X11 software license, see the accompanying
23848 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
23849 #ifndef BITCOIN_UTIL_H
23850 #define BITCOIN_UTIL_H
23851
23852 #include "uint256.h"
23853
23854 #ifndef WIN32
23855 #include <sys/types.h>
23856 #include <sys/time.h>
23857 #include <sys/resource.h>
23858 #endif
23859 #include <map>
23860 #include <vector>
23861 #include <string>
23862
23863 #include <boost/thread.hpp>
23864 #include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
23865 #include <boost/date_time/gregorian/gregorian_types.hpp>
23866 #include <boost/date_time/posix_time/posix_time_types.hpp>
23867
23868 #include <openssl/sha.h>
23869 #include <openssl/ripemd.h>
23870
23871
23872 #if defined(_MSC_VER) || defined(__BORLANDC__)
23873 typedef __int64 int64;
23874 typedef unsigned __int64 uint64;
23875 #else
23876 typedef long long int64;
23877 typedef unsigned long long uint64;
23878 #endif
23879 #if defined(_MSC_VER) && _MSC_VER < 1300
23880 #define for if (false) ; else for
23881 #endif
23882 #ifndef _MSC_VER
23883 #define __forceinline inline
23884 #endif
23885
23886 #define loop for (;;)
23887 #define BEGIN(a) ((char*)&(a))
23888 #define END(a) ((char*)&((&(a))[1]))
23889 #define UBEGIN(a) ((unsigned char*)&(a))
23890 #define UEND(a) ((unsigned char*)&((&(a))[1]))
23891 #define ARRAYLEN(array) (sizeof(array)/sizeof((array)[0]))
23892 #define printf OutputDebugStringF
23893
23894 #ifdef snprintf
23895 #undef snprintf
23896 #endif
23897 #define snprintf my_snprintf
23898
23899 #ifndef PRI64d
23900 #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MSVCRT__)
23901 #define PRI64d "I64d"
23902 #define PRI64u "I64u"
23903 #define PRI64x "I64x"
23904 #else
23905 #define PRI64d "lld"
23906 #define PRI64u "llu"
23907 #define PRI64x "llx"
23908 #endif
23909 #endif
23910
23911 // This is needed because the foreach macro can't get over the comma in pair<t1, t2>
23912 #define PAIRTYPE(t1, t2) std::pair<t1, t2>
23913
23914 // Align by increasing pointer, must have extra space at end of buffer
23915 template <size_t nBytes, typename T>
23916 T* alignup(T* p)
23917 {
23918 union
23919 {
23920 T* ptr;
23921 size_t n;
23922 } u;
23923 u.ptr = p;
23924 u.n = (u.n + (nBytes-1)) & ~(nBytes-1);
23925 return u.ptr;
23926 }
23927
23928 #ifdef WIN32
23929 #define MSG_NOSIGNAL 0
23930 #define MSG_DONTWAIT 0
23931 #ifndef UINT64_MAX
23932 #define UINT64_MAX _UI64_MAX
23933 #define INT64_MAX _I64_MAX
23934 #define INT64_MIN _I64_MIN
23935 #endif
23936 #ifndef S_IRUSR
23937 #define S_IRUSR 0400
23938 #define S_IWUSR 0200
23939 #endif
23940 #define unlink _unlink
23941 typedef int socklen_t;
23942 #else
23943 #define WSAGetLastError() errno
23944 #define WSAEINVAL EINVAL
23945 #define WSAEALREADY EALREADY
23946 #define WSAEWOULDBLOCK EWOULDBLOCK
23947 #define WSAEMSGSIZE EMSGSIZE
23948 #define WSAEINTR EINTR
23949 #define WSAEINPROGRESS EINPROGRESS
23950 #define WSAEADDRINUSE EADDRINUSE
23951 #define WSAENOTSOCK EBADF
23952 #define INVALID_SOCKET (SOCKET)(~0)
23953 #define SOCKET_ERROR -1
23954 typedef u_int SOCKET;
23955 #define _vsnprintf(a,b,c,d) vsnprintf(a,b,c,d)
23956 #define strlwr(psz) to_lower(psz)
23957 #define _strlwr(psz) to_lower(psz)
23958 #define MAX_PATH 1024
23959 #define Beep(n1,n2) (0)
23960 inline void Sleep(int64 n)
23961 {
23962 /*Boost has a year 2038 problem- if the request sleep time is past epoch+2^31 seconds the sleep returns instantly.
23963 So we clamp our sleeps here to 10 years and hope that boost is fixed by 2028.*/
23964 boost::thread::sleep(boost::get_system_time() + boost::posix_time::milliseconds(n>315576000000LL?315576000000LL:n));
23965 }
23966 #endif
23967
23968 inline int myclosesocket(SOCKET& hSocket)
23969 {
23970 if (hSocket == INVALID_SOCKET)
23971 return WSAENOTSOCK;
23972 #ifdef WIN32
23973 int ret = closesocket(hSocket);
23974 #else
23975 int ret = close(hSocket);
23976 #endif
23977 hSocket = INVALID_SOCKET;
23978 return ret;
23979 }
23980 #define closesocket(s) myclosesocket(s)
23981 #if !defined(QT_GUI)
23982 inline const char* _(const char* psz)
23983 {
23984 return psz;
23985 }
23986 #endif
23987
23988
23989
23990
23991
23992
23993
23994
23995
23996 extern std::map<std::string, std::string> mapArgs;
23997 extern std::map<std::string, std::vector<std::string> > mapMultiArgs;
23998 extern bool fDebug;
23999 extern bool fPrintToConsole;
24000 extern bool fPrintToDebugger;
24001 extern char pszSetDataDir[MAX_PATH];
24002 extern bool fRequestShutdown;
24003 extern bool fShutdown;
24004 extern bool fDaemon;
24005 extern bool fServer;
24006 extern bool fCommandLine;
24007 extern std::string strMiscWarning;
24008 extern bool fTestNet;
24009 extern bool fNoListen;
24010 extern bool fLogTimestamps;
24011
24012 void RandAddSeed();
24013 void RandAddSeedPerfmon();
24014 int OutputDebugStringF(const char* pszFormat, ...);
24015 int my_snprintf(char* buffer, size_t limit, const char* format, ...);
24016 std::string strprintf(const std::string &format, ...);
24017 bool error(const std::string &format, ...);
24018 void LogException(std::exception* pex, const char* pszThread);
24019 void PrintException(std::exception* pex, const char* pszThread);
24020 void PrintExceptionContinue(std::exception* pex, const char* pszThread);
24021 void ParseString(const std::string& str, char c, std::vector<std::string>& v);
24022 std::string FormatMoney(int64 n, bool fPlus=false);
24023 bool ParseMoney(const std::string& str, int64& nRet);
24024 bool ParseMoney(const char* pszIn, int64& nRet);
24025 std::vector<unsigned char> ParseHex(const char* psz);
24026 std::vector<unsigned char> ParseHex(const std::string& str);
24027 std::vector<unsigned char> DecodeBase64(const char* p, bool* pfInvalid = NULL);
24028 std::string DecodeBase64(const std::string& str);
24029 std::string EncodeBase64(const unsigned char* pch, size_t len);
24030 std::string EncodeBase64(const std::string& str);
24031 void ParseParameters(int argc, char* argv[]);
24032 const char* wxGetTranslation(const char* psz);
24033 bool WildcardMatch(const char* psz, const char* mask);
24034 bool WildcardMatch(const std::string& str, const std::string& mask);
24035 int GetFilesize(FILE* file);
24036 void GetDataDir(char* pszDirRet);
24037 std::string GetConfigFile();
24038 std::string GetPidFile();
24039 void CreatePidFile(std::string pidFile, pid_t pid);
24040 void ReadConfigFile(std::map<std::string, std::string>& mapSettingsRet, std::map<std::string, std::vector<std::string> >& mapMultiSettingsRet);
24041 #ifdef WIN32
24042 std::string MyGetSpecialFolderPath(int nFolder, bool fCreate);
24043 #endif
24044 std::string GetDefaultDataDir();
24045 std::string GetDataDir();
24046 void ShrinkDebugFile();
24047 int GetRandInt(int nMax);
24048 uint64 GetRand(uint64 nMax);
24049 int64 GetTime();
24050 void SetMockTime(int64 nMockTimeIn);
24051 int64 GetAdjustedTime();
24052 void AddTimeData(unsigned int ip, int64 nTime);
24053 std::string FormatFullVersion();
24054
24055
24056
24057
24058
24059
24060
24061
24062
24063
24064
24065
24066
24067 // Wrapper to automatically initialize mutex
24068 class CCriticalSection
24069 {
24070 protected:
24071 boost::interprocess::interprocess_recursive_mutex mutex;
24072 public:
24073 explicit CCriticalSection() { }
24074 ~CCriticalSection() { }
24075 void Enter(const char* pszName, const char* pszFile, int nLine);
24076 void Leave();
24077 bool TryEnter(const char* pszName, const char* pszFile, int nLine);
24078 };
24079
24080 // Automatically leave critical section when leaving block, needed for exception safety
24081 class CCriticalBlock
24082 {
24083 protected:
24084 CCriticalSection* pcs;
24085
24086 public:
24087 CCriticalBlock(CCriticalSection& csIn, const char* pszName, const char* pszFile, int nLine)
24088 {
24089 pcs = &csIn;
24090 pcs->Enter(pszName, pszFile, nLine);
24091 }
24092
24093 operator bool() const
24094 {
24095 return true;
24096 }
24097
24098 ~CCriticalBlock()
24099 {
24100 pcs->Leave();
24101 }
24102 };
24103
24104 #define CRITICAL_BLOCK(cs) \
24105 if (CCriticalBlock criticalblock = CCriticalBlock(cs, #cs, __FILE__, __LINE__))
24106
24107 #define ENTER_CRITICAL_SECTION(cs) \
24108 (cs).Enter(#cs, __FILE__, __LINE__)
24109
24110 #define LEAVE_CRITICAL_SECTION(cs) \
24111 (cs).Leave()
24112
24113 class CTryCriticalBlock
24114 {
24115 protected:
24116 CCriticalSection* pcs;
24117
24118 public:
24119 CTryCriticalBlock(CCriticalSection& csIn, const char* pszName, const char* pszFile, int nLine)
24120 {
24121 pcs = (csIn.TryEnter(pszName, pszFile, nLine) ? &csIn : NULL);
24122 }
24123
24124 operator bool() const
24125 {
24126 return Entered();
24127 }
24128
24129 ~CTryCriticalBlock()
24130 {
24131 if (pcs)
24132 {
24133 pcs->Leave();
24134 }
24135 }
24136 bool Entered() const { return pcs != NULL; }
24137 };
24138
24139 #define TRY_CRITICAL_BLOCK(cs) \
24140 if (CTryCriticalBlock criticalblock = CTryCriticalBlock(cs, #cs, __FILE__, __LINE__))
24141
24142
24143
24144
24145
24146
24147 // This is exactly like std::string, but with a custom allocator.
24148 // (secure_allocator<> is defined in serialize.h)
24149 typedef std::basic_string<char, std::char_traits<char>, secure_allocator<char> > SecureString;
24150
24151 // This is exactly like std::string, but with a custom allocator.
24152 // (secure_allocator<> is defined in serialize.h)
24153 typedef std::basic_string<char, std::char_traits<char>, secure_allocator<char> > SecureString;
24154
24155
24156
24157
24158
24159 inline std::string i64tostr(int64 n)
24160 {
24161 return strprintf("%"PRI64d, n);
24162 }
24163
24164 inline std::string itostr(int n)
24165 {
24166 return strprintf("%d", n);
24167 }
24168
24169 inline int64 atoi64(const char* psz)
24170 {
24171 #ifdef _MSC_VER
24172 return _atoi64(psz);
24173 #else
24174 return strtoll(psz, NULL, 10);
24175 #endif
24176 }
24177
24178 inline int64 atoi64(const std::string& str)
24179 {
24180 #ifdef _MSC_VER
24181 return _atoi64(str.c_str());
24182 #else
24183 return strtoll(str.c_str(), NULL, 10);
24184 #endif
24185 }
24186
24187 inline int atoi(const std::string& str)
24188 {
24189 return atoi(str.c_str());
24190 }
24191
24192 inline int roundint(double d)
24193 {
24194 return (int)(d > 0 ? d + 0.5 : d - 0.5);
24195 }
24196
24197 inline int64 roundint64(double d)
24198 {
24199 return (int64)(d > 0 ? d + 0.5 : d - 0.5);
24200 }
24201
24202 inline int64 abs64(int64 n)
24203 {
24204 return (n >= 0 ? n : -n);
24205 }
24206
24207 template<typename T>
24208 std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
24209 {
24210 if (itbegin == itend)
24211 return "";
24212 const unsigned char* pbegin = (const unsigned char*)&itbegin[0];
24213 const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]);
24214 std::string str;
24215 str.reserve((pend-pbegin) * (fSpaces ? 3 : 2));
24216 for (const unsigned char* p = pbegin; p != pend; p++)
24217 str += strprintf((fSpaces && p != pend-1 ? "%02x " : "%02x"), *p);
24218 return str;
24219 }
24220
24221 inline std::string HexStr(const std::vector<unsigned char>& vch, bool fSpaces=false)
24222 {
24223 return HexStr(vch.begin(), vch.end(), fSpaces);
24224 }
24225
24226 template<typename T>
24227 std::string HexNumStr(const T itbegin, const T itend, bool f0x=true)
24228 {
24229 if (itbegin == itend)
24230 return "";
24231 const unsigned char* pbegin = (const unsigned char*)&itbegin[0];
24232 const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]);
24233 std::string str = (f0x ? "0x" : "");
24234 str.reserve(str.size() + (pend-pbegin) * 2);
24235 for (const unsigned char* p = pend-1; p >= pbegin; p--)
24236 str += strprintf("%02x", *p);
24237 return str;
24238 }
24239
24240 inline std::string HexNumStr(const std::vector<unsigned char>& vch, bool f0x=true)
24241 {
24242 return HexNumStr(vch.begin(), vch.end(), f0x);
24243 }
24244
24245 template<typename T>
24246 void PrintHex(const T pbegin, const T pend, const char* pszFormat="%s", bool fSpaces=true)
24247 {
24248 printf(pszFormat, HexStr(pbegin, pend, fSpaces).c_str());
24249 }
24250
24251 inline void PrintHex(const std::vector<unsigned char>& vch, const char* pszFormat="%s", bool fSpaces=true)
24252 {
24253 printf(pszFormat, HexStr(vch, fSpaces).c_str());
24254 }
24255
24256 inline int64 GetPerformanceCounter()
24257 {
24258 int64 nCounter = 0;
24259 #ifdef WIN32
24260 QueryPerformanceCounter((LARGE_INTEGER*)&nCounter);
24261 #else
24262 timeval t;
24263 gettimeofday(&t, NULL);
24264 nCounter = t.tv_sec * 1000000 + t.tv_usec;
24265 #endif
24266 return nCounter;
24267 }
24268
24269 inline int64 GetTimeMillis()
24270 {
24271 return (boost::posix_time::ptime(boost::posix_time::microsec_clock::universal_time()) -
24272 boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_milliseconds();
24273 }
24274
24275 inline std::string DateTimeStrFormat(const char* pszFormat, int64 nTime)
24276 {
24277 time_t n = nTime;
24278 struct tm* ptmTime = gmtime(&n);
24279 char pszTime[200];
24280 strftime(pszTime, sizeof(pszTime), pszFormat, ptmTime);
24281 return pszTime;
24282 }
24283
24284 template<typename T>
24285 void skipspaces(T& it)
24286 {
24287 while (isspace(*it))
24288 ++it;
24289 }
24290
24291 inline bool IsSwitchChar(char c)
24292 {
24293 #ifdef WIN32
24294 return c == '-' || c == '/';
24295 #else
24296 return c == '-';
24297 #endif
24298 }
24299
24300 inline std::string GetArg(const std::string& strArg, const std::string& strDefault)
24301 {
24302 if (mapArgs.count(strArg))
24303 return mapArgs[strArg];
24304 return strDefault;
24305 }
24306
24307 inline int64 GetArg(const std::string& strArg, int64 nDefault)
24308 {
24309 if (mapArgs.count(strArg))
24310 return atoi64(mapArgs[strArg]);
24311 return nDefault;
24312 }
24313
24314 inline bool GetBoolArg(const std::string& strArg, bool fDefault=false)
24315 {
24316 if (mapArgs.count(strArg))
24317 {
24318 if (mapArgs[strArg].empty())
24319 return true;
24320 return (atoi(mapArgs[strArg]) != 0);
24321 }
24322 return fDefault;
24323 }
24324
24325 /**
24326 * Set an argument if it doesn't already have a value
24327 *
24328 * @param strArg Argument to set (e.g. "-foo")
24329 * @param strValue Value (e.g. "1")
24330 * @return true if argument gets set, false if it already had a value
24331 */
24332 bool SoftSetArg(const std::string& strArg, const std::string& strValue);
24333
24334 /**
24335 * Set a boolean argument if it doesn't already have a value
24336 *
24337 * @param strArg Argument to set (e.g. "-foo")
24338 * @param fValue Value (e.g. false)
24339 * @return true if argument gets set, false if it already had a value
24340 */
24341 bool SoftSetArg(const std::string& strArg, bool fValue);
24342
24343
24344
24345
24346
24347
24348
24349
24350
24351 inline void heapchk()
24352 {
24353 #ifdef WIN32
24354 /// for debugging
24355 //if (_heapchk() != _HEAPOK)
24356 // DebugBreak();
24357 #endif
24358 }
24359
24360 // Randomize the stack to help protect against buffer overrun exploits
24361 #define IMPLEMENT_RANDOMIZE_STACK(ThreadFn) \
24362 { \
24363 static char nLoops; \
24364 if (nLoops <= 0) \
24365 nLoops = GetRand(20) + 1; \
24366 if (nLoops-- > 1) \
24367 { \
24368 ThreadFn; \
24369 return; \
24370 } \
24371 }
24372
24373 #define CATCH_PRINT_EXCEPTION(pszFn) \
24374 catch (std::exception& e) { \
24375 PrintException(&e, (pszFn)); \
24376 } catch (...) { \
24377 PrintException(NULL, (pszFn)); \
24378 }
24379
24380
24381
24382
24383
24384
24385
24386
24387
24388
24389 template<typename T1>
24390 inline uint256 Hash(const T1 pbegin, const T1 pend)
24391 {
24392 static unsigned char pblank[1];
24393 uint256 hash1;
24394 SHA256((pbegin == pend ? pblank : (unsigned char*)&pbegin[0]), (pend - pbegin) * sizeof(pbegin[0]), (unsigned char*)&hash1);
24395 uint256 hash2;
24396 SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
24397 return hash2;
24398 }
24399
24400 template<typename T1, typename T2>
24401 inline uint256 Hash(const T1 p1begin, const T1 p1end,
24402 const T2 p2begin, const T2 p2end)
24403 {
24404 static unsigned char pblank[1];
24405 uint256 hash1;
24406 SHA256_CTX ctx;
24407 SHA256_Init(&ctx);
24408 SHA256_Update(&ctx, (p1begin == p1end ? pblank : (unsigned char*)&p1begin[0]), (p1end - p1begin) * sizeof(p1begin[0]));
24409 SHA256_Update(&ctx, (p2begin == p2end ? pblank : (unsigned char*)&p2begin[0]), (p2end - p2begin) * sizeof(p2begin[0]));
24410 SHA256_Final((unsigned char*)&hash1, &ctx);
24411 uint256 hash2;
24412 SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
24413 return hash2;
24414 }
24415
24416 template<typename T1, typename T2, typename T3>
24417 inline uint256 Hash(const T1 p1begin, const T1 p1end,
24418 const T2 p2begin, const T2 p2end,
24419 const T3 p3begin, const T3 p3end)
24420 {
24421 static unsigned char pblank[1];
24422 uint256 hash1;
24423 SHA256_CTX ctx;
24424 SHA256_Init(&ctx);
24425 SHA256_Update(&ctx, (p1begin == p1end ? pblank : (unsigned char*)&p1begin[0]), (p1end - p1begin) * sizeof(p1begin[0]));
24426 SHA256_Update(&ctx, (p2begin == p2end ? pblank : (unsigned char*)&p2begin[0]), (p2end - p2begin) * sizeof(p2begin[0]));
24427 SHA256_Update(&ctx, (p3begin == p3end ? pblank : (unsigned char*)&p3begin[0]), (p3end - p3begin) * sizeof(p3begin[0]));
24428 SHA256_Final((unsigned char*)&hash1, &ctx);
24429 uint256 hash2;
24430 SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
24431 return hash2;
24432 }
24433
24434 template<typename T>
24435 uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=VERSION)
24436 {
24437 // Most of the time is spent allocating and deallocating CDataStream's
24438 // buffer. If this ever needs to be optimized further, make a CStaticStream
24439 // class with its buffer on the stack.
24440 CDataStream ss(nType, nVersion);
24441 ss.reserve(10000);
24442 ss << obj;
24443 return Hash(ss.begin(), ss.end());
24444 }
24445
24446 inline uint160 Hash160(const std::vector<unsigned char>& vch)
24447 {
24448 uint256 hash1;
24449 SHA256(&vch[0], vch.size(), (unsigned char*)&hash1);
24450 uint160 hash2;
24451 RIPEMD160((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
24452 return hash2;
24453 }
24454
24455
24456 // Median filter over a stream of values
24457 // Returns the median of the last N numbers
24458 template <typename T> class CMedianFilter
24459 {
24460 private:
24461 std::vector<T> vValues;
24462 std::vector<T> vSorted;
24463 int nSize;
24464 public:
24465 CMedianFilter(int size, T initial_value):
24466 nSize(size)
24467 {
24468 vValues.reserve(size);
24469 vValues.push_back(initial_value);
24470 vSorted = vValues;
24471 }
24472
24473 void input(T value)
24474 {
24475 if(vValues.size() == nSize)
24476 {
24477 vValues.erase(vValues.begin());
24478 }
24479 vValues.push_back(value);
24480
24481 vSorted.resize(vValues.size());
24482 std::copy(vValues.begin(), vValues.end(), vSorted.begin());
24483 std::sort(vSorted.begin(), vSorted.end());
24484 }
24485
24486 T median() const
24487 {
24488 int size = vSorted.size();
24489 assert(size>0);
24490 if(size & 1) // Odd number of elements
24491 {
24492 return vSorted[size/2];
24493 }
24494 else // Even number of elements
24495 {
24496 return (vSorted[size/2-1] + vSorted[size/2]) / 2;
24497 }
24498 }
24499 };
24500
24501
24502
24503
24504
24505
24506
24507
24508
24509
24510 // Note: It turns out we might have been able to use boost::thread
24511 // by using TerminateThread(boost::thread.native_handle(), 0);
24512 #ifdef WIN32
24513 typedef HANDLE pthread_t;
24514
24515 inline pthread_t CreateThread(void(*pfn)(void*), void* parg, bool fWantHandle=false)
24516 {
24517 DWORD nUnused = 0;
24518 HANDLE hthread =
24519 CreateThread(
24520 NULL, // default security
24521 0, // inherit stack size from parent
24522 (LPTHREAD_START_ROUTINE)pfn, // function pointer
24523 parg, // argument
24524 0, // creation option, start immediately
24525 &nUnused); // thread identifier
24526 if (hthread == NULL)
24527 {
24528 printf("Error: CreateThread() returned %d\n", GetLastError());
24529 return (pthread_t)0;
24530 }
24531 if (!fWantHandle)
24532 {
24533 CloseHandle(hthread);
24534 return (pthread_t)-1;
24535 }
24536 return hthread;
24537 }
24538
24539 inline void SetThreadPriority(int nPriority)
24540 {
24541 SetThreadPriority(GetCurrentThread(), nPriority);
24542 }
24543 #else
24544 inline pthread_t CreateThread(void(*pfn)(void*), void* parg, bool fWantHandle=false)
24545 {
24546 pthread_t hthread = 0;
24547 int ret = pthread_create(&hthread, NULL, (void*(*)(void*))pfn, parg);
24548 if (ret != 0)
24549 {
24550 printf("Error: pthread_create() returned %d\n", ret);
24551 return (pthread_t)0;
24552 }
24553 if (!fWantHandle)
24554 {
24555 pthread_detach(hthread);
24556 return (pthread_t)-1;
24557 }
24558 return hthread;
24559 }
24560
24561 #define THREAD_PRIORITY_LOWEST PRIO_MAX
24562 #define THREAD_PRIORITY_BELOW_NORMAL 2
24563 #define THREAD_PRIORITY_NORMAL 0
24564 #define THREAD_PRIORITY_ABOVE_NORMAL 0
24565
24566 inline void SetThreadPriority(int nPriority)
24567 {
24568 // It's unclear if it's even possible to change thread priorities on Linux,
24569 // but we really and truly need it for the generation threads.
24570 #ifdef PRIO_THREAD
24571 setpriority(PRIO_THREAD, 0, nPriority);
24572 #else
24573 setpriority(PRIO_PROCESS, 0, nPriority);
24574 #endif
24575 }
24576
24577 inline bool TerminateThread(pthread_t hthread, unsigned int nExitCode)
24578 {
24579 return (pthread_cancel(hthread) == 0);
24580 }
24581
24582 inline void ExitThread(size_t nExitCode)
24583 {
24584 pthread_exit((void*)nExitCode);
24585 }
24586 #endif
24587
24588
24589
24590
24591
24592 inline bool AffinityBugWorkaround(void(*pfn)(void*))
24593 {
24594 #ifdef WIN32
24595 // Sometimes after a few hours affinity gets stuck on one processor
24596 DWORD_PTR dwProcessAffinityMask = -1;
24597 DWORD_PTR dwSystemAffinityMask = -1;
24598 GetProcessAffinityMask(GetCurrentProcess(), &dwProcessAffinityMask, &dwSystemAffinityMask);
24599 DWORD dwPrev1 = SetThreadAffinityMask(GetCurrentThread(), dwProcessAffinityMask);
24600 DWORD dwPrev2 = SetThreadAffinityMask(GetCurrentThread(), dwProcessAffinityMask);
24601 if (dwPrev2 != dwProcessAffinityMask)
24602 {
24603 printf("AffinityBugWorkaround() : SetThreadAffinityMask=%d, ProcessAffinityMask=%d, restarting thread\n", dwPrev2, dwProcessAffinityMask);
24604 if (!CreateThread(pfn, NULL))
24605 printf("Error: CreateThread() failed\n");
24606 return true;
24607 }
24608 #endif
24609 return false;
24610 }
24611
24612 inline uint32_t ByteReverse(uint32_t value)
24613 {
24614 value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
24615 return (value<<16) | (value>>16);
24616 }
24617
24618 #endif
-
+ DA1E35BCCE58F94AE0C44B6C2D8AC21D3B8263A594B93EFA335A6C804A1B115C16A977AB237D78C4E9EB6899FF5C9A108F36A9A2FC9FAD96DDAA2E30267587F7
bitcoin/src/wallet.cpp
(0 . 0)(1 . 1415)
24623 // Copyright (c) 2009-2010 Satoshi Nakamoto
24624 // Copyright (c) 2011 The Bitcoin developers
24625 // Distributed under the MIT/X11 software license, see the accompanying
24626 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
24627
24628 #include "headers.h"
24629 #include "db.h"
24630 #include "crypter.h"
24631
24632 using namespace std;
24633
24634
24635 //////////////////////////////////////////////////////////////////////////////
24636 //
24637 // mapWallet
24638 //
24639
24640 bool CWallet::AddKey(const CKey& key)
24641 {
24642 if (!CCryptoKeyStore::AddKey(key))
24643 return false;
24644 if (!fFileBacked)
24645 return true;
24646 if (!IsCrypted())
24647 return CWalletDB(strWalletFile).WriteKey(key.GetPubKey(), key.GetPrivKey());
24648 return true;
24649 }
24650
24651 bool CWallet::AddCryptedKey(const vector<unsigned char> &vchPubKey, const vector<unsigned char> &vchCryptedSecret)
24652 {
24653 if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret))
24654 return false;
24655 if (!fFileBacked)
24656 return true;
24657 CRITICAL_BLOCK(cs_wallet)
24658 {
24659 if (pwalletdbEncryption)
24660 return pwalletdbEncryption->WriteCryptedKey(vchPubKey, vchCryptedSecret);
24661 else
24662 return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey, vchCryptedSecret);
24663 }
24664 return false;
24665 }
24666
24667 bool CWallet::Unlock(const SecureString& strWalletPassphrase)
24668 {
24669 if (!IsLocked())
24670 return false;
24671
24672 CCrypter crypter;
24673 CKeyingMaterial vMasterKey;
24674
24675 CRITICAL_BLOCK(cs_wallet)
24676 BOOST_FOREACH(const MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
24677 {
24678 if(!crypter.SetKeyFromPassphrase(strWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
24679 return false;
24680 if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
24681 return false;
24682 if (CCryptoKeyStore::Unlock(vMasterKey))
24683 return true;
24684 }
24685 return false;
24686 }
24687
24688 bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase)
24689 {
24690 bool fWasLocked = IsLocked();
24691
24692 CRITICAL_BLOCK(cs_wallet)
24693 {
24694 Lock();
24695
24696 CCrypter crypter;
24697 CKeyingMaterial vMasterKey;
24698 BOOST_FOREACH(MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
24699 {
24700 if(!crypter.SetKeyFromPassphrase(strOldWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
24701 return false;
24702 if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
24703 return false;
24704 if (CCryptoKeyStore::Unlock(vMasterKey))
24705 {
24706 int64 nStartTime = GetTimeMillis();
24707 crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
24708 pMasterKey.second.nDeriveIterations = pMasterKey.second.nDeriveIterations * (100 / ((double)(GetTimeMillis() - nStartTime)));
24709
24710 nStartTime = GetTimeMillis();
24711 crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
24712 pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + pMasterKey.second.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2;
24713
24714 if (pMasterKey.second.nDeriveIterations < 25000)
24715 pMasterKey.second.nDeriveIterations = 25000;
24716
24717 printf("Wallet passphrase changed to an nDeriveIterations of %i\n", pMasterKey.second.nDeriveIterations);
24718
24719 if (!crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
24720 return false;
24721 if (!crypter.Encrypt(vMasterKey, pMasterKey.second.vchCryptedKey))
24722 return false;
24723 CWalletDB(strWalletFile).WriteMasterKey(pMasterKey.first, pMasterKey.second);
24724 if (fWasLocked)
24725 Lock();
24726 return true;
24727 }
24728 }
24729 }
24730
24731 return false;
24732 }
24733
24734
24735 // This class implements an addrIncoming entry that causes pre-0.4
24736 // clients to crash on startup if reading a private-key-encrypted wallet.
24737 class CCorruptAddress
24738 {
24739 public:
24740 IMPLEMENT_SERIALIZE
24741 (
24742 if (nType & SER_DISK)
24743 READWRITE(nVersion);
24744 )
24745 };
24746
24747 bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
24748 {
24749 if (IsCrypted())
24750 return false;
24751
24752 CKeyingMaterial vMasterKey;
24753 RandAddSeedPerfmon();
24754
24755 vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE);
24756 RAND_bytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE);
24757
24758 CMasterKey kMasterKey;
24759
24760 RandAddSeedPerfmon();
24761 kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE);
24762 RAND_bytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE);
24763
24764 CCrypter crypter;
24765 int64 nStartTime = GetTimeMillis();
24766 crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod);
24767 kMasterKey.nDeriveIterations = 2500000 / ((double)(GetTimeMillis() - nStartTime));
24768
24769 nStartTime = GetTimeMillis();
24770 crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod);
24771 kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + kMasterKey.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2;
24772
24773 if (kMasterKey.nDeriveIterations < 25000)
24774 kMasterKey.nDeriveIterations = 25000;
24775
24776 printf("Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations);
24777
24778 if (!crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod))
24779 return false;
24780 if (!crypter.Encrypt(vMasterKey, kMasterKey.vchCryptedKey))
24781 return false;
24782
24783 CRITICAL_BLOCK(cs_wallet)
24784 {
24785 mapMasterKeys[++nMasterKeyMaxID] = kMasterKey;
24786 if (fFileBacked)
24787 {
24788 pwalletdbEncryption = new CWalletDB(strWalletFile);
24789 pwalletdbEncryption->TxnBegin();
24790 pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey);
24791 }
24792
24793 if (!EncryptKeys(vMasterKey))
24794 {
24795 if (fFileBacked)
24796 pwalletdbEncryption->TxnAbort();
24797 exit(1); //We now probably have half of our keys encrypted in memory, and half not...die and let the user reload their unencrypted wallet.
24798 }
24799
24800 if (fFileBacked)
24801 {
24802 CCorruptAddress corruptAddress;
24803 pwalletdbEncryption->WriteSetting("addrIncoming", corruptAddress);
24804 if (!pwalletdbEncryption->TxnCommit())
24805 exit(1); //We now have keys encrypted in memory, but no on disk...die to avoid confusion and let the user reload their unencrypted wallet.
24806
24807 delete pwalletdbEncryption;
24808 pwalletdbEncryption = NULL;
24809 }
24810
24811 Lock();
24812 Unlock(strWalletPassphrase);
24813 NewKeyPool();
24814 Lock();
24815
24816 // Need to completely rewrite the wallet file; if we don't, bdb might keep
24817 // bits of the unencrypted private key in slack space in the database file.
24818 CDB::Rewrite(strWalletFile);
24819 }
24820
24821 return true;
24822 }
24823
24824 void CWallet::WalletUpdateSpent(const CTransaction &tx)
24825 {
24826 // Anytime a signature is successfully verified, it's proof the outpoint is spent.
24827 // Update the wallet spent flag if it doesn't know due to wallet.dat being
24828 // restored from backup or the user making copies of wallet.dat.
24829 CRITICAL_BLOCK(cs_wallet)
24830 {
24831 BOOST_FOREACH(const CTxIn& txin, tx.vin)
24832 {
24833 map<uint256, CWalletTx>::iterator mi = mapWallet.find(txin.prevout.hash);
24834 if (mi != mapWallet.end())
24835 {
24836 CWalletTx& wtx = (*mi).second;
24837 if (!wtx.IsSpent(txin.prevout.n) && IsMine(wtx.vout[txin.prevout.n]))
24838 {
24839 printf("WalletUpdateSpent found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str());
24840 wtx.MarkSpent(txin.prevout.n);
24841 wtx.WriteToDisk();
24842 vWalletUpdated.push_back(txin.prevout.hash);
24843 }
24844 }
24845 }
24846 }
24847 }
24848
24849 bool CWallet::AddToWallet(const CWalletTx& wtxIn)
24850 {
24851 uint256 hash = wtxIn.GetHash();
24852 CRITICAL_BLOCK(cs_wallet)
24853 {
24854 // Inserts only if not already there, returns tx inserted or tx found
24855 pair<map<uint256, CWalletTx>::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn));
24856 CWalletTx& wtx = (*ret.first).second;
24857 wtx.pwallet = this;
24858 bool fInsertedNew = ret.second;
24859 if (fInsertedNew)
24860 wtx.nTimeReceived = GetAdjustedTime();
24861
24862 bool fUpdated = false;
24863 if (!fInsertedNew)
24864 {
24865 // Merge
24866 if (wtxIn.hashBlock != 0 && wtxIn.hashBlock != wtx.hashBlock)
24867 {
24868 wtx.hashBlock = wtxIn.hashBlock;
24869 fUpdated = true;
24870 }
24871 if (wtxIn.nIndex != -1 && (wtxIn.vMerkleBranch != wtx.vMerkleBranch || wtxIn.nIndex != wtx.nIndex))
24872 {
24873 wtx.vMerkleBranch = wtxIn.vMerkleBranch;
24874 wtx.nIndex = wtxIn.nIndex;
24875 fUpdated = true;
24876 }
24877 if (wtxIn.fFromMe && wtxIn.fFromMe != wtx.fFromMe)
24878 {
24879 wtx.fFromMe = wtxIn.fFromMe;
24880 fUpdated = true;
24881 }
24882 fUpdated |= wtx.UpdateSpent(wtxIn.vfSpent);
24883 }
24884
24885 //// debug print
24886 printf("AddToWallet %s %s%s\n", wtxIn.GetHash().ToString().substr(0,10).c_str(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : ""));
24887
24888 // Write to disk
24889 if (fInsertedNew || fUpdated)
24890 if (!wtx.WriteToDisk())
24891 return false;
24892 #ifndef QT_GUI
24893 // If default receiving address gets used, replace it with a new one
24894 CScript scriptDefaultKey;
24895 scriptDefaultKey.SetBitcoinAddress(vchDefaultKey);
24896 BOOST_FOREACH(const CTxOut& txout, wtx.vout)
24897 {
24898 if (txout.scriptPubKey == scriptDefaultKey)
24899 {
24900 std::vector<unsigned char> newDefaultKey;
24901 if (GetKeyFromPool(newDefaultKey, false))
24902 {
24903 SetDefaultKey(newDefaultKey);
24904 SetAddressBookName(CBitcoinAddress(vchDefaultKey), "");
24905 }
24906 }
24907 }
24908 #endif
24909 // Notify UI
24910 vWalletUpdated.push_back(hash);
24911
24912 // since AddToWallet is called directly for self-originating transactions, check for consumption of own coins
24913 WalletUpdateSpent(wtx);
24914 }
24915
24916 // Refresh UI
24917 MainFrameRepaint();
24918 return true;
24919 }
24920
24921 // Add a transaction to the wallet, or update it.
24922 // pblock is optional, but should be provided if the transaction is known to be in a block.
24923 // If fUpdate is true, existing transactions will be updated.
24924 bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate)
24925 {
24926 uint256 hash = tx.GetHash();
24927 CRITICAL_BLOCK(cs_wallet)
24928 {
24929 bool fExisted = mapWallet.count(hash);
24930 if (fExisted && !fUpdate) return false;
24931 if (fExisted || IsMine(tx) || IsFromMe(tx))
24932 {
24933 CWalletTx wtx(this,tx);
24934 // Get merkle branch if transaction was found in a block
24935 if (pblock)
24936 wtx.SetMerkleBranch(pblock);
24937 return AddToWallet(wtx);
24938 }
24939 else
24940 WalletUpdateSpent(tx);
24941 }
24942 return false;
24943 }
24944
24945 bool CWallet::EraseFromWallet(uint256 hash)
24946 {
24947 if (!fFileBacked)
24948 return false;
24949 CRITICAL_BLOCK(cs_wallet)
24950 {
24951 if (mapWallet.erase(hash))
24952 CWalletDB(strWalletFile).EraseTx(hash);
24953 }
24954 return true;
24955 }
24956
24957
24958 bool CWallet::IsMine(const CTxIn &txin) const
24959 {
24960 CRITICAL_BLOCK(cs_wallet)
24961 {
24962 map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
24963 if (mi != mapWallet.end())
24964 {
24965 const CWalletTx& prev = (*mi).second;
24966 if (txin.prevout.n < prev.vout.size())
24967 if (IsMine(prev.vout[txin.prevout.n]))
24968 return true;
24969 }
24970 }
24971 return false;
24972 }
24973
24974 int64 CWallet::GetDebit(const CTxIn &txin) const
24975 {
24976 CRITICAL_BLOCK(cs_wallet)
24977 {
24978 map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
24979 if (mi != mapWallet.end())
24980 {
24981 const CWalletTx& prev = (*mi).second;
24982 if (txin.prevout.n < prev.vout.size())
24983 if (IsMine(prev.vout[txin.prevout.n]))
24984 return prev.vout[txin.prevout.n].nValue;
24985 }
24986 }
24987 return 0;
24988 }
24989
24990 int64 CWalletTx::GetTxTime() const
24991 {
24992 return nTimeReceived;
24993 }
24994
24995 int CWalletTx::GetRequestCount() const
24996 {
24997 // Returns -1 if it wasn't being tracked
24998 int nRequests = -1;
24999 CRITICAL_BLOCK(pwallet->cs_wallet)
25000 {
25001 if (IsCoinBase())
25002 {
25003 // Generated block
25004 if (hashBlock != 0)
25005 {
25006 map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
25007 if (mi != pwallet->mapRequestCount.end())
25008 nRequests = (*mi).second;
25009 }
25010 }
25011 else
25012 {
25013 // Did anyone request this transaction?
25014 map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(GetHash());
25015 if (mi != pwallet->mapRequestCount.end())
25016 {
25017 nRequests = (*mi).second;
25018
25019 // How about the block it's in?
25020 if (nRequests == 0 && hashBlock != 0)
25021 {
25022 map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
25023 if (mi != pwallet->mapRequestCount.end())
25024 nRequests = (*mi).second;
25025 else
25026 nRequests = 1; // If it's in someone else's block it must have got out
25027 }
25028 }
25029 }
25030 }
25031 return nRequests;
25032 }
25033
25034 void CWalletTx::GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, list<pair<CBitcoinAddress, int64> >& listReceived,
25035 list<pair<CBitcoinAddress, int64> >& listSent, int64& nFee, string& strSentAccount) const
25036 {
25037 nGeneratedImmature = nGeneratedMature = nFee = 0;
25038 listReceived.clear();
25039 listSent.clear();
25040 strSentAccount = strFromAccount;
25041
25042 if (IsCoinBase())
25043 {
25044 if (GetBlocksToMaturity() > 0)
25045 nGeneratedImmature = pwallet->GetCredit(*this);
25046 else
25047 nGeneratedMature = GetCredit();
25048 return;
25049 }
25050
25051 // Compute fee:
25052 int64 nDebit = GetDebit();
25053 if (nDebit > 0) // debit>0 means we signed/sent this transaction
25054 {
25055 int64 nValueOut = GetValueOut();
25056 nFee = nDebit - nValueOut;
25057 }
25058
25059 // Sent/received. Standard client will never generate a send-to-multiple-recipients,
25060 // but non-standard clients might (so return a list of address/amount pairs)
25061 BOOST_FOREACH(const CTxOut& txout, vout)
25062 {
25063 CBitcoinAddress address;
25064 vector<unsigned char> vchPubKey;
25065 if (!ExtractAddress(txout.scriptPubKey, NULL, address))
25066 {
25067 printf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n",
25068 this->GetHash().ToString().c_str());
25069 address = " unknown ";
25070 }
25071
25072 // Don't report 'change' txouts
25073 if (nDebit > 0 && pwallet->IsChange(txout))
25074 continue;
25075
25076 if (nDebit > 0)
25077 listSent.push_back(make_pair(address, txout.nValue));
25078
25079 if (pwallet->IsMine(txout))
25080 listReceived.push_back(make_pair(address, txout.nValue));
25081 }
25082
25083 }
25084
25085 void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nGenerated, int64& nReceived,
25086 int64& nSent, int64& nFee) const
25087 {
25088 nGenerated = nReceived = nSent = nFee = 0;
25089
25090 int64 allGeneratedImmature, allGeneratedMature, allFee;
25091 allGeneratedImmature = allGeneratedMature = allFee = 0;
25092 string strSentAccount;
25093 list<pair<CBitcoinAddress, int64> > listReceived;
25094 list<pair<CBitcoinAddress, int64> > listSent;
25095 GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount);
25096
25097 if (strAccount == "")
25098 nGenerated = allGeneratedMature;
25099 if (strAccount == strSentAccount)
25100 {
25101 BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& s, listSent)
25102 nSent += s.second;
25103 nFee = allFee;
25104 }
25105 CRITICAL_BLOCK(pwallet->cs_wallet)
25106 {
25107 BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listReceived)
25108 {
25109 if (pwallet->mapAddressBook.count(r.first))
25110 {
25111 map<CBitcoinAddress, string>::const_iterator mi = pwallet->mapAddressBook.find(r.first);
25112 if (mi != pwallet->mapAddressBook.end() && (*mi).second == strAccount)
25113 nReceived += r.second;
25114 }
25115 else if (strAccount.empty())
25116 {
25117 nReceived += r.second;
25118 }
25119 }
25120 }
25121 }
25122
25123 void CWalletTx::AddSupportingTransactions(CTxDB& txdb)
25124 {
25125 vtxPrev.clear();
25126
25127 const int COPY_DEPTH = 3;
25128 if (SetMerkleBranch() < COPY_DEPTH)
25129 {
25130 vector<uint256> vWorkQueue;
25131 BOOST_FOREACH(const CTxIn& txin, vin)
25132 vWorkQueue.push_back(txin.prevout.hash);
25133
25134 // This critsect is OK because txdb is already open
25135 CRITICAL_BLOCK(pwallet->cs_wallet)
25136 {
25137 map<uint256, const CMerkleTx*> mapWalletPrev;
25138 set<uint256> setAlreadyDone;
25139 for (int i = 0; i < vWorkQueue.size(); i++)
25140 {
25141 uint256 hash = vWorkQueue[i];
25142 if (setAlreadyDone.count(hash))
25143 continue;
25144 setAlreadyDone.insert(hash);
25145
25146 CMerkleTx tx;
25147 map<uint256, CWalletTx>::const_iterator mi = pwallet->mapWallet.find(hash);
25148 if (mi != pwallet->mapWallet.end())
25149 {
25150 tx = (*mi).second;
25151 BOOST_FOREACH(const CMerkleTx& txWalletPrev, (*mi).second.vtxPrev)
25152 mapWalletPrev[txWalletPrev.GetHash()] = &txWalletPrev;
25153 }
25154 else if (mapWalletPrev.count(hash))
25155 {
25156 tx = *mapWalletPrev[hash];
25157 }
25158 else if (!fClient && txdb.ReadDiskTx(hash, tx))
25159 {
25160 ;
25161 }
25162 else
25163 {
25164 printf("ERROR: AddSupportingTransactions() : unsupported transaction\n");
25165 continue;
25166 }
25167
25168 int nDepth = tx.SetMerkleBranch();
25169 vtxPrev.push_back(tx);
25170
25171 if (nDepth < COPY_DEPTH)
25172 BOOST_FOREACH(const CTxIn& txin, tx.vin)
25173 vWorkQueue.push_back(txin.prevout.hash);
25174 }
25175 }
25176 }
25177
25178 reverse(vtxPrev.begin(), vtxPrev.end());
25179 }
25180
25181 bool CWalletTx::WriteToDisk()
25182 {
25183 return CWalletDB(pwallet->strWalletFile).WriteTx(GetHash(), *this);
25184 }
25185
25186 // Scan the block chain (starting in pindexStart) for transactions
25187 // from or to us. If fUpdate is true, found transactions that already
25188 // exist in the wallet will be updated.
25189 int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
25190 {
25191 int ret = 0;
25192
25193 CBlockIndex* pindex = pindexStart;
25194 CRITICAL_BLOCK(cs_wallet)
25195 {
25196 while (pindex)
25197 {
25198 CBlock block;
25199 block.ReadFromDisk(pindex, true);
25200 BOOST_FOREACH(CTransaction& tx, block.vtx)
25201 {
25202 if (AddToWalletIfInvolvingMe(tx, &block, fUpdate))
25203 ret++;
25204 }
25205 pindex = pindex->pnext;
25206 }
25207 }
25208 return ret;
25209 }
25210
25211 void CWallet::ReacceptWalletTransactions()
25212 {
25213 CTxDB txdb("r");
25214 bool fRepeat = true;
25215 while (fRepeat) CRITICAL_BLOCK(cs_wallet)
25216 {
25217 fRepeat = false;
25218 vector<CDiskTxPos> vMissingTx;
25219 BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
25220 {
25221 CWalletTx& wtx = item.second;
25222 if (wtx.IsCoinBase() && wtx.IsSpent(0))
25223 continue;
25224
25225 CTxIndex txindex;
25226 bool fUpdated = false;
25227 if (txdb.ReadTxIndex(wtx.GetHash(), txindex))
25228 {
25229 // Update fSpent if a tx got spent somewhere else by a copy of wallet.dat
25230 if (txindex.vSpent.size() != wtx.vout.size())
25231 {
25232 printf("ERROR: ReacceptWalletTransactions() : txindex.vSpent.size() %d != wtx.vout.size() %d\n", txindex.vSpent.size(), wtx.vout.size());
25233 continue;
25234 }
25235 for (int i = 0; i < txindex.vSpent.size(); i++)
25236 {
25237 if (wtx.IsSpent(i))
25238 continue;
25239 if (!txindex.vSpent[i].IsNull() && IsMine(wtx.vout[i]))
25240 {
25241 wtx.MarkSpent(i);
25242 fUpdated = true;
25243 vMissingTx.push_back(txindex.vSpent[i]);
25244 }
25245 }
25246 if (fUpdated)
25247 {
25248 printf("ReacceptWalletTransactions found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str());
25249 wtx.MarkDirty();
25250 wtx.WriteToDisk();
25251 }
25252 }
25253 else
25254 {
25255 // Reaccept any txes of ours that aren't already in a block
25256 if (!wtx.IsCoinBase())
25257 wtx.AcceptWalletTransaction(txdb, false);
25258 }
25259 }
25260 if (!vMissingTx.empty())
25261 {
25262 // TODO: optimize this to scan just part of the block chain?
25263 if (ScanForWalletTransactions(pindexGenesisBlock))
25264 fRepeat = true; // Found missing transactions: re-do Reaccept.
25265 }
25266 }
25267 }
25268
25269 void CWalletTx::RelayWalletTransaction(CTxDB& txdb)
25270 {
25271 BOOST_FOREACH(const CMerkleTx& tx, vtxPrev)
25272 {
25273 if (!tx.IsCoinBase())
25274 {
25275 uint256 hash = tx.GetHash();
25276 if (!txdb.ContainsTx(hash))
25277 RelayMessage(CInv(MSG_TX, hash), (CTransaction)tx);
25278 }
25279 }
25280 if (!IsCoinBase())
25281 {
25282 uint256 hash = GetHash();
25283 if (!txdb.ContainsTx(hash))
25284 {
25285 printf("Relaying wtx %s\n", hash.ToString().substr(0,10).c_str());
25286 RelayMessage(CInv(MSG_TX, hash), (CTransaction)*this);
25287 }
25288 }
25289 }
25290
25291 void CWalletTx::RelayWalletTransaction()
25292 {
25293 CTxDB txdb("r");
25294 RelayWalletTransaction(txdb);
25295 }
25296
25297 void CWallet::ResendWalletTransactions()
25298 {
25299 // Do this infrequently and randomly to avoid giving away
25300 // that these are our transactions.
25301 static int64 nNextTime;
25302 if (GetTime() < nNextTime)
25303 return;
25304 bool fFirst = (nNextTime == 0);
25305 nNextTime = GetTime() + GetRand(30 * 60);
25306 if (fFirst)
25307 return;
25308
25309 // Only do it if there's been a new block since last time
25310 static int64 nLastTime;
25311 if (nTimeBestReceived < nLastTime)
25312 return;
25313 nLastTime = GetTime();
25314
25315 // Rebroadcast any of our txes that aren't in a block yet
25316 printf("ResendWalletTransactions()\n");
25317 CTxDB txdb("r");
25318 CRITICAL_BLOCK(cs_wallet)
25319 {
25320 // Sort them in chronological order
25321 multimap<unsigned int, CWalletTx*> mapSorted;
25322 BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
25323 {
25324 CWalletTx& wtx = item.second;
25325 // Don't rebroadcast until it's had plenty of time that
25326 // it should have gotten in already by now.
25327 if (nTimeBestReceived - (int64)wtx.nTimeReceived > 5 * 60)
25328 mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx));
25329 }
25330 BOOST_FOREACH(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted)
25331 {
25332 CWalletTx& wtx = *item.second;
25333 wtx.RelayWalletTransaction(txdb);
25334 }
25335 }
25336 }
25337
25338
25339
25340
25341
25342
25343 //////////////////////////////////////////////////////////////////////////////
25344 //
25345 // Actions
25346 //
25347
25348
25349 int64 CWallet::GetBalance() const
25350 {
25351 int64 nTotal = 0;
25352 CRITICAL_BLOCK(cs_wallet)
25353 {
25354 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
25355 {
25356 const CWalletTx* pcoin = &(*it).second;
25357 if (!pcoin->IsFinal() || !pcoin->IsConfirmed())
25358 continue;
25359 nTotal += pcoin->GetAvailableCredit();
25360 }
25361 }
25362
25363 return nTotal;
25364 }
25365
25366 int64 CWallet::GetUnconfirmedBalance() const
25367 {
25368 int64 nTotal = 0;
25369 CRITICAL_BLOCK(cs_wallet)
25370 {
25371 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
25372 {
25373 const CWalletTx* pcoin = &(*it).second;
25374 if (pcoin->IsFinal() && pcoin->IsConfirmed())
25375 continue;
25376 nTotal += pcoin->GetAvailableCredit();
25377 }
25378 }
25379 return nTotal;
25380 }
25381
25382 bool CWallet::SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfTheirs, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const
25383 {
25384 setCoinsRet.clear();
25385 nValueRet = 0;
25386
25387 // List of values less than target
25388 pair<int64, pair<const CWalletTx*,unsigned int> > coinLowestLarger;
25389 coinLowestLarger.first = INT64_MAX;
25390 coinLowestLarger.second.first = NULL;
25391 vector<pair<int64, pair<const CWalletTx*,unsigned int> > > vValue;
25392 int64 nTotalLower = 0;
25393
25394 CRITICAL_BLOCK(cs_wallet)
25395 {
25396 vector<const CWalletTx*> vCoins;
25397 vCoins.reserve(mapWallet.size());
25398 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
25399 vCoins.push_back(&(*it).second);
25400 random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt);
25401
25402 BOOST_FOREACH(const CWalletTx* pcoin, vCoins)
25403 {
25404 if (!pcoin->IsFinal() || !pcoin->IsConfirmed())
25405 continue;
25406
25407 if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
25408 continue;
25409
25410 int nDepth = pcoin->GetDepthInMainChain();
25411 if (nDepth < (pcoin->IsFromMe() ? nConfMine : nConfTheirs))
25412 continue;
25413
25414 for (int i = 0; i < pcoin->vout.size(); i++)
25415 {
25416 if (pcoin->IsSpent(i) || !IsMine(pcoin->vout[i]))
25417 continue;
25418
25419 int64 n = pcoin->vout[i].nValue;
25420
25421 if (n <= 0)
25422 continue;
25423
25424 pair<int64,pair<const CWalletTx*,unsigned int> > coin = make_pair(n,make_pair(pcoin,i));
25425
25426 if (n == nTargetValue)
25427 {
25428 setCoinsRet.insert(coin.second);
25429 nValueRet += coin.first;
25430 return true;
25431 }
25432 else if (n < nTargetValue + CENT)
25433 {
25434 vValue.push_back(coin);
25435 nTotalLower += n;
25436 }
25437 else if (n < coinLowestLarger.first)
25438 {
25439 coinLowestLarger = coin;
25440 }
25441 }
25442 }
25443 }
25444
25445 if (nTotalLower == nTargetValue || nTotalLower == nTargetValue + CENT)
25446 {
25447 for (int i = 0; i < vValue.size(); ++i)
25448 {
25449 setCoinsRet.insert(vValue[i].second);
25450 nValueRet += vValue[i].first;
25451 }
25452 return true;
25453 }
25454
25455 if (nTotalLower < nTargetValue + (coinLowestLarger.second.first ? CENT : 0))
25456 {
25457 if (coinLowestLarger.second.first == NULL)
25458 return false;
25459 setCoinsRet.insert(coinLowestLarger.second);
25460 nValueRet += coinLowestLarger.first;
25461 return true;
25462 }
25463
25464 if (nTotalLower >= nTargetValue + CENT)
25465 nTargetValue += CENT;
25466
25467 // Solve subset sum by stochastic approximation
25468 sort(vValue.rbegin(), vValue.rend());
25469 vector<char> vfIncluded;
25470 vector<char> vfBest(vValue.size(), true);
25471 int64 nBest = nTotalLower;
25472
25473 for (int nRep = 0; nRep < 1000 && nBest != nTargetValue; nRep++)
25474 {
25475 vfIncluded.assign(vValue.size(), false);
25476 int64 nTotal = 0;
25477 bool fReachedTarget = false;
25478 for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++)
25479 {
25480 for (int i = 0; i < vValue.size(); i++)
25481 {
25482 if (nPass == 0 ? rand() % 2 : !vfIncluded[i])
25483 {
25484 nTotal += vValue[i].first;
25485 vfIncluded[i] = true;
25486 if (nTotal >= nTargetValue)
25487 {
25488 fReachedTarget = true;
25489 if (nTotal < nBest)
25490 {
25491 nBest = nTotal;
25492 vfBest = vfIncluded;
25493 }
25494 nTotal -= vValue[i].first;
25495 vfIncluded[i] = false;
25496 }
25497 }
25498 }
25499 }
25500 }
25501
25502 // If the next larger is still closer, return it
25503 if (coinLowestLarger.second.first && coinLowestLarger.first - nTargetValue <= nBest - nTargetValue)
25504 {
25505 setCoinsRet.insert(coinLowestLarger.second);
25506 nValueRet += coinLowestLarger.first;
25507 }
25508 else {
25509 for (int i = 0; i < vValue.size(); i++)
25510 if (vfBest[i])
25511 {
25512 setCoinsRet.insert(vValue[i].second);
25513 nValueRet += vValue[i].first;
25514 }
25515
25516 //// debug print
25517 printf("SelectCoins() best subset: ");
25518 for (int i = 0; i < vValue.size(); i++)
25519 if (vfBest[i])
25520 printf("%s ", FormatMoney(vValue[i].first).c_str());
25521 printf("total %s\n", FormatMoney(nBest).c_str());
25522 }
25523
25524 return true;
25525 }
25526
25527 bool CWallet::SelectCoins(int64 nTargetValue, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const
25528 {
25529 return (SelectCoinsMinConf(nTargetValue, 1, 6, setCoinsRet, nValueRet) ||
25530 SelectCoinsMinConf(nTargetValue, 1, 1, setCoinsRet, nValueRet) ||
25531 SelectCoinsMinConf(nTargetValue, 0, 1, setCoinsRet, nValueRet));
25532 }
25533
25534
25535
25536
25537 bool CWallet::CreateTransaction(const vector<pair<CScript, int64> >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet)
25538 {
25539 int64 nValue = 0;
25540 BOOST_FOREACH (const PAIRTYPE(CScript, int64)& s, vecSend)
25541 {
25542 if (nValue < 0)
25543 return false;
25544 nValue += s.second;
25545 }
25546 if (vecSend.empty() || nValue < 0)
25547 return false;
25548
25549 wtxNew.pwallet = this;
25550
25551 CRITICAL_BLOCK(cs_main)
25552 CRITICAL_BLOCK(cs_wallet)
25553 {
25554 // txdb must be opened before the mapWallet lock
25555 CTxDB txdb("r");
25556 {
25557 nFeeRet = nTransactionFee;
25558 loop
25559 {
25560 wtxNew.vin.clear();
25561 wtxNew.vout.clear();
25562 wtxNew.fFromMe = true;
25563
25564 int64 nTotalValue = nValue + nFeeRet;
25565 double dPriority = 0;
25566 // vouts to the payees
25567 BOOST_FOREACH (const PAIRTYPE(CScript, int64)& s, vecSend)
25568 wtxNew.vout.push_back(CTxOut(s.second, s.first));
25569
25570 // Choose coins to use
25571 set<pair<const CWalletTx*,unsigned int> > setCoins;
25572 int64 nValueIn = 0;
25573 if (!SelectCoins(nTotalValue, setCoins, nValueIn))
25574 return false;
25575 BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins)
25576 {
25577 int64 nCredit = pcoin.first->vout[pcoin.second].nValue;
25578 dPriority += (double)nCredit * pcoin.first->GetDepthInMainChain();
25579 }
25580
25581 int64 nChange = nValueIn - nValue - nFeeRet;
25582 // if sub-cent change is required, the fee must be raised to at least MIN_TX_FEE
25583 // or until nChange becomes zero
25584 if (nFeeRet < MIN_TX_FEE && nChange > 0 && nChange < CENT)
25585 {
25586 int64 nMoveToFee = min(nChange, MIN_TX_FEE - nFeeRet);
25587 nChange -= nMoveToFee;
25588 nFeeRet += nMoveToFee;
25589 }
25590
25591 if (nChange > 0)
25592 {
25593 // Note: We use a new key here to keep it from being obvious which side is the change.
25594 // The drawback is that by not reusing a previous key, the change may be lost if a
25595 // backup is restored, if the backup doesn't have the new private key for the change.
25596 // If we reused the old key, it would be possible to add code to look for and
25597 // rediscover unknown transactions that were written with keys of ours to recover
25598 // post-backup change.
25599
25600 // Reserve a new key pair from key pool
25601 vector<unsigned char> vchPubKey = reservekey.GetReservedKey();
25602 // assert(mapKeys.count(vchPubKey));
25603
25604 // Fill a vout to ourself, using same address type as the payment
25605 CScript scriptChange;
25606 if (vecSend[0].first.GetBitcoinAddress().IsValid())
25607 scriptChange.SetBitcoinAddress(vchPubKey);
25608 else
25609 scriptChange << vchPubKey << OP_CHECKSIG;
25610
25611 // Insert change txn at random position:
25612 vector<CTxOut>::iterator position = wtxNew.vout.begin()+GetRandInt(wtxNew.vout.size());
25613 wtxNew.vout.insert(position, CTxOut(nChange, scriptChange));
25614 }
25615 else
25616 reservekey.ReturnKey();
25617
25618 // Fill vin
25619 BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
25620 wtxNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second));
25621
25622 // Sign
25623 int nIn = 0;
25624 BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
25625 if (!SignSignature(*this, *coin.first, wtxNew, nIn++))
25626 return false;
25627
25628 // Limit size
25629 unsigned int nBytes = ::GetSerializeSize(*(CTransaction*)&wtxNew, SER_NETWORK);
25630 if (nBytes >= MAX_BLOCK_SIZE_GEN/5)
25631 return false;
25632 dPriority /= nBytes;
25633
25634 // Check that enough fee is included
25635 int64 nPayFee = nTransactionFee * (1 + (int64)nBytes / 1000);
25636 bool fAllowFree = CTransaction::AllowFree(dPriority);
25637 int64 nMinFee = wtxNew.GetMinFee(1, fAllowFree);
25638 if (nFeeRet < max(nPayFee, nMinFee))
25639 {
25640 nFeeRet = max(nPayFee, nMinFee);
25641 continue;
25642 }
25643
25644 // Fill vtxPrev by copying from previous transactions vtxPrev
25645 wtxNew.AddSupportingTransactions(txdb);
25646 wtxNew.fTimeReceivedIsTxTime = true;
25647
25648 break;
25649 }
25650 }
25651 }
25652 return true;
25653 }
25654
25655 bool CWallet::CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet)
25656 {
25657 vector< pair<CScript, int64> > vecSend;
25658 vecSend.push_back(make_pair(scriptPubKey, nValue));
25659 return CreateTransaction(vecSend, wtxNew, reservekey, nFeeRet);
25660 }
25661
25662 // Call after CreateTransaction unless you want to abort
25663 bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
25664 {
25665 CRITICAL_BLOCK(cs_main)
25666 CRITICAL_BLOCK(cs_wallet)
25667 {
25668 printf("CommitTransaction:\n%s", wtxNew.ToString().c_str());
25669 {
25670 // This is only to keep the database open to defeat the auto-flush for the
25671 // duration of this scope. This is the only place where this optimization
25672 // maybe makes sense; please don't do it anywhere else.
25673 CWalletDB* pwalletdb = fFileBacked ? new CWalletDB(strWalletFile,"r") : NULL;
25674
25675 // Take key pair from key pool so it won't be used again
25676 reservekey.KeepKey();
25677
25678 // Add tx to wallet, because if it has change it's also ours,
25679 // otherwise just for transaction history.
25680 AddToWallet(wtxNew);
25681
25682 // Mark old coins as spent
25683 set<CWalletTx*> setCoins;
25684 BOOST_FOREACH(const CTxIn& txin, wtxNew.vin)
25685 {
25686 CWalletTx &coin = mapWallet[txin.prevout.hash];
25687 coin.pwallet = this;
25688 coin.MarkSpent(txin.prevout.n);
25689 coin.WriteToDisk();
25690 vWalletUpdated.push_back(coin.GetHash());
25691 }
25692
25693 if (fFileBacked)
25694 delete pwalletdb;
25695 }
25696
25697 // Track how many getdata requests our transaction gets
25698 mapRequestCount[wtxNew.GetHash()] = 0;
25699
25700 // Broadcast
25701 if (!wtxNew.AcceptToMemoryPool())
25702 {
25703 // This must not fail. The transaction has already been signed and recorded.
25704 printf("CommitTransaction() : Error: Transaction not valid");
25705 return false;
25706 }
25707 wtxNew.RelayWalletTransaction();
25708 }
25709 MainFrameRepaint();
25710 return true;
25711 }
25712
25713
25714
25715
25716 string CWallet::SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee)
25717 {
25718 CReserveKey reservekey(this);
25719 int64 nFeeRequired;
25720
25721 if (IsLocked())
25722 {
25723 string strError = _("Error: Wallet locked, unable to create transaction ");
25724 printf("SendMoney() : %s", strError.c_str());
25725 return strError;
25726 }
25727 if (!CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired))
25728 {
25729 string strError;
25730 if (nValue + nFeeRequired > GetBalance())
25731 strError = strprintf(_("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds "), FormatMoney(nFeeRequired).c_str());
25732 else
25733 strError = _("Error: Transaction creation failed ");
25734 printf("SendMoney() : %s", strError.c_str());
25735 return strError;
25736 }
25737
25738 if (fAskFee && !ThreadSafeAskFee(nFeeRequired, _("Sending..."), NULL))
25739 return "ABORTED";
25740
25741 if (!CommitTransaction(wtxNew, reservekey))
25742 return _("Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.");
25743
25744 MainFrameRepaint();
25745 return "";
25746 }
25747
25748
25749
25750 string CWallet::SendMoneyToBitcoinAddress(const CBitcoinAddress& address, int64 nValue, CWalletTx& wtxNew, bool fAskFee)
25751 {
25752 // Check amount
25753 if (nValue <= 0)
25754 return _("Invalid amount");
25755 if (nValue + nTransactionFee > GetBalance())
25756 return _("Insufficient funds");
25757
25758 // Parse bitcoin address
25759 CScript scriptPubKey;
25760 scriptPubKey.SetBitcoinAddress(address);
25761
25762 return SendMoney(scriptPubKey, nValue, wtxNew, fAskFee);
25763 }
25764
25765
25766
25767
25768 int CWallet::LoadWallet(bool& fFirstRunRet)
25769 {
25770 if (!fFileBacked)
25771 return false;
25772 fFirstRunRet = false;
25773 int nLoadWalletRet = CWalletDB(strWalletFile,"cr+").LoadWallet(this);
25774 if (nLoadWalletRet == DB_NEED_REWRITE)
25775 {
25776 if (CDB::Rewrite(strWalletFile, "\x04pool"))
25777 {
25778 setKeyPool.clear();
25779 // Note: can't top-up keypool here, because wallet is locked.
25780 // User will be prompted to unlock wallet the next operation
25781 // the requires a new key.
25782 }
25783 nLoadWalletRet = DB_NEED_REWRITE;
25784 }
25785
25786 if (nLoadWalletRet != DB_LOAD_OK)
25787 return nLoadWalletRet;
25788 fFirstRunRet = vchDefaultKey.empty();
25789
25790 if (!HaveKey(Hash160(vchDefaultKey)))
25791 {
25792 // Create new keyUser and set as default key
25793 RandAddSeedPerfmon();
25794
25795 std::vector<unsigned char> newDefaultKey;
25796 if (!GetKeyFromPool(newDefaultKey, false))
25797 return DB_LOAD_FAIL;
25798 SetDefaultKey(newDefaultKey);
25799 if (!SetAddressBookName(CBitcoinAddress(vchDefaultKey), ""))
25800 return DB_LOAD_FAIL;
25801 }
25802
25803 CreateThread(ThreadFlushWalletDB, &strWalletFile);
25804 return DB_LOAD_OK;
25805 }
25806
25807
25808 bool CWallet::SetAddressBookName(const CBitcoinAddress& address, const string& strName)
25809 {
25810 mapAddressBook[address] = strName;
25811 if (!fFileBacked)
25812 return false;
25813 return CWalletDB(strWalletFile).WriteName(address.ToString(), strName);
25814 }
25815
25816 bool CWallet::DelAddressBookName(const CBitcoinAddress& address)
25817 {
25818 mapAddressBook.erase(address);
25819 if (!fFileBacked)
25820 return false;
25821 return CWalletDB(strWalletFile).EraseName(address.ToString());
25822 }
25823
25824
25825 void CWallet::PrintWallet(const CBlock& block)
25826 {
25827 CRITICAL_BLOCK(cs_wallet)
25828 {
25829 if (mapWallet.count(block.vtx[0].GetHash()))
25830 {
25831 CWalletTx& wtx = mapWallet[block.vtx[0].GetHash()];
25832 printf(" mine: %d %d %d", wtx.GetDepthInMainChain(), wtx.GetBlocksToMaturity(), wtx.GetCredit());
25833 }
25834 }
25835 printf("\n");
25836 }
25837
25838 bool CWallet::GetTransaction(const uint256 &hashTx, CWalletTx& wtx)
25839 {
25840 CRITICAL_BLOCK(cs_wallet)
25841 {
25842 map<uint256, CWalletTx>::iterator mi = mapWallet.find(hashTx);
25843 if (mi != mapWallet.end())
25844 {
25845 wtx = (*mi).second;
25846 return true;
25847 }
25848 }
25849 return false;
25850 }
25851
25852 bool CWallet::SetDefaultKey(const std::vector<unsigned char> &vchPubKey)
25853 {
25854 if (fFileBacked)
25855 {
25856 if (!CWalletDB(strWalletFile).WriteDefaultKey(vchPubKey))
25857 return false;
25858 }
25859 vchDefaultKey = vchPubKey;
25860 return true;
25861 }
25862
25863 bool GetWalletFile(CWallet* pwallet, string &strWalletFileOut)
25864 {
25865 if (!pwallet->fFileBacked)
25866 return false;
25867 strWalletFileOut = pwallet->strWalletFile;
25868 return true;
25869 }
25870
25871 //
25872 // Mark old keypool keys as used,
25873 // and generate all new keys
25874 //
25875 bool CWallet::NewKeyPool()
25876 {
25877 CRITICAL_BLOCK(cs_wallet)
25878 {
25879 CWalletDB walletdb(strWalletFile);
25880 BOOST_FOREACH(int64 nIndex, setKeyPool)
25881 walletdb.ErasePool(nIndex);
25882 setKeyPool.clear();
25883
25884 if (IsLocked())
25885 return false;
25886
25887 int64 nKeys = max(GetArg("-keypool", 100), (int64)0);
25888 for (int i = 0; i < nKeys; i++)
25889 {
25890 int64 nIndex = i+1;
25891 walletdb.WritePool(nIndex, CKeyPool(GenerateNewKey()));
25892 setKeyPool.insert(nIndex);
25893 }
25894 printf("CWallet::NewKeyPool wrote %"PRI64d" new keys\n", nKeys);
25895 }
25896 return true;
25897 }
25898
25899 bool CWallet::TopUpKeyPool()
25900 {
25901 CRITICAL_BLOCK(cs_wallet)
25902 {
25903 if (IsLocked())
25904 return false;
25905
25906 CWalletDB walletdb(strWalletFile);
25907
25908 // Top up key pool
25909 int64 nTargetSize = max(GetArg("-keypool", 100), (int64)0);
25910 while (setKeyPool.size() < nTargetSize+1)
25911 {
25912 int64 nEnd = 1;
25913 if (!setKeyPool.empty())
25914 nEnd = *(--setKeyPool.end()) + 1;
25915 if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey())))
25916 throw runtime_error("TopUpKeyPool() : writing generated key failed");
25917 setKeyPool.insert(nEnd);
25918 printf("keypool added key %"PRI64d", size=%d\n", nEnd, setKeyPool.size());
25919 }
25920 }
25921 return true;
25922 }
25923
25924 void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool)
25925 {
25926 nIndex = -1;
25927 keypool.vchPubKey.clear();
25928 CRITICAL_BLOCK(cs_wallet)
25929 {
25930 if (!IsLocked())
25931 TopUpKeyPool();
25932
25933 // Get the oldest key
25934 if(setKeyPool.empty())
25935 return;
25936
25937 CWalletDB walletdb(strWalletFile);
25938
25939 nIndex = *(setKeyPool.begin());
25940 setKeyPool.erase(setKeyPool.begin());
25941 if (!walletdb.ReadPool(nIndex, keypool))
25942 throw runtime_error("ReserveKeyFromKeyPool() : read failed");
25943 if (!HaveKey(Hash160(keypool.vchPubKey)))
25944 throw runtime_error("ReserveKeyFromKeyPool() : unknown key in key pool");
25945 assert(!keypool.vchPubKey.empty());
25946 printf("keypool reserve %"PRI64d"\n", nIndex);
25947 }
25948 }
25949
25950 void CWallet::KeepKey(int64 nIndex)
25951 {
25952 // Remove from key pool
25953 if (fFileBacked)
25954 {
25955 CWalletDB walletdb(strWalletFile);
25956 walletdb.ErasePool(nIndex);
25957 }
25958 printf("keypool keep %"PRI64d"\n", nIndex);
25959 }
25960
25961 void CWallet::ReturnKey(int64 nIndex)
25962 {
25963 // Return to key pool
25964 CRITICAL_BLOCK(cs_wallet)
25965 setKeyPool.insert(nIndex);
25966 printf("keypool return %"PRI64d"\n", nIndex);
25967 }
25968
25969 bool CWallet::GetKeyFromPool(vector<unsigned char>& result, bool fAllowReuse)
25970 {
25971 int64 nIndex = 0;
25972 CKeyPool keypool;
25973 CRITICAL_BLOCK(cs_wallet)
25974 {
25975 ReserveKeyFromKeyPool(nIndex, keypool);
25976 if (nIndex == -1)
25977 {
25978 if (fAllowReuse && !vchDefaultKey.empty())
25979 {
25980 result = vchDefaultKey;
25981 return true;
25982 }
25983 if (IsLocked()) return false;
25984 result = GenerateNewKey();
25985 return true;
25986 }
25987 KeepKey(nIndex);
25988 result = keypool.vchPubKey;
25989 }
25990 return true;
25991 }
25992
25993 int64 CWallet::GetOldestKeyPoolTime()
25994 {
25995 int64 nIndex = 0;
25996 CKeyPool keypool;
25997 ReserveKeyFromKeyPool(nIndex, keypool);
25998 if (nIndex == -1)
25999 return GetTime();
26000 ReturnKey(nIndex);
26001 return keypool.nTime;
26002 }
26003
26004 vector<unsigned char> CReserveKey::GetReservedKey()
26005 {
26006 if (nIndex == -1)
26007 {
26008 CKeyPool keypool;
26009 pwallet->ReserveKeyFromKeyPool(nIndex, keypool);
26010 if (nIndex != -1)
26011 vchPubKey = keypool.vchPubKey;
26012 else
26013 {
26014 printf("CReserveKey::GetReservedKey(): Warning: using default key instead of a new key, top up your keypool.");
26015 vchPubKey = pwallet->vchDefaultKey;
26016 }
26017 }
26018 assert(!vchPubKey.empty());
26019 return vchPubKey;
26020 }
26021
26022 void CReserveKey::KeepKey()
26023 {
26024 if (nIndex != -1)
26025 pwallet->KeepKey(nIndex);
26026 nIndex = -1;
26027 vchPubKey.clear();
26028 }
26029
26030 void CReserveKey::ReturnKey()
26031 {
26032 if (nIndex != -1)
26033 pwallet->ReturnKey(nIndex);
26034 nIndex = -1;
26035 vchPubKey.clear();
26036 }
26037
-
+ DF93B83C3880E14D890FE853D8556EEC6377B90D5E83BD696F4C5800042C2CD04C5242B69B8886E22DFCEB5B9B16E790FB526E9039CC130C9FB0F12CC8BB19D2
bitcoin/src/wallet.h
(0 . 0)(1 . 645)
26042 // Copyright (c) 2009-2010 Satoshi Nakamoto
26043 // Copyright (c) 2009-2012 The Bitcoin developers
26044 // Distributed under the MIT/X11 software license, see the accompanying
26045 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
26046 #ifndef BITCOIN_WALLET_H
26047 #define BITCOIN_WALLET_H
26048
26049 #include "bignum.h"
26050 #include "key.h"
26051 #include "script.h"
26052
26053 class CWalletTx;
26054 class CReserveKey;
26055 class CWalletDB;
26056
26057 // A CWallet is an extension of a keystore, which also maintains a set of
26058 // transactions and balances, and provides the ability to create new
26059 // transactions
26060 class CWallet : public CCryptoKeyStore
26061 {
26062 private:
26063 bool SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfTheirs, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const;
26064 bool SelectCoins(int64 nTargetValue, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const;
26065
26066 CWalletDB *pwalletdbEncryption;
26067
26068 public:
26069 mutable CCriticalSection cs_wallet;
26070
26071 bool fFileBacked;
26072 std::string strWalletFile;
26073
26074 std::set<int64> setKeyPool;
26075
26076 typedef std::map<unsigned int, CMasterKey> MasterKeyMap;
26077 MasterKeyMap mapMasterKeys;
26078 unsigned int nMasterKeyMaxID;
26079
26080 CWallet()
26081 {
26082 fFileBacked = false;
26083 nMasterKeyMaxID = 0;
26084 pwalletdbEncryption = NULL;
26085 }
26086 CWallet(std::string strWalletFileIn)
26087 {
26088 strWalletFile = strWalletFileIn;
26089 fFileBacked = true;
26090 nMasterKeyMaxID = 0;
26091 pwalletdbEncryption = NULL;
26092 }
26093
26094 std::map<uint256, CWalletTx> mapWallet;
26095 std::vector<uint256> vWalletUpdated;
26096
26097 std::map<uint256, int> mapRequestCount;
26098
26099 std::map<CBitcoinAddress, std::string> mapAddressBook;
26100
26101 std::vector<unsigned char> vchDefaultKey;
26102
26103 // keystore implementation
26104 // Adds a key to the store, and saves it to disk.
26105 bool AddKey(const CKey& key);
26106 // Adds a key to the store, without saving it to disk (used by LoadWallet)
26107 bool LoadKey(const CKey& key) { return CCryptoKeyStore::AddKey(key); }
26108
26109 // Adds an encrypted key to the store, and saves it to disk.
26110 bool AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
26111 // Adds an encrypted key to the store, without saving it to disk (used by LoadWallet)
26112 bool LoadCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret) { return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret); }
26113
26114 bool Unlock(const SecureString& strWalletPassphrase);
26115 bool ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase);
26116 bool EncryptWallet(const SecureString& strWalletPassphrase);
26117
26118 bool AddToWallet(const CWalletTx& wtxIn);
26119 bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate = false);
26120 bool EraseFromWallet(uint256 hash);
26121 void WalletUpdateSpent(const CTransaction& prevout);
26122 int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false);
26123 void ReacceptWalletTransactions();
26124 void ResendWalletTransactions();
26125 int64 GetBalance() const;
26126 int64 GetUnconfirmedBalance() const;
26127 bool CreateTransaction(const std::vector<std::pair<CScript, int64> >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet);
26128 bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet);
26129 bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey);
26130 std::string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
26131 std::string SendMoneyToBitcoinAddress(const CBitcoinAddress& address, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
26132
26133 bool NewKeyPool();
26134 bool TopUpKeyPool();
26135 void ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool);
26136 void KeepKey(int64 nIndex);
26137 void ReturnKey(int64 nIndex);
26138 bool GetKeyFromPool(std::vector<unsigned char> &key, bool fAllowReuse=true);
26139 int64 GetOldestKeyPoolTime();
26140
26141 bool IsMine(const CTxIn& txin) const;
26142 int64 GetDebit(const CTxIn& txin) const;
26143 bool IsMine(const CTxOut& txout) const
26144 {
26145 return ::IsMine(*this, txout.scriptPubKey);
26146 }
26147 int64 GetCredit(const CTxOut& txout) const
26148 {
26149 if (!MoneyRange(txout.nValue))
26150 throw std::runtime_error("CWallet::GetCredit() : value out of range");
26151 return (IsMine(txout) ? txout.nValue : 0);
26152 }
26153 bool IsChange(const CTxOut& txout) const
26154 {
26155 CBitcoinAddress address;
26156 if (ExtractAddress(txout.scriptPubKey, this, address))
26157 CRITICAL_BLOCK(cs_wallet)
26158 if (!mapAddressBook.count(address))
26159 return true;
26160 return false;
26161 }
26162 int64 GetChange(const CTxOut& txout) const
26163 {
26164 if (!MoneyRange(txout.nValue))
26165 throw std::runtime_error("CWallet::GetChange() : value out of range");
26166 return (IsChange(txout) ? txout.nValue : 0);
26167 }
26168 bool IsMine(const CTransaction& tx) const
26169 {
26170 BOOST_FOREACH(const CTxOut& txout, tx.vout)
26171 if (IsMine(txout))
26172 return true;
26173 return false;
26174 }
26175 bool IsFromMe(const CTransaction& tx) const
26176 {
26177 return (GetDebit(tx) > 0);
26178 }
26179 int64 GetDebit(const CTransaction& tx) const
26180 {
26181 int64 nDebit = 0;
26182 BOOST_FOREACH(const CTxIn& txin, tx.vin)
26183 {
26184 nDebit += GetDebit(txin);
26185 if (!MoneyRange(nDebit))
26186 throw std::runtime_error("CWallet::GetDebit() : value out of range");
26187 }
26188 return nDebit;
26189 }
26190 int64 GetCredit(const CTransaction& tx) const
26191 {
26192 int64 nCredit = 0;
26193 BOOST_FOREACH(const CTxOut& txout, tx.vout)
26194 {
26195 nCredit += GetCredit(txout);
26196 if (!MoneyRange(nCredit))
26197 throw std::runtime_error("CWallet::GetCredit() : value out of range");
26198 }
26199 return nCredit;
26200 }
26201 int64 GetChange(const CTransaction& tx) const
26202 {
26203 int64 nChange = 0;
26204 BOOST_FOREACH(const CTxOut& txout, tx.vout)
26205 {
26206 nChange += GetChange(txout);
26207 if (!MoneyRange(nChange))
26208 throw std::runtime_error("CWallet::GetChange() : value out of range");
26209 }
26210 return nChange;
26211 }
26212 void SetBestChain(const CBlockLocator& loc)
26213 {
26214 CWalletDB walletdb(strWalletFile);
26215 walletdb.WriteBestBlock(loc);
26216 }
26217
26218 int LoadWallet(bool& fFirstRunRet);
26219 // bool BackupWallet(const std::string& strDest);
26220
26221 bool SetAddressBookName(const CBitcoinAddress& address, const std::string& strName);
26222
26223 bool DelAddressBookName(const CBitcoinAddress& address);
26224
26225 void UpdatedTransaction(const uint256 &hashTx)
26226 {
26227 CRITICAL_BLOCK(cs_wallet)
26228 vWalletUpdated.push_back(hashTx);
26229 }
26230
26231 void PrintWallet(const CBlock& block);
26232
26233 void Inventory(const uint256 &hash)
26234 {
26235 CRITICAL_BLOCK(cs_wallet)
26236 {
26237 std::map<uint256, int>::iterator mi = mapRequestCount.find(hash);
26238 if (mi != mapRequestCount.end())
26239 (*mi).second++;
26240 }
26241 }
26242
26243 int GetKeyPoolSize()
26244 {
26245 return setKeyPool.size();
26246 }
26247
26248 bool GetTransaction(const uint256 &hashTx, CWalletTx& wtx);
26249
26250 bool SetDefaultKey(const std::vector<unsigned char> &vchPubKey);
26251 };
26252
26253
26254 class CReserveKey
26255 {
26256 protected:
26257 CWallet* pwallet;
26258 int64 nIndex;
26259 std::vector<unsigned char> vchPubKey;
26260 public:
26261 CReserveKey(CWallet* pwalletIn)
26262 {
26263 nIndex = -1;
26264 pwallet = pwalletIn;
26265 }
26266
26267 ~CReserveKey()
26268 {
26269 if (!fShutdown)
26270 ReturnKey();
26271 }
26272
26273 void ReturnKey();
26274 std::vector<unsigned char> GetReservedKey();
26275 void KeepKey();
26276 };
26277
26278
26279 //
26280 // A transaction with a bunch of additional info that only the owner cares
26281 // about. It includes any unrecorded transactions needed to link it back
26282 // to the block chain.
26283 //
26284 class CWalletTx : public CMerkleTx
26285 {
26286 public:
26287 const CWallet* pwallet;
26288
26289 std::vector<CMerkleTx> vtxPrev;
26290 std::map<std::string, std::string> mapValue;
26291 std::vector<std::pair<std::string, std::string> > vOrderForm;
26292 unsigned int fTimeReceivedIsTxTime;
26293 unsigned int nTimeReceived; // time received by this node
26294 char fFromMe;
26295 std::string strFromAccount;
26296 std::vector<char> vfSpent; // which outputs are already spent
26297
26298 // memory only
26299 mutable char fDebitCached;
26300 mutable char fCreditCached;
26301 mutable char fAvailableCreditCached;
26302 mutable char fChangeCached;
26303 mutable int64 nDebitCached;
26304 mutable int64 nCreditCached;
26305 mutable int64 nAvailableCreditCached;
26306 mutable int64 nChangeCached;
26307
26308 // memory only UI hints
26309 mutable unsigned int nTimeDisplayed;
26310 mutable int nLinesDisplayed;
26311 mutable char fConfirmedDisplayed;
26312
26313 CWalletTx()
26314 {
26315 Init(NULL);
26316 }
26317
26318 CWalletTx(const CWallet* pwalletIn)
26319 {
26320 Init(pwalletIn);
26321 }
26322
26323 CWalletTx(const CWallet* pwalletIn, const CMerkleTx& txIn) : CMerkleTx(txIn)
26324 {
26325 Init(pwalletIn);
26326 }
26327
26328 CWalletTx(const CWallet* pwalletIn, const CTransaction& txIn) : CMerkleTx(txIn)
26329 {
26330 Init(pwalletIn);
26331 }
26332
26333 void Init(const CWallet* pwalletIn)
26334 {
26335 pwallet = pwalletIn;
26336 vtxPrev.clear();
26337 mapValue.clear();
26338 vOrderForm.clear();
26339 fTimeReceivedIsTxTime = false;
26340 nTimeReceived = 0;
26341 fFromMe = false;
26342 strFromAccount.clear();
26343 vfSpent.clear();
26344 fDebitCached = false;
26345 fCreditCached = false;
26346 fAvailableCreditCached = false;
26347 fChangeCached = false;
26348 nDebitCached = 0;
26349 nCreditCached = 0;
26350 nAvailableCreditCached = 0;
26351 nChangeCached = 0;
26352 nTimeDisplayed = 0;
26353 nLinesDisplayed = 0;
26354 fConfirmedDisplayed = false;
26355 }
26356
26357 IMPLEMENT_SERIALIZE
26358 (
26359 CWalletTx* pthis = const_cast<CWalletTx*>(this);
26360 if (fRead)
26361 pthis->Init(NULL);
26362 char fSpent = false;
26363
26364 if (!fRead)
26365 {
26366 pthis->mapValue["fromaccount"] = pthis->strFromAccount;
26367
26368 std::string str;
26369 BOOST_FOREACH(char f, vfSpent)
26370 {
26371 str += (f ? '1' : '0');
26372 if (f)
26373 fSpent = true;
26374 }
26375 pthis->mapValue["spent"] = str;
26376 }
26377
26378 nSerSize += SerReadWrite(s, *(CMerkleTx*)this, nType, nVersion,ser_action);
26379 READWRITE(vtxPrev);
26380 READWRITE(mapValue);
26381 READWRITE(vOrderForm);
26382 READWRITE(fTimeReceivedIsTxTime);
26383 READWRITE(nTimeReceived);
26384 READWRITE(fFromMe);
26385 READWRITE(fSpent);
26386
26387 if (fRead)
26388 {
26389 pthis->strFromAccount = pthis->mapValue["fromaccount"];
26390
26391 if (mapValue.count("spent"))
26392 BOOST_FOREACH(char c, pthis->mapValue["spent"])
26393 pthis->vfSpent.push_back(c != '0');
26394 else
26395 pthis->vfSpent.assign(vout.size(), fSpent);
26396 }
26397
26398 pthis->mapValue.erase("fromaccount");
26399 pthis->mapValue.erase("version");
26400 pthis->mapValue.erase("spent");
26401 )
26402
26403 // marks certain txout's as spent
26404 // returns true if any update took place
26405 bool UpdateSpent(const std::vector<char>& vfNewSpent)
26406 {
26407 bool fReturn = false;
26408 for (int i=0; i < vfNewSpent.size(); i++)
26409 {
26410 if (i == vfSpent.size())
26411 break;
26412
26413 if (vfNewSpent[i] && !vfSpent[i])
26414 {
26415 vfSpent[i] = true;
26416 fReturn = true;
26417 fAvailableCreditCached = false;
26418 }
26419 }
26420 return fReturn;
26421 }
26422
26423 // make sure balances are recalculated
26424 void MarkDirty()
26425 {
26426 fCreditCached = false;
26427 fAvailableCreditCached = false;
26428 fDebitCached = false;
26429 fChangeCached = false;
26430 }
26431
26432 void MarkSpent(unsigned int nOut)
26433 {
26434 if (nOut >= vout.size())
26435 throw std::runtime_error("CWalletTx::MarkSpent() : nOut out of range");
26436 vfSpent.resize(vout.size());
26437 if (!vfSpent[nOut])
26438 {
26439 vfSpent[nOut] = true;
26440 fAvailableCreditCached = false;
26441 }
26442 }
26443
26444 bool IsSpent(unsigned int nOut) const
26445 {
26446 if (nOut >= vout.size())
26447 throw std::runtime_error("CWalletTx::IsSpent() : nOut out of range");
26448 if (nOut >= vfSpent.size())
26449 return false;
26450 return (!!vfSpent[nOut]);
26451 }
26452
26453 int64 GetDebit() const
26454 {
26455 if (vin.empty())
26456 return 0;
26457 if (fDebitCached)
26458 return nDebitCached;
26459 nDebitCached = pwallet->GetDebit(*this);
26460 fDebitCached = true;
26461 return nDebitCached;
26462 }
26463
26464 int64 GetCredit(bool fUseCache=true) const
26465 {
26466 // Must wait until coinbase is safely deep enough in the chain before valuing it
26467 if (IsCoinBase() && GetBlocksToMaturity() > 0)
26468 return 0;
26469
26470 // GetBalance can assume transactions in mapWallet won't change
26471 if (fUseCache && fCreditCached)
26472 return nCreditCached;
26473 nCreditCached = pwallet->GetCredit(*this);
26474 fCreditCached = true;
26475 return nCreditCached;
26476 }
26477
26478 int64 GetAvailableCredit(bool fUseCache=true) const
26479 {
26480 // Must wait until coinbase is safely deep enough in the chain before valuing it
26481 if (IsCoinBase() && GetBlocksToMaturity() > 0)
26482 return 0;
26483
26484 if (fUseCache && fAvailableCreditCached)
26485 return nAvailableCreditCached;
26486
26487 int64 nCredit = 0;
26488 for (int i = 0; i < vout.size(); i++)
26489 {
26490 if (!IsSpent(i))
26491 {
26492 const CTxOut &txout = vout[i];
26493 nCredit += pwallet->GetCredit(txout);
26494 if (!MoneyRange(nCredit))
26495 throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
26496 }
26497 }
26498
26499 nAvailableCreditCached = nCredit;
26500 fAvailableCreditCached = true;
26501 return nCredit;
26502 }
26503
26504
26505 int64 GetChange() const
26506 {
26507 if (fChangeCached)
26508 return nChangeCached;
26509 nChangeCached = pwallet->GetChange(*this);
26510 fChangeCached = true;
26511 return nChangeCached;
26512 }
26513
26514 void GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, std::list<std::pair<CBitcoinAddress, int64> >& listReceived,
26515 std::list<std::pair<CBitcoinAddress, int64> >& listSent, int64& nFee, std::string& strSentAccount) const;
26516
26517 void GetAccountAmounts(const std::string& strAccount, int64& nGenerated, int64& nReceived,
26518 int64& nSent, int64& nFee) const;
26519
26520 bool IsFromMe() const
26521 {
26522 return (GetDebit() > 0);
26523 }
26524
26525 bool IsConfirmed() const
26526 {
26527 // Quick answer in most cases
26528 if (!IsFinal())
26529 return false;
26530 if (GetDepthInMainChain() >= 1)
26531 return true;
26532 if (!IsFromMe()) // using wtx's cached debit
26533 return false;
26534
26535 // If no confirmations but it's from us, we can still
26536 // consider it confirmed if all dependencies are confirmed
26537 std::map<uint256, const CMerkleTx*> mapPrev;
26538 std::vector<const CMerkleTx*> vWorkQueue;
26539 vWorkQueue.reserve(vtxPrev.size()+1);
26540 vWorkQueue.push_back(this);
26541 for (int i = 0; i < vWorkQueue.size(); i++)
26542 {
26543 const CMerkleTx* ptx = vWorkQueue[i];
26544
26545 if (!ptx->IsFinal())
26546 return false;
26547 if (ptx->GetDepthInMainChain() >= 1)
26548 continue;
26549 if (!pwallet->IsFromMe(*ptx))
26550 return false;
26551
26552 if (mapPrev.empty())
26553 BOOST_FOREACH(const CMerkleTx& tx, vtxPrev)
26554 mapPrev[tx.GetHash()] = &tx;
26555
26556 BOOST_FOREACH(const CTxIn& txin, ptx->vin)
26557 {
26558 if (!mapPrev.count(txin.prevout.hash))
26559 return false;
26560 vWorkQueue.push_back(mapPrev[txin.prevout.hash]);
26561 }
26562 }
26563 return true;
26564 }
26565
26566 bool WriteToDisk();
26567
26568 int64 GetTxTime() const;
26569 int GetRequestCount() const;
26570
26571 void AddSupportingTransactions(CTxDB& txdb);
26572
26573 bool AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs=true);
26574 bool AcceptWalletTransaction();
26575
26576 void RelayWalletTransaction(CTxDB& txdb);
26577 void RelayWalletTransaction();
26578 };
26579
26580
26581 //
26582 // Private key that includes an expiration date in case it never gets used.
26583 //
26584 class CWalletKey
26585 {
26586 public:
26587 CPrivKey vchPrivKey;
26588 int64 nTimeCreated;
26589 int64 nTimeExpires;
26590 std::string strComment;
26591 //// todo: add something to note what created it (user, getnewaddress, change)
26592 //// maybe should have a map<string, string> property map
26593
26594 CWalletKey(int64 nExpires=0)
26595 {
26596 nTimeCreated = (nExpires ? GetTime() : 0);
26597 nTimeExpires = nExpires;
26598 }
26599
26600 IMPLEMENT_SERIALIZE
26601 (
26602 if (!(nType & SER_GETHASH))
26603 READWRITE(nVersion);
26604 READWRITE(vchPrivKey);
26605 READWRITE(nTimeCreated);
26606 READWRITE(nTimeExpires);
26607 READWRITE(strComment);
26608 )
26609 };
26610
26611
26612
26613
26614
26615
26616 //
26617 // Account information.
26618 // Stored in wallet with key "acc"+string account name
26619 //
26620 class CAccount
26621 {
26622 public:
26623 std::vector<unsigned char> vchPubKey;
26624
26625 CAccount()
26626 {
26627 SetNull();
26628 }
26629
26630 void SetNull()
26631 {
26632 vchPubKey.clear();
26633 }
26634
26635 IMPLEMENT_SERIALIZE
26636 (
26637 if (!(nType & SER_GETHASH))
26638 READWRITE(nVersion);
26639 READWRITE(vchPubKey);
26640 )
26641 };
26642
26643
26644
26645 //
26646 // Internal transfers.
26647 // Database key is acentry<account><counter>
26648 //
26649 class CAccountingEntry
26650 {
26651 public:
26652 std::string strAccount;
26653 int64 nCreditDebit;
26654 int64 nTime;
26655 std::string strOtherAccount;
26656 std::string strComment;
26657
26658 CAccountingEntry()
26659 {
26660 SetNull();
26661 }
26662
26663 void SetNull()
26664 {
26665 nCreditDebit = 0;
26666 nTime = 0;
26667 strAccount.clear();
26668 strOtherAccount.clear();
26669 strComment.clear();
26670 }
26671
26672 IMPLEMENT_SERIALIZE
26673 (
26674 if (!(nType & SER_GETHASH))
26675 READWRITE(nVersion);
26676 // Note: strAccount is serialized as part of the key, not here.
26677 READWRITE(nCreditDebit);
26678 READWRITE(nTime);
26679 READWRITE(strOtherAccount);
26680 READWRITE(strComment);
26681 )
26682 };
26683
26684 bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut);
26685
26686 #endif