genesis 1
genesis 2
genesis 3
genesis 4
genesis 5 #ifndef BITCOIN_MAIN_H
genesis 6 #define BITCOIN_MAIN_H
genesis 7
genesis 8 #include "bignum.h"
genesis 9 #include "net.h"
genesis 10 #include "key.h"
genesis 11 #include "script.h"
genesis 12 #include "db.h"
genesis 13
genesis 14 #include <list>
genesis 15
genesis 16 class CBlock;
genesis 17 class CBlockIndex;
genesis 18 class CWalletTx;
genesis 19 class CWallet;
genesis 20 class CKeyItem;
genesis 21 class CReserveKey;
genesis 22 class CWalletDB;
genesis 23
genesis 24 class CAddress;
genesis 25 class CInv;
genesis 26 class CRequestTracker;
genesis 27 class CNode;
genesis 28 class CBlockIndex;
genesis 29
genesis 30 static const unsigned int MAX_BLOCK_SIZE = 1000000;
genesis 31 static const unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE/2;
genesis 32 static const int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
genesis 33 static const int64 COIN = 100000000;
genesis 34 static const int64 CENT = 1000000;
genesis 35 static const int64 MIN_TX_FEE = 50000;
genesis 36 static const int64 MIN_RELAY_TX_FEE = 10000;
genesis 37 static const int64 MAX_MONEY = 21000000 * COIN;
genesis 38 inline bool MoneyRange(int64 nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); }
genesis 39 static const int COINBASE_MATURITY = 100;
genesis 40
genesis 41 static const int LOCKTIME_THRESHOLD = 500000000;
genesis 42
genesis 43
genesis 44
genesis 45
genesis 46
genesis 47
genesis 48 extern CCriticalSection cs_main;
genesis 49 extern std::map<uint256, CBlockIndex*> mapBlockIndex;
genesis 50 extern uint256 hashGenesisBlock;
genesis 51 extern CBlockIndex* pindexGenesisBlock;
genesis 52 extern int nBestHeight;
genesis 53 extern CBigNum bnBestChainWork;
genesis 54 extern CBigNum bnBestInvalidWork;
genesis 55 extern uint256 hashBestChain;
genesis 56 extern CBlockIndex* pindexBest;
genesis 57 extern unsigned int nTransactionsUpdated;
genesis 58 extern double dHashesPerSec;
genesis 59 extern int64 nHPSTimerStart;
genesis 60 extern int64 nTimeBestReceived;
genesis 61 extern CCriticalSection cs_setpwalletRegistered;
genesis 62 extern std::set<CWallet*> setpwalletRegistered;
genesis 63
genesis 64
genesis 65 extern int fGenerateBitcoins;
genesis 66 extern int64 nTransactionFee;
genesis 67 extern int fLimitProcessors;
genesis 68 extern int nLimitProcessors;
genesis 69 extern int fMinimizeToTray;
genesis 70 extern int fMinimizeOnClose;
genesis 71
genesis 72
genesis 73
genesis 74
genesis 75
genesis 76 class CReserveKey;
genesis 77 class CTxDB;
genesis 78 class CTxIndex;
genesis 79
genesis 80 void RegisterWallet(CWallet* pwalletIn);
genesis 81 void UnregisterWallet(CWallet* pwalletIn);
genesis 82 bool ProcessBlock(CNode* pfrom, CBlock* pblock);
genesis 83 bool CheckDiskSpace(uint64 nAdditionalBytes=0);
genesis 84 FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb");
genesis 85 FILE* AppendBlockFile(unsigned int& nFileRet);
genesis 86 bool LoadBlockIndex(bool fAllowNew=true);
genesis 87 void PrintBlockTree();
genesis 88 bool ProcessMessages(CNode* pfrom);
genesis 89 bool SendMessages(CNode* pto, bool fSendTrickle);
genesis 90 void GenerateBitcoins(bool fGenerate, CWallet* pwallet);
genesis 91 CBlock* CreateNewBlock(CReserveKey& reservekey);
genesis 92 void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
genesis 93 void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1);
genesis 94 bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey);
genesis 95 bool CheckProofOfWork(uint256 hash, unsigned int nBits);
genesis 96 unsigned int ComputeMinWork(unsigned int nBase, int64 nTime);
genesis 97 int GetNumBlocksOfPeers();
genesis 98 bool IsInitialBlockDownload();
genesis 99 std::string GetWarnings(std::string strFor);
genesis 100
genesis 101
genesis 102
genesis 103
genesis 104
genesis 105
genesis 106
genesis 107
genesis 108
genesis 109
genesis 110
genesis 111
genesis 112 bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut);
genesis 113
genesis 114 template<typename T>
genesis 115 bool WriteSetting(const std::string& strKey, const T& value)
genesis 116 {
genesis 117 bool fOk = false;
genesis 118 BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
genesis 119 {
genesis 120 std::string strWalletFile;
genesis 121 if (!GetWalletFile(pwallet, strWalletFile))
genesis 122 continue;
genesis 123 fOk |= CWalletDB(strWalletFile).WriteSetting(strKey, value);
genesis 124 }
genesis 125 return fOk;
genesis 126 }
genesis 127
genesis 128
genesis 129 class CDiskTxPos
genesis 130 {
genesis 131 public:
genesis 132 unsigned int nFile;
genesis 133 unsigned int nBlockPos;
genesis 134 unsigned int nTxPos;
genesis 135
genesis 136 CDiskTxPos()
genesis 137 {
genesis 138 SetNull();
genesis 139 }
genesis 140
genesis 141 CDiskTxPos(unsigned int nFileIn, unsigned int nBlockPosIn, unsigned int nTxPosIn)
genesis 142 {
genesis 143 nFile = nFileIn;
genesis 144 nBlockPos = nBlockPosIn;
genesis 145 nTxPos = nTxPosIn;
genesis 146 }
genesis 147
genesis 148 IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); )
genesis 149 void SetNull() { nFile = -1; nBlockPos = 0; nTxPos = 0; }
genesis 150 bool IsNull() const { return (nFile == -1); }
genesis 151
genesis 152 friend bool operator==(const CDiskTxPos& a, const CDiskTxPos& b)
genesis 153 {
genesis 154 return (a.nFile == b.nFile &&
genesis 155 a.nBlockPos == b.nBlockPos &&
genesis 156 a.nTxPos == b.nTxPos);
genesis 157 }
genesis 158
genesis 159 friend bool operator!=(const CDiskTxPos& a, const CDiskTxPos& b)
genesis 160 {
genesis 161 return !(a == b);
genesis 162 }
genesis 163
genesis 164 std::string ToString() const
genesis 165 {
genesis 166 if (IsNull())
genesis 167 return strprintf("null");
genesis 168 else
genesis 169 return strprintf("(nFile=%d, nBlockPos=%d, nTxPos=%d)", nFile, nBlockPos, nTxPos);
genesis 170 }
genesis 171
genesis 172 void print() const
genesis 173 {
genesis 174 printf("%s", ToString().c_str());
genesis 175 }
genesis 176 };
genesis 177
genesis 178
genesis 179
genesis 180
genesis 181 class CInPoint
genesis 182 {
genesis 183 public:
genesis 184 CTransaction* ptx;
genesis 185 unsigned int n;
genesis 186
genesis 187 CInPoint() { SetNull(); }
genesis 188 CInPoint(CTransaction* ptxIn, unsigned int nIn) { ptx = ptxIn; n = nIn; }
genesis 189 void SetNull() { ptx = NULL; n = -1; }
genesis 190 bool IsNull() const { return (ptx == NULL && n == -1); }
genesis 191 };
genesis 192
genesis 193
genesis 194
genesis 195
genesis 196 class COutPoint
genesis 197 {
genesis 198 public:
genesis 199 uint256 hash;
genesis 200 unsigned int n;
genesis 201
genesis 202 COutPoint() { SetNull(); }
genesis 203 COutPoint(uint256 hashIn, unsigned int nIn) { hash = hashIn; n = nIn; }
genesis 204 IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); )
genesis 205 void SetNull() { hash = 0; n = -1; }
genesis 206 bool IsNull() const { return (hash == 0 && n == -1); }
genesis 207
genesis 208 friend bool operator<(const COutPoint& a, const COutPoint& b)
genesis 209 {
genesis 210 return (a.hash < b.hash || (a.hash == b.hash && a.n < b.n));
genesis 211 }
genesis 212
genesis 213 friend bool operator==(const COutPoint& a, const COutPoint& b)
genesis 214 {
genesis 215 return (a.hash == b.hash && a.n == b.n);
genesis 216 }
genesis 217
genesis 218 friend bool operator!=(const COutPoint& a, const COutPoint& b)
genesis 219 {
genesis 220 return !(a == b);
genesis 221 }
genesis 222
genesis 223 std::string ToString() const
genesis 224 {
genesis 225 return strprintf("COutPoint(%s, %d)", hash.ToString().substr(0,10).c_str(), n);
genesis 226 }
genesis 227
genesis 228 void print() const
genesis 229 {
genesis 230 printf("%s\n", ToString().c_str());
genesis 231 }
genesis 232 };
genesis 233
genesis 234
genesis 235
genesis 236
genesis 237
genesis 238
genesis 239
genesis 240
genesis 241
genesis 242 class CTxIn
genesis 243 {
genesis 244 public:
genesis 245 COutPoint prevout;
genesis 246 CScript scriptSig;
genesis 247 unsigned int nSequence;
genesis 248
genesis 249 CTxIn()
genesis 250 {
genesis 251 nSequence = UINT_MAX;
genesis 252 }
genesis 253
genesis 254 explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX)
genesis 255 {
genesis 256 prevout = prevoutIn;
genesis 257 scriptSig = scriptSigIn;
genesis 258 nSequence = nSequenceIn;
genesis 259 }
genesis 260
genesis 261 CTxIn(uint256 hashPrevTx, unsigned int nOut, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX)
genesis 262 {
genesis 263 prevout = COutPoint(hashPrevTx, nOut);
genesis 264 scriptSig = scriptSigIn;
genesis 265 nSequence = nSequenceIn;
genesis 266 }
genesis 267
genesis 268 IMPLEMENT_SERIALIZE
genesis 269 (
genesis 270 READWRITE(prevout);
genesis 271 READWRITE(scriptSig);
genesis 272 READWRITE(nSequence);
genesis 273 )
genesis 274
genesis 275 bool IsFinal() const
genesis 276 {
genesis 277 return (nSequence == UINT_MAX);
genesis 278 }
genesis 279
genesis 280 friend bool operator==(const CTxIn& a, const CTxIn& b)
genesis 281 {
genesis 282 return (a.prevout == b.prevout &&
genesis 283 a.scriptSig == b.scriptSig &&
genesis 284 a.nSequence == b.nSequence);
genesis 285 }
genesis 286
genesis 287 friend bool operator!=(const CTxIn& a, const CTxIn& b)
genesis 288 {
genesis 289 return !(a == b);
genesis 290 }
genesis 291
genesis 292 std::string ToString() const
genesis 293 {
genesis 294 std::string str;
genesis 295 str += strprintf("CTxIn(");
genesis 296 str += prevout.ToString();
genesis 297 if (prevout.IsNull())
genesis 298 str += strprintf(", coinbase %s", HexStr(scriptSig).c_str());
genesis 299 else
genesis 300 str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24).c_str());
genesis 301 if (nSequence != UINT_MAX)
genesis 302 str += strprintf(", nSequence=%u", nSequence);
genesis 303 str += ")";
genesis 304 return str;
genesis 305 }
genesis 306
genesis 307 void print() const
genesis 308 {
genesis 309 printf("%s\n", ToString().c_str());
genesis 310 }
genesis 311 };
genesis 312
genesis 313
genesis 314
genesis 315
genesis 316
genesis 317
genesis 318
genesis 319
genesis 320 class CTxOut
genesis 321 {
genesis 322 public:
genesis 323 int64 nValue;
genesis 324 CScript scriptPubKey;
genesis 325
genesis 326 CTxOut()
genesis 327 {
genesis 328 SetNull();
genesis 329 }
genesis 330
genesis 331 CTxOut(int64 nValueIn, CScript scriptPubKeyIn)
genesis 332 {
genesis 333 nValue = nValueIn;
genesis 334 scriptPubKey = scriptPubKeyIn;
genesis 335 }
genesis 336
genesis 337 IMPLEMENT_SERIALIZE
genesis 338 (
genesis 339 READWRITE(nValue);
genesis 340 READWRITE(scriptPubKey);
genesis 341 )
genesis 342
genesis 343 void SetNull()
genesis 344 {
genesis 345 nValue = -1;
genesis 346 scriptPubKey.clear();
genesis 347 }
genesis 348
genesis 349 bool IsNull()
genesis 350 {
genesis 351 return (nValue == -1);
genesis 352 }
genesis 353
genesis 354 uint256 GetHash() const
genesis 355 {
genesis 356 return SerializeHash(*this);
genesis 357 }
genesis 358
genesis 359 friend bool operator==(const CTxOut& a, const CTxOut& b)
genesis 360 {
genesis 361 return (a.nValue == b.nValue &&
genesis 362 a.scriptPubKey == b.scriptPubKey);
genesis 363 }
genesis 364
genesis 365 friend bool operator!=(const CTxOut& a, const CTxOut& b)
genesis 366 {
genesis 367 return !(a == b);
genesis 368 }
genesis 369
genesis 370 std::string ToString() const
genesis 371 {
genesis 372 if (scriptPubKey.size() < 6)
genesis 373 return "CTxOut(error)";
genesis 374 return strprintf("CTxOut(nValue=%"PRI64d".%08"PRI64d", scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,30).c_str());
genesis 375 }
genesis 376
genesis 377 void print() const
genesis 378 {
genesis 379 printf("%s\n", ToString().c_str());
genesis 380 }
genesis 381 };
genesis 382
genesis 383
genesis 384
genesis 385
genesis 386
genesis 387
genesis 388
genesis 389
genesis 390 class CTransaction
genesis 391 {
genesis 392 public:
genesis 393 int nVersion;
genesis 394 std::vector<CTxIn> vin;
genesis 395 std::vector<CTxOut> vout;
genesis 396 unsigned int nLockTime;
genesis 397
genesis 398
genesis 399 mutable int nDoS;
genesis 400 bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; }
genesis 401
genesis 402 CTransaction()
genesis 403 {
genesis 404 SetNull();
genesis 405 }
genesis 406
genesis 407 IMPLEMENT_SERIALIZE
genesis 408 (
genesis 409 READWRITE(this->nVersion);
genesis 410 nVersion = this->nVersion;
genesis 411 READWRITE(vin);
genesis 412 READWRITE(vout);
genesis 413 READWRITE(nLockTime);
genesis 414 )
genesis 415
genesis 416 void SetNull()
genesis 417 {
genesis 418 nVersion = 1;
genesis 419 vin.clear();
genesis 420 vout.clear();
genesis 421 nLockTime = 0;
genesis 422 nDoS = 0;
genesis 423 }
genesis 424
genesis 425 bool IsNull() const
genesis 426 {
genesis 427 return (vin.empty() && vout.empty());
genesis 428 }
genesis 429
genesis 430 uint256 GetHash() const
genesis 431 {
genesis 432 return SerializeHash(*this);
genesis 433 }
genesis 434
genesis 435 bool IsFinal(int nBlockHeight=0, int64 nBlockTime=0) const
genesis 436 {
genesis 437
genesis 438 if (nLockTime == 0)
genesis 439 return true;
genesis 440 if (nBlockHeight == 0)
genesis 441 nBlockHeight = nBestHeight;
genesis 442 if (nBlockTime == 0)
genesis 443 nBlockTime = GetAdjustedTime();
genesis 444 if ((int64)nLockTime < (nLockTime < LOCKTIME_THRESHOLD ? (int64)nBlockHeight : nBlockTime))
genesis 445 return true;
genesis 446 BOOST_FOREACH(const CTxIn& txin, vin)
genesis 447 if (!txin.IsFinal())
genesis 448 return false;
genesis 449 return true;
genesis 450 }
genesis 451
genesis 452 bool IsNewerThan(const CTransaction& old) const
genesis 453 {
genesis 454 if (vin.size() != old.vin.size())
genesis 455 return false;
genesis 456 for (int i = 0; i < vin.size(); i++)
genesis 457 if (vin[i].prevout != old.vin[i].prevout)
genesis 458 return false;
genesis 459
genesis 460 bool fNewer = false;
genesis 461 unsigned int nLowest = UINT_MAX;
genesis 462 for (int i = 0; i < vin.size(); i++)
genesis 463 {
genesis 464 if (vin[i].nSequence != old.vin[i].nSequence)
genesis 465 {
genesis 466 if (vin[i].nSequence <= nLowest)
genesis 467 {
genesis 468 fNewer = false;
genesis 469 nLowest = vin[i].nSequence;
genesis 470 }
genesis 471 if (old.vin[i].nSequence < nLowest)
genesis 472 {
genesis 473 fNewer = true;
genesis 474 nLowest = old.vin[i].nSequence;
genesis 475 }
genesis 476 }
genesis 477 }
genesis 478 return fNewer;
genesis 479 }
genesis 480
genesis 481 bool IsCoinBase() const
genesis 482 {
genesis 483 return (vin.size() == 1 && vin[0].prevout.IsNull());
genesis 484 }
genesis 485
genesis 486 int GetSigOpCount() const
genesis 487 {
genesis 488 int n = 0;
genesis 489 BOOST_FOREACH(const CTxIn& txin, vin)
genesis 490 n += txin.scriptSig.GetSigOpCount();
genesis 491 BOOST_FOREACH(const CTxOut& txout, vout)
genesis 492 n += txout.scriptPubKey.GetSigOpCount();
genesis 493 return n;
genesis 494 }
genesis 495
genesis 496 bool IsStandard() const
genesis 497 {
genesis 498 BOOST_FOREACH(const CTxIn& txin, vin)
genesis 499 if (!txin.scriptSig.IsPushOnly())
genesis 500 return error("nonstandard txin: %s", txin.scriptSig.ToString().c_str());
genesis 501 BOOST_FOREACH(const CTxOut& txout, vout)
genesis 502 if (!::IsStandard(txout.scriptPubKey))
genesis 503 return error("nonstandard txout: %s", txout.scriptPubKey.ToString().c_str());
genesis 504 return true;
genesis 505 }
genesis 506
genesis 507 int64 GetValueOut() const
genesis 508 {
genesis 509 int64 nValueOut = 0;
genesis 510 BOOST_FOREACH(const CTxOut& txout, vout)
genesis 511 {
genesis 512 nValueOut += txout.nValue;
genesis 513 if (!MoneyRange(txout.nValue) || !MoneyRange(nValueOut))
genesis 514 throw std::runtime_error("CTransaction::GetValueOut() : value out of range");
genesis 515 }
genesis 516 return nValueOut;
genesis 517 }
genesis 518
genesis 519 static bool AllowFree(double dPriority)
genesis 520 {
genesis 521
genesis 522
genesis 523 return dPriority > COIN * 144 / 250;
genesis 524 }
genesis 525
genesis 526 int64 GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=true, bool fForRelay=false) const
genesis 527 {
genesis 528
genesis 529 int64 nBaseFee = fForRelay ? MIN_RELAY_TX_FEE : MIN_TX_FEE;
genesis 530
genesis 531 unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK);
genesis 532 unsigned int nNewBlockSize = nBlockSize + nBytes;
genesis 533 int64 nMinFee = (1 + (int64)nBytes / 1000) * nBaseFee;
genesis 534
genesis 535 if (fAllowFree)
genesis 536 {
genesis 537 if (nBlockSize == 1)
genesis 538 {
genesis 539
genesis 540
genesis 541 if (nBytes < 10000)
genesis 542 nMinFee = 0;
genesis 543 }
genesis 544 else
genesis 545 {
genesis 546
genesis 547 if (nNewBlockSize < 27000)
genesis 548 nMinFee = 0;
genesis 549 }
genesis 550 }
genesis 551
genesis 552
genesis 553 if (nMinFee < nBaseFee)
genesis 554 BOOST_FOREACH(const CTxOut& txout, vout)
genesis 555 if (txout.nValue < CENT)
genesis 556 nMinFee = nBaseFee;
genesis 557
genesis 558
genesis 559 if (nBlockSize != 1 && nNewBlockSize >= MAX_BLOCK_SIZE_GEN/2)
genesis 560 {
genesis 561 if (nNewBlockSize >= MAX_BLOCK_SIZE_GEN)
genesis 562 return MAX_MONEY;
genesis 563 nMinFee *= MAX_BLOCK_SIZE_GEN / (MAX_BLOCK_SIZE_GEN - nNewBlockSize);
genesis 564 }
genesis 565
genesis 566 if (!MoneyRange(nMinFee))
genesis 567 nMinFee = MAX_MONEY;
genesis 568 return nMinFee;
genesis 569 }
genesis 570
genesis 571
genesis 572 bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL)
genesis 573 {
genesis 574 CAutoFile filein = OpenBlockFile(pos.nFile, 0, pfileRet ? "rb+" : "rb");
genesis 575 if (!filein)
genesis 576 return error("CTransaction::ReadFromDisk() : OpenBlockFile failed");
genesis 577
genesis 578
genesis 579 if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)
genesis 580 return error("CTransaction::ReadFromDisk() : fseek failed");
genesis 581 filein >> *this;
genesis 582
genesis 583
genesis 584 if (pfileRet)
genesis 585 {
genesis 586 if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)
genesis 587 return error("CTransaction::ReadFromDisk() : second fseek failed");
genesis 588 *pfileRet = filein.release();
genesis 589 }
genesis 590 return true;
genesis 591 }
genesis 592
genesis 593 friend bool operator==(const CTransaction& a, const CTransaction& b)
genesis 594 {
genesis 595 return (a.nVersion == b.nVersion &&
genesis 596 a.vin == b.vin &&
genesis 597 a.vout == b.vout &&
genesis 598 a.nLockTime == b.nLockTime);
genesis 599 }
genesis 600
genesis 601 friend bool operator!=(const CTransaction& a, const CTransaction& b)
genesis 602 {
genesis 603 return !(a == b);
genesis 604 }
genesis 605
genesis 606
genesis 607 std::string ToString() const
genesis 608 {
genesis 609 std::string str;
genesis 610 str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%d, vout.size=%d, nLockTime=%d)\n",
genesis 611 GetHash().ToString().substr(0,10).c_str(),
genesis 612 nVersion,
genesis 613 vin.size(),
genesis 614 vout.size(),
genesis 615 nLockTime);
genesis 616 for (int i = 0; i < vin.size(); i++)
genesis 617 str += " " + vin[i].ToString() + "\n";
genesis 618 for (int i = 0; i < vout.size(); i++)
genesis 619 str += " " + vout[i].ToString() + "\n";
genesis 620 return str;
genesis 621 }
genesis 622
genesis 623 void print() const
genesis 624 {
genesis 625 printf("%s", ToString().c_str());
genesis 626 }
genesis 627
genesis 628
genesis 629 bool ReadFromDisk(CTxDB& txdb, COutPoint prevout, CTxIndex& txindexRet);
genesis 630 bool ReadFromDisk(CTxDB& txdb, COutPoint prevout);
genesis 631 bool ReadFromDisk(COutPoint prevout);
genesis 632 bool DisconnectInputs(CTxDB& txdb);
genesis 633 bool ConnectInputs(CTxDB& txdb, std::map<uint256, CTxIndex>& mapTestPool, CDiskTxPos posThisTx,
genesis 634 CBlockIndex* pindexBlock, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee,
genesis 635 bool& fInvalid);
genesis 636 bool ClientConnectInputs();
genesis 637 bool CheckTransaction() const;
genesis 638 bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL);
genesis 639 bool AcceptToMemoryPool(bool fCheckInputs=true, bool* pfMissingInputs=NULL);
genesis 640 protected:
genesis 641 bool AddToMemoryPoolUnchecked();
genesis 642 public:
genesis 643 bool RemoveFromMemoryPool();
genesis 644 };
genesis 645
genesis 646
genesis 647
genesis 648
genesis 649
genesis 650
genesis 651
genesis 652
genesis 653 class CMerkleTx : public CTransaction
genesis 654 {
genesis 655 public:
genesis 656 uint256 hashBlock;
genesis 657 std::vector<uint256> vMerkleBranch;
genesis 658 int nIndex;
genesis 659
genesis 660
genesis 661 mutable char fMerkleVerified;
genesis 662
genesis 663
genesis 664 CMerkleTx()
genesis 665 {
genesis 666 Init();
genesis 667 }
genesis 668
genesis 669 CMerkleTx(const CTransaction& txIn) : CTransaction(txIn)
genesis 670 {
genesis 671 Init();
genesis 672 }
genesis 673
genesis 674 void Init()
genesis 675 {
genesis 676 hashBlock = 0;
genesis 677 nIndex = -1;
genesis 678 fMerkleVerified = false;
genesis 679 }
genesis 680
genesis 681
genesis 682 IMPLEMENT_SERIALIZE
genesis 683 (
genesis 684 nSerSize += SerReadWrite(s, *(CTransaction*)this, nType, nVersion, ser_action);
genesis 685 nVersion = this->nVersion;
genesis 686 READWRITE(hashBlock);
genesis 687 READWRITE(vMerkleBranch);
genesis 688 READWRITE(nIndex);
genesis 689 )
genesis 690
genesis 691
genesis 692 int SetMerkleBranch(const CBlock* pblock=NULL);
genesis 693 int GetDepthInMainChain(int& nHeightRet) const;
genesis 694 int GetDepthInMainChain() const { int nHeight; return GetDepthInMainChain(nHeight); }
genesis 695 bool IsInMainChain() const { return GetDepthInMainChain() > 0; }
genesis 696 int GetBlocksToMaturity() const;
genesis 697 bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true);
genesis 698 bool AcceptToMemoryPool();
genesis 699 };
genesis 700
genesis 701
genesis 702
genesis 703
genesis 704
genesis 705
genesis 706
genesis 707
genesis 708
genesis 709 class CTxIndex
genesis 710 {
genesis 711 public:
genesis 712 CDiskTxPos pos;
genesis 713 std::vector<CDiskTxPos> vSpent;
genesis 714
genesis 715 CTxIndex()
genesis 716 {
genesis 717 SetNull();
genesis 718 }
genesis 719
genesis 720 CTxIndex(const CDiskTxPos& posIn, unsigned int nOutputs)
genesis 721 {
genesis 722 pos = posIn;
genesis 723 vSpent.resize(nOutputs);
genesis 724 }
genesis 725
genesis 726 IMPLEMENT_SERIALIZE
genesis 727 (
genesis 728 if (!(nType & SER_GETHASH))
genesis 729 READWRITE(nVersion);
genesis 730 READWRITE(pos);
genesis 731 READWRITE(vSpent);
genesis 732 )
genesis 733
genesis 734 void SetNull()
genesis 735 {
genesis 736 pos.SetNull();
genesis 737 vSpent.clear();
genesis 738 }
genesis 739
genesis 740 bool IsNull()
genesis 741 {
genesis 742 return pos.IsNull();
genesis 743 }
genesis 744
genesis 745 friend bool operator==(const CTxIndex& a, const CTxIndex& b)
genesis 746 {
genesis 747 return (a.pos == b.pos &&
genesis 748 a.vSpent == b.vSpent);
genesis 749 }
genesis 750
genesis 751 friend bool operator!=(const CTxIndex& a, const CTxIndex& b)
genesis 752 {
genesis 753 return !(a == b);
genesis 754 }
genesis 755 int GetDepthInMainChain() const;
genesis 756 };
genesis 757
genesis 758
genesis 759
genesis 760
genesis 761
genesis 762
genesis 763
genesis 764
genesis 765
genesis 766
genesis 767
genesis 768
genesis 769
genesis 770
genesis 771
genesis 772
genesis 773 class CBlock
genesis 774 {
genesis 775 public:
genesis 776
genesis 777 int nVersion;
genesis 778 uint256 hashPrevBlock;
genesis 779 uint256 hashMerkleRoot;
genesis 780 unsigned int nTime;
genesis 781 unsigned int nBits;
genesis 782 unsigned int nNonce;
genesis 783
genesis 784
genesis 785 std::vector<CTransaction> vtx;
genesis 786
genesis 787
genesis 788 mutable std::vector<uint256> vMerkleTree;
genesis 789
genesis 790
genesis 791 mutable int nDoS;
genesis 792 bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; }
genesis 793
genesis 794 CBlock()
genesis 795 {
genesis 796 SetNull();
genesis 797 }
genesis 798
genesis 799 IMPLEMENT_SERIALIZE
genesis 800 (
genesis 801 READWRITE(this->nVersion);
genesis 802 nVersion = this->nVersion;
genesis 803 READWRITE(hashPrevBlock);
genesis 804 READWRITE(hashMerkleRoot);
genesis 805 READWRITE(nTime);
genesis 806 READWRITE(nBits);
genesis 807 READWRITE(nNonce);
genesis 808
genesis 809
genesis 810 if (!(nType & (SER_GETHASH|SER_BLOCKHEADERONLY)))
genesis 811 READWRITE(vtx);
genesis 812 else if (fRead)
genesis 813 const_cast<CBlock*>(this)->vtx.clear();
genesis 814 )
genesis 815
genesis 816 void SetNull()
genesis 817 {
genesis 818 nVersion = 1;
genesis 819 hashPrevBlock = 0;
genesis 820 hashMerkleRoot = 0;
genesis 821 nTime = 0;
genesis 822 nBits = 0;
genesis 823 nNonce = 0;
genesis 824 vtx.clear();
genesis 825 vMerkleTree.clear();
genesis 826 nDoS = 0;
genesis 827 }
genesis 828
genesis 829 bool IsNull() const
genesis 830 {
genesis 831 return (nBits == 0);
genesis 832 }
genesis 833
genesis 834 uint256 GetHash() const
genesis 835 {
genesis 836 return Hash(BEGIN(nVersion), END(nNonce));
genesis 837 }
genesis 838
genesis 839 int64 GetBlockTime() const
genesis 840 {
genesis 841 return (int64)nTime;
genesis 842 }
genesis 843
genesis 844 int GetSigOpCount() const
genesis 845 {
genesis 846 int n = 0;
genesis 847 BOOST_FOREACH(const CTransaction& tx, vtx)
genesis 848 n += tx.GetSigOpCount();
genesis 849 return n;
genesis 850 }
genesis 851
genesis 852
genesis 853 uint256 BuildMerkleTree() const
genesis 854 {
genesis 855 vMerkleTree.clear();
genesis 856 BOOST_FOREACH(const CTransaction& tx, vtx)
genesis 857 vMerkleTree.push_back(tx.GetHash());
genesis 858 int j = 0;
genesis 859 for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
genesis 860 {
genesis 861 for (int i = 0; i < nSize; i += 2)
genesis 862 {
genesis 863 int i2 = std::min(i+1, nSize-1);
genesis 864 vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]), END(vMerkleTree[j+i]),
genesis 865 BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2])));
genesis 866 }
genesis 867 j += nSize;
genesis 868 }
genesis 869 return (vMerkleTree.empty() ? 0 : vMerkleTree.back());
genesis 870 }
genesis 871
genesis 872 std::vector<uint256> GetMerkleBranch(int nIndex) const
genesis 873 {
genesis 874 if (vMerkleTree.empty())
genesis 875 BuildMerkleTree();
genesis 876 std::vector<uint256> vMerkleBranch;
genesis 877 int j = 0;
genesis 878 for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
genesis 879 {
genesis 880 int i = std::min(nIndex^1, nSize-1);
genesis 881 vMerkleBranch.push_back(vMerkleTree[j+i]);
genesis 882 nIndex >>= 1;
genesis 883 j += nSize;
genesis 884 }
genesis 885 return vMerkleBranch;
genesis 886 }
genesis 887
genesis 888 static uint256 CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex)
genesis 889 {
genesis 890 if (nIndex == -1)
genesis 891 return 0;
genesis 892 BOOST_FOREACH(const uint256& otherside, vMerkleBranch)
genesis 893 {
genesis 894 if (nIndex & 1)
genesis 895 hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash));
genesis 896 else
genesis 897 hash = Hash(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside));
genesis 898 nIndex >>= 1;
genesis 899 }
genesis 900 return hash;
genesis 901 }
genesis 902
genesis 903
genesis 904 bool WriteToDisk(unsigned int& nFileRet, unsigned int& nBlockPosRet)
genesis 905 {
genesis 906
genesis 907 CAutoFile fileout = AppendBlockFile(nFileRet);
genesis 908 if (!fileout)
genesis 909 return error("CBlock::WriteToDisk() : AppendBlockFile failed");
genesis 910
genesis 911
genesis 912 unsigned int nSize = fileout.GetSerializeSize(*this);
genesis 913 fileout << FLATDATA(pchMessageStart) << nSize;
genesis 914
genesis 915
genesis 916 nBlockPosRet = ftell(fileout);
genesis 917 if (nBlockPosRet == -1)
genesis 918 return error("CBlock::WriteToDisk() : ftell failed");
genesis 919 fileout << *this;
genesis 920
genesis 921
genesis 922 fflush(fileout);
genesis 923 if (!IsInitialBlockDownload() || (nBestHeight+1) % 500 == 0)
genesis 924 {
genesis 925 fsync(fileno(fileout));
genesis 926 }
genesis 927
genesis 928 return true;
genesis 929 }
genesis 930
genesis 931 bool ReadFromDisk(unsigned int nFile, unsigned int nBlockPos, bool fReadTransactions=true)
genesis 932 {
genesis 933 SetNull();
genesis 934
genesis 935
genesis 936 CAutoFile filein = OpenBlockFile(nFile, nBlockPos, "rb");
genesis 937 if (!filein)
genesis 938 return error("CBlock::ReadFromDisk() : OpenBlockFile failed");
genesis 939 if (!fReadTransactions)
genesis 940 filein.nType |= SER_BLOCKHEADERONLY;
genesis 941
genesis 942
genesis 943 filein >> *this;
genesis 944
genesis 945
genesis 946 if (!CheckProofOfWork(GetHash(), nBits))
genesis 947 return error("CBlock::ReadFromDisk() : errors in block header");
genesis 948
genesis 949 return true;
genesis 950 }
genesis 951
genesis 952
genesis 953
genesis 954 void print() const
genesis 955 {
genesis 956 printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%d)\n",
genesis 957 GetHash().ToString().substr(0,20).c_str(),
genesis 958 nVersion,
genesis 959 hashPrevBlock.ToString().substr(0,20).c_str(),
genesis 960 hashMerkleRoot.ToString().substr(0,10).c_str(),
genesis 961 nTime, nBits, nNonce,
genesis 962 vtx.size());
genesis 963 for (int i = 0; i < vtx.size(); i++)
genesis 964 {
genesis 965 printf(" ");
genesis 966 vtx[i].print();
genesis 967 }
genesis 968 printf(" vMerkleTree: ");
genesis 969 for (int i = 0; i < vMerkleTree.size(); i++)
genesis 970 printf("%s ", vMerkleTree[i].ToString().substr(0,10).c_str());
genesis 971 printf("\n");
genesis 972 }
genesis 973
genesis 974
genesis 975 bool DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex);
genesis 976 bool ConnectBlock(CTxDB& txdb, CBlockIndex* pindex);
genesis 977 bool ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions=true);
genesis 978 bool SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew);
genesis 979 bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos);
genesis 980 bool CheckBlock() const;
genesis 981 bool AcceptBlock();
genesis 982 };
genesis 983
genesis 984
genesis 985
genesis 986
genesis 987
genesis 988
genesis 989
genesis 990
genesis 991
genesis 992
genesis 993
genesis 994
genesis 995
genesis 996
genesis 997 class CBlockIndex
genesis 998 {
genesis 999 public:
genesis 1000 const uint256* phashBlock;
genesis 1001 CBlockIndex* pprev;
genesis 1002 CBlockIndex* pnext;
genesis 1003 unsigned int nFile;
genesis 1004 unsigned int nBlockPos;
genesis 1005 int nHeight;
genesis 1006 CBigNum bnChainWork;
genesis 1007
genesis 1008
genesis 1009 int nVersion;
genesis 1010 uint256 hashMerkleRoot;
genesis 1011 unsigned int nTime;
genesis 1012 unsigned int nBits;
genesis 1013 unsigned int nNonce;
genesis 1014
genesis 1015
genesis 1016 CBlockIndex()
genesis 1017 {
genesis 1018 phashBlock = NULL;
genesis 1019 pprev = NULL;
genesis 1020 pnext = NULL;
genesis 1021 nFile = 0;
genesis 1022 nBlockPos = 0;
genesis 1023 nHeight = 0;
genesis 1024 bnChainWork = 0;
genesis 1025
genesis 1026 nVersion = 0;
genesis 1027 hashMerkleRoot = 0;
genesis 1028 nTime = 0;
genesis 1029 nBits = 0;
genesis 1030 nNonce = 0;
genesis 1031 }
genesis 1032
genesis 1033 CBlockIndex(unsigned int nFileIn, unsigned int nBlockPosIn, CBlock& block)
genesis 1034 {
genesis 1035 phashBlock = NULL;
genesis 1036 pprev = NULL;
genesis 1037 pnext = NULL;
genesis 1038 nFile = nFileIn;
genesis 1039 nBlockPos = nBlockPosIn;
genesis 1040 nHeight = 0;
genesis 1041 bnChainWork = 0;
genesis 1042
genesis 1043 nVersion = block.nVersion;
genesis 1044 hashMerkleRoot = block.hashMerkleRoot;
genesis 1045 nTime = block.nTime;
genesis 1046 nBits = block.nBits;
genesis 1047 nNonce = block.nNonce;
genesis 1048 }
genesis 1049
genesis 1050 CBlock GetBlockHeader() const
genesis 1051 {
genesis 1052 CBlock block;
genesis 1053 block.nVersion = nVersion;
genesis 1054 if (pprev)
genesis 1055 block.hashPrevBlock = pprev->GetBlockHash();
genesis 1056 block.hashMerkleRoot = hashMerkleRoot;
genesis 1057 block.nTime = nTime;
genesis 1058 block.nBits = nBits;
genesis 1059 block.nNonce = nNonce;
genesis 1060 return block;
genesis 1061 }
genesis 1062
genesis 1063 uint256 GetBlockHash() const
genesis 1064 {
genesis 1065 return *phashBlock;
genesis 1066 }
genesis 1067
genesis 1068 int64 GetBlockTime() const
genesis 1069 {
genesis 1070 return (int64)nTime;
genesis 1071 }
genesis 1072
genesis 1073 CBigNum GetBlockWork() const
genesis 1074 {
genesis 1075 CBigNum bnTarget;
genesis 1076 bnTarget.SetCompact(nBits);
genesis 1077 if (bnTarget <= 0)
genesis 1078 return 0;
genesis 1079 return (CBigNum(1)<<256) / (bnTarget+1);
genesis 1080 }
genesis 1081
genesis 1082 bool IsInMainChain() const
genesis 1083 {
genesis 1084 return (pnext || this == pindexBest);
genesis 1085 }
genesis 1086
genesis 1087 bool CheckIndex() const
genesis 1088 {
genesis 1089 return CheckProofOfWork(GetBlockHash(), nBits);
genesis 1090 }
genesis 1091
genesis 1092 bool EraseBlockFromDisk()
genesis 1093 {
genesis 1094
genesis 1095 CAutoFile fileout = OpenBlockFile(nFile, nBlockPos, "rb+");
genesis 1096 if (!fileout)
genesis 1097 return false;
genesis 1098
genesis 1099
genesis 1100 CBlock block;
genesis 1101 block.SetNull();
genesis 1102 fileout << block;
genesis 1103
genesis 1104 return true;
genesis 1105 }
genesis 1106
genesis 1107 enum { nMedianTimeSpan=11 };
genesis 1108
genesis 1109 int64 GetMedianTimePast() const
genesis 1110 {
genesis 1111 int64 pmedian[nMedianTimeSpan];
genesis 1112 int64* pbegin = &pmedian[nMedianTimeSpan];
genesis 1113 int64* pend = &pmedian[nMedianTimeSpan];
genesis 1114
genesis 1115 const CBlockIndex* pindex = this;
genesis 1116 for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev)
genesis 1117 *(--pbegin) = pindex->GetBlockTime();
genesis 1118
genesis 1119 std::sort(pbegin, pend);
genesis 1120 return pbegin[(pend - pbegin)/2];
genesis 1121 }
genesis 1122
genesis 1123 int64 GetMedianTime() const
genesis 1124 {
genesis 1125 const CBlockIndex* pindex = this;
genesis 1126 for (int i = 0; i < nMedianTimeSpan/2; i++)
genesis 1127 {
genesis 1128 if (!pindex->pnext)
genesis 1129 return GetBlockTime();
genesis 1130 pindex = pindex->pnext;
genesis 1131 }
genesis 1132 return pindex->GetMedianTimePast();
genesis 1133 }
genesis 1134
genesis 1135
genesis 1136
genesis 1137 std::string ToString() const
genesis 1138 {
genesis 1139 return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)",
genesis 1140 pprev, pnext, nFile, nBlockPos, nHeight,
genesis 1141 hashMerkleRoot.ToString().substr(0,10).c_str(),
genesis 1142 GetBlockHash().ToString().substr(0,20).c_str());
genesis 1143 }
genesis 1144
genesis 1145 void print() const
genesis 1146 {
genesis 1147 printf("%s\n", ToString().c_str());
genesis 1148 }
genesis 1149 };
genesis 1150
genesis 1151
genesis 1152
genesis 1153
genesis 1154
genesis 1155
genesis 1156 class CDiskBlockIndex : public CBlockIndex
genesis 1157 {
genesis 1158 public:
genesis 1159 uint256 hashPrev;
genesis 1160 uint256 hashNext;
genesis 1161
genesis 1162 CDiskBlockIndex()
genesis 1163 {
genesis 1164 hashPrev = 0;
genesis 1165 hashNext = 0;
genesis 1166 }
genesis 1167
genesis 1168 explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex)
genesis 1169 {
genesis 1170 hashPrev = (pprev ? pprev->GetBlockHash() : 0);
genesis 1171 hashNext = (pnext ? pnext->GetBlockHash() : 0);
genesis 1172 }
genesis 1173
genesis 1174 IMPLEMENT_SERIALIZE
genesis 1175 (
genesis 1176 if (!(nType & SER_GETHASH))
genesis 1177 READWRITE(nVersion);
genesis 1178
genesis 1179 READWRITE(hashNext);
genesis 1180 READWRITE(nFile);
genesis 1181 READWRITE(nBlockPos);
genesis 1182 READWRITE(nHeight);
genesis 1183
genesis 1184
genesis 1185 READWRITE(this->nVersion);
genesis 1186 READWRITE(hashPrev);
genesis 1187 READWRITE(hashMerkleRoot);
genesis 1188 READWRITE(nTime);
genesis 1189 READWRITE(nBits);
genesis 1190 READWRITE(nNonce);
genesis 1191 )
genesis 1192
genesis 1193 uint256 GetBlockHash() const
genesis 1194 {
genesis 1195 CBlock block;
genesis 1196 block.nVersion = nVersion;
genesis 1197 block.hashPrevBlock = hashPrev;
genesis 1198 block.hashMerkleRoot = hashMerkleRoot;
genesis 1199 block.nTime = nTime;
genesis 1200 block.nBits = nBits;
genesis 1201 block.nNonce = nNonce;
genesis 1202 return block.GetHash();
genesis 1203 }
genesis 1204
genesis 1205
genesis 1206 std::string ToString() const
genesis 1207 {
genesis 1208 std::string str = "CDiskBlockIndex(";
genesis 1209 str += CBlockIndex::ToString();
genesis 1210 str += strprintf("\n hashBlock=%s, hashPrev=%s, hashNext=%s)",
genesis 1211 GetBlockHash().ToString().c_str(),
genesis 1212 hashPrev.ToString().substr(0,20).c_str(),
genesis 1213 hashNext.ToString().substr(0,20).c_str());
genesis 1214 return str;
genesis 1215 }
genesis 1216
genesis 1217 void print() const
genesis 1218 {
genesis 1219 printf("%s\n", ToString().c_str());
genesis 1220 }
genesis 1221 };
genesis 1222
genesis 1223
genesis 1224
genesis 1225
genesis 1226
genesis 1227
genesis 1228
genesis 1229
genesis 1230
genesis 1231
genesis 1232
genesis 1233
genesis 1234
genesis 1235 class CBlockLocator
genesis 1236 {
genesis 1237 protected:
genesis 1238 std::vector<uint256> vHave;
genesis 1239 public:
genesis 1240
genesis 1241 CBlockLocator()
genesis 1242 {
genesis 1243 }
genesis 1244
genesis 1245 explicit CBlockLocator(const CBlockIndex* pindex)
genesis 1246 {
genesis 1247 Set(pindex);
genesis 1248 }
genesis 1249
genesis 1250 explicit CBlockLocator(uint256 hashBlock)
genesis 1251 {
genesis 1252 std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
genesis 1253 if (mi != mapBlockIndex.end())
genesis 1254 Set((*mi).second);
genesis 1255 }
genesis 1256
genesis 1257 IMPLEMENT_SERIALIZE
genesis 1258 (
genesis 1259 if (!(nType & SER_GETHASH))
genesis 1260 READWRITE(nVersion);
genesis 1261 READWRITE(vHave);
genesis 1262 )
genesis 1263
genesis 1264 void SetNull()
genesis 1265 {
genesis 1266 vHave.clear();
genesis 1267 }
genesis 1268
genesis 1269 bool IsNull()
genesis 1270 {
genesis 1271 return vHave.empty();
genesis 1272 }
genesis 1273
genesis 1274 void Set(const CBlockIndex* pindex)
genesis 1275 {
genesis 1276 vHave.clear();
genesis 1277 int nStep = 1;
genesis 1278 while (pindex)
genesis 1279 {
genesis 1280 vHave.push_back(pindex->GetBlockHash());
genesis 1281
genesis 1282
genesis 1283 for (int i = 0; pindex && i < nStep; i++)
genesis 1284 pindex = pindex->pprev;
genesis 1285 if (vHave.size() > 10)
genesis 1286 nStep *= 2;
genesis 1287 }
genesis 1288 vHave.push_back(hashGenesisBlock);
genesis 1289 }
genesis 1290
genesis 1291 int GetDistanceBack()
genesis 1292 {
genesis 1293
genesis 1294 int nDistance = 0;
genesis 1295 int nStep = 1;
genesis 1296 BOOST_FOREACH(const uint256& hash, vHave)
genesis 1297 {
genesis 1298 std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
genesis 1299 if (mi != mapBlockIndex.end())
genesis 1300 {
genesis 1301 CBlockIndex* pindex = (*mi).second;
genesis 1302 if (pindex->IsInMainChain())
genesis 1303 return nDistance;
genesis 1304 }
genesis 1305 nDistance += nStep;
genesis 1306 if (nDistance > 10)
genesis 1307 nStep *= 2;
genesis 1308 }
genesis 1309 return nDistance;
genesis 1310 }
genesis 1311
genesis 1312 CBlockIndex* GetBlockIndex()
genesis 1313 {
genesis 1314
genesis 1315 BOOST_FOREACH(const uint256& hash, vHave)
genesis 1316 {
genesis 1317 std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
genesis 1318 if (mi != mapBlockIndex.end())
genesis 1319 {
genesis 1320 CBlockIndex* pindex = (*mi).second;
genesis 1321 if (pindex->IsInMainChain())
genesis 1322 return pindex;
genesis 1323 }
genesis 1324 }
genesis 1325 return pindexGenesisBlock;
genesis 1326 }
genesis 1327
genesis 1328 uint256 GetBlockHash()
genesis 1329 {
genesis 1330
genesis 1331 BOOST_FOREACH(const uint256& hash, vHave)
genesis 1332 {
genesis 1333 std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
genesis 1334 if (mi != mapBlockIndex.end())
genesis 1335 {
genesis 1336 CBlockIndex* pindex = (*mi).second;
genesis 1337 if (pindex->IsInMainChain())
genesis 1338 return hash;
genesis 1339 }
genesis 1340 }
genesis 1341 return hashGenesisBlock;
genesis 1342 }
genesis 1343
genesis 1344 int GetHeight()
genesis 1345 {
genesis 1346 CBlockIndex* pindex = GetBlockIndex();
genesis 1347 if (!pindex)
genesis 1348 return 0;
genesis 1349 return pindex->nHeight;
genesis 1350 }
genesis 1351 };
genesis 1352
genesis 1353 #endif