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