tree checksum vpatch file split hunks

all signers: asciilifeform ben_vulpes mircea_popescu mod6 trinque

antecedents:

press order:

genesisasciilifeform ben_vulpes mircea_popescu mod6 trinque

patch:

-
+ 9A57FBA56BDAF8AC851E2A336013F03F354005DEE6F12F6D472882B284DD5CDAE09D0F57729D877C0CF7DFEE0F8BEA8B602492860AE703F3F5934DE15C7514AE
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
-
+ E7F37A4EEA93D09CDCFDD669A97F7A1AD3C1C96395F9517B33B396AF03292FE97F27F630DF1EC1D261FCF396E0E2D31F0DED4F50D5181046A0609A4EF0D71450
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.
-
+ 14321C5769EB37D637E2C911F668EDBE20D8B712494EA585D8201345D690B6E82341E2F0C6C4572013CA24208E077C05F0A82A4096017083B2BE9709F37498AB
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
-
+ 81F78BDA68EBE0A6A4F5C0BEA8C7C091E6056850BDD7CBB8DD68D9CB3E8662BEB143668BA5C3F089D9B4AE32875FCA6CB1CFBFFFB02865812BA3222CE2FE6778
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
-
+ A1812AC4E4425986E8574EBF837C6B1A84E4772E01B46E4E1CAEF098496226F7321A3FABC5249B55CE6365863F2C25FEF0005F4BCDE7188603B0805C77256BC0
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
-
+ 59CBCD0388F17CF7C4EA6C69C4034A0CED5C05D1D9AB22A1AAAE0AF7B95C3D3245657A049110A45AD9DD66F41A793082CAAB6A8A79441B93FCBFA4B4CE44574D
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[]);
-
+ 0B7CA89FD0A4045EF9553FF439C4FD39DDDD92069CA97B29DECBC31D2F96A004E0015B453DBF4C4669555ED997FFD02F1066C43F346FEB8CD0ADE0B80772E863
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 }
-
+ 8BD5D4BB576D5755203BC207138E556266BA6015D0F673BCD6D94B3272291BD637F019849CAEE47B6AE64E412439974D1409EC14C784DD430C88F252F856F266
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
-
+ 64DDDC1348603EA005F4F5297EA6D51074FEAD3DD8D1256C1A4C2A678FEF1ABCB58D148EBB9EB3716E200E27ABF6D07C19D1CF6FCBB4E1B9DCBA59FDE8EAE324
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 }
-
+ 03B2BADB8A68951E41FDDEA52AA38E5FB3838F1C7F6A9EB7C7297A32455176FA1F75DF422DD6A9E41E8E75D61D368D5EF62CC7E558F4D4C32E3CB437A685BE2A
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
-
+ 6C7B584C387898CEEE4C76D4BC56D7400105807885B5B497089F99849E04F57A2E5C775B206765F5900C3C83967C6E2A0100DAB71F314B1D28B01CAAA67667CC
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 }
-
+ 1A4B9BD666180ACF944D189FFD5B89DA0F1C0D7B60223FE7F16F73A7D90BDD2A75B7D46805738EA3DA36AE766B0AA4A5D29283B5F4EF8A77AAE991CF990AE0CC
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
-
+ BAC815C59CD69F09371CBC605C3365056B02529D4FC0CD68026B6DC0304F12DAFCDA86479F52191F20F14B87C56006306E362020BA7A0651CCE2BDA87DB547AC
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
-
+ 9EA336B2061C743C7F9FD590A02546616D8E3FD0DEE8C9A15BB9A24E8E6138FB48F9B9BE4B7452CE1E0EB4E69E8882D2B5F03EF2D6D0B50FDB9E0A869719ECFC
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 }
-
+ B98A9164BEFDEA031D670D65EDDF8DDA79AA277E71114390B0F83CCEFCF580D078B1B85BEF27006BA4C429488EB26316F156023C33BF037B82A3283F8FFC3E83
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
-
+ FC9388561AE8AF72AB6F10816CACD133746DE668B500BAE02C239B129DC5E190794A94D7569B7ECBD294844BFE3C2A3A2B5C4E2A0A5F3AA3170DA498A8D0724B
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
-
+ 960A1A96AABF8154DFE3619E5198F52CADC493D949CE647CBA3DC4CBC69AB03C392F54C71F03A8E2D11070966D35A33EB7FEA096D3799439D9583D32D0664E10
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
-
+ 881A2AEBB27224D7B4101B97BAD2B6DCCD833968F2C7BFB5D3B9C06EC0A4F6B68AB10111CA247F1DA024F475FB23AB3E96DC5B50226EC5DF4DAE75F0B98BA71C
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.
-
+ 1499B4CBDAE705DFB050F0376961BC5CF0994199F995FBAFB37EDAE20F92BB8FCA802627991ACDC7216339981B9E00262782D5F59A30403E41769756AEF2BA6A
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
-
+ 54363E1ADE4F6518FBEC710EEC2C62DB4D1DE18B812B8CDC8059946602F98FFEDF47A92444225F8AEC3967B86453F984FD1BC6890C41BFBED4B7E2D625CD826A
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
-
+ 78609CF3F6735E920DC08E5B1FF0139B675256471F95ACA9659066DB7163A264F005128CF7E1BE38D34B3828AB313E125A29BA20FA2DB69762E22E952A506D93
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
-
+ 28F2D586E50555E9C1C86F6D9CC39288C49DE44F90B81793194F6D3AF2BB53FE64D8D360E418A50DE4D1AD91A02B4B464658847BC343EA5A45D96D5AF7628D79
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
-
+ 2030127C7941B905D7C30163B0333C87B8A517B897113CA6E1564B0FC9A0FC81EF9D973814DDFFE2A5BEA0F7C0CA0C0BDB43CC035D9587B9147BA6B73C8A6138
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
-
+ B1E6947F1078775D2B3A0BCC3BBA32679012E21A25E47CA6558C43B254FD2B5763E19DCE5C47D7D3C4B5D9D8A162D136774F37B6936EA12B91822902664761B2
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
-
+ 349F1AEF927DA56CA3C7ABF019B5BAA230698047CDB2786C812F2F202D7F5D7831453681775D528052A9BC9FCD3182D18885FAE8E8CA57F6E69151AA0D17267E
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
-
+ C8DA4081AFDDCE1A03290639B288BB0C9EE55447AA5B3DFACBDA7A6F1C3B2DD1758126D498E08485CBE877222A211E7AF8E0169C17170854838E8A2406D67DBF
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"
-
+ C2BCDC1E04F52791173BCD0AF2C7CFE63B6953BA108B2590F98DF767899CA15616C984FEBC4A9076720586B254D256B8A1C023DD5431DD88DF939F9519BAF18F
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
-
+ 849C5978099870A2432E75AD7F5CCA8C95C6C348CA2F59FC5AF2BCE1FE162F1E0F9E54230B090CD0A25280B44DD06A94F8E3D607FE253916AF080D0E9732909D
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
-
+ 9F6723BD7D02F878BDBF7F1F62E124FCFA1954E26969B99A1295918E2CC822B72B6E3856F4F9A6A806FBF547606D0BC9A1D1C4726B70212D5D445E24BE456707
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
-
+ 786A2FF2F1887F12494A318DA01915B682D5B0059BBE0D3FDEFC538C911883DA54E0A111D2FBF962914C62FDA8CAAF01613CFAEE8FB7FE74F61754D11D4F53B4
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
-
+ 6B2389129DEC411D013D754EAEBC169A23F60B2169DC41CCED21248A603CED46DFDC64E016C082A154AF87784049333BE75C91FB08265306A3BDC2BC0AF2E6C5
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;