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())
polarbeard_better... 500 return error(SMEM "non-standard input %s", txin.scriptSig.ToString().c_str());
genesis 501 BOOST_FOREACH(const CTxOut& txout, vout)
genesis 502 if (!::IsStandard(txout.scriptPubKey))
polarbeard_better... 503 return error(SMEM "non-standard output %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)
polarbeard_better... 576 return error(SBLK "failure reading block file %d from disk", pos.nFile);
genesis 577
genesis 578
genesis 579 if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)
polarbeard_better... 580 return error(SBLK "failure reading block file %d from disk at position %d",
polarbeard_better... 581 pos.nFile, pos.nTxPos);
genesis 582 filein >> *this;
genesis 583
genesis 584
genesis 585 if (pfileRet)
genesis 586 {
genesis 587 if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)
polarbeard_better... 588 return error(SBLK "second failure reading block file %d from disk at position %d",
polarbeard_better... 589 pos.nFile, pos.nTxPos);
genesis 590 *pfileRet = filein.release();
genesis 591 }
genesis 592 return true;
genesis 593 }
genesis 594
genesis 595 friend bool operator==(const CTransaction& a, const CTransaction& b)
genesis 596 {
genesis 597 return (a.nVersion == b.nVersion &&
genesis 598 a.vin == b.vin &&
genesis 599 a.vout == b.vout &&
genesis 600 a.nLockTime == b.nLockTime);
genesis 601 }
genesis 602
genesis 603 friend bool operator!=(const CTransaction& a, const CTransaction& b)
genesis 604 {
genesis 605 return !(a == b);
genesis 606 }
genesis 607
genesis 608
genesis 609 std::string ToString() const
genesis 610 {
genesis 611 std::string str;
genesis 612 str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%d, vout.size=%d, nLockTime=%d)\n",
genesis 613 GetHash().ToString().substr(0,10).c_str(),
genesis 614 nVersion,
genesis 615 vin.size(),
genesis 616 vout.size(),
genesis 617 nLockTime);
genesis 618 for (int i = 0; i < vin.size(); i++)
genesis 619 str += " " + vin[i].ToString() + "\n";
genesis 620 for (int i = 0; i < vout.size(); i++)
genesis 621 str += " " + vout[i].ToString() + "\n";
genesis 622 return str;
genesis 623 }
genesis 624
genesis 625 void print() const
genesis 626 {
genesis 627 printf("%s", ToString().c_str());
genesis 628 }
genesis 629
genesis 630
genesis 631 bool ReadFromDisk(CTxDB& txdb, COutPoint prevout, CTxIndex& txindexRet);
genesis 632 bool ReadFromDisk(CTxDB& txdb, COutPoint prevout);
genesis 633 bool ReadFromDisk(COutPoint prevout);
genesis 634 bool DisconnectInputs(CTxDB& txdb);
genesis 635 bool ConnectInputs(CTxDB& txdb, std::map<uint256, CTxIndex>& mapTestPool, CDiskTxPos posThisTx,
genesis 636 CBlockIndex* pindexBlock, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee,
genesis 637 bool& fInvalid);
genesis 638 bool ClientConnectInputs();
genesis 639 bool CheckTransaction() const;
genesis 640 bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL);
genesis 641 bool AcceptToMemoryPool(bool fCheckInputs=true, bool* pfMissingInputs=NULL);
genesis 642 protected:
genesis 643 bool AddToMemoryPoolUnchecked();
genesis 644 public:
genesis 645 bool RemoveFromMemoryPool();
genesis 646 };
genesis 647
genesis 648
genesis 649
genesis 650
genesis 651
genesis 652
genesis 653
genesis 654
genesis 655 class CMerkleTx : public CTransaction
genesis 656 {
genesis 657 public:
genesis 658 uint256 hashBlock;
genesis 659 std::vector<uint256> vMerkleBranch;
genesis 660 int nIndex;
genesis 661
genesis 662
genesis 663 mutable char fMerkleVerified;
genesis 664
genesis 665
genesis 666 CMerkleTx()
genesis 667 {
genesis 668 Init();
genesis 669 }
genesis 670
genesis 671 CMerkleTx(const CTransaction& txIn) : CTransaction(txIn)
genesis 672 {
genesis 673 Init();
genesis 674 }
genesis 675
genesis 676 void Init()
genesis 677 {
genesis 678 hashBlock = 0;
genesis 679 nIndex = -1;
genesis 680 fMerkleVerified = false;
genesis 681 }
genesis 682
genesis 683
genesis 684 IMPLEMENT_SERIALIZE
genesis 685 (
genesis 686 nSerSize += SerReadWrite(s, *(CTransaction*)this, nType, nVersion, ser_action);
genesis 687 nVersion = this->nVersion;
genesis 688 READWRITE(hashBlock);
genesis 689 READWRITE(vMerkleBranch);
genesis 690 READWRITE(nIndex);
genesis 691 )
genesis 692
genesis 693
genesis 694 int SetMerkleBranch(const CBlock* pblock=NULL);
genesis 695 int GetDepthInMainChain(int& nHeightRet) const;
genesis 696 int GetDepthInMainChain() const { int nHeight; return GetDepthInMainChain(nHeight); }
genesis 697 bool IsInMainChain() const { return GetDepthInMainChain() > 0; }
genesis 698 int GetBlocksToMaturity() const;
genesis 699 bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true);
genesis 700 bool AcceptToMemoryPool();
genesis 701 };
genesis 702
genesis 703
genesis 704
genesis 705
genesis 706
genesis 707
genesis 708
genesis 709
genesis 710
genesis 711 class CTxIndex
genesis 712 {
genesis 713 public:
genesis 714 CDiskTxPos pos;
genesis 715 std::vector<CDiskTxPos> vSpent;
genesis 716
genesis 717 CTxIndex()
genesis 718 {
genesis 719 SetNull();
genesis 720 }
genesis 721
genesis 722 CTxIndex(const CDiskTxPos& posIn, unsigned int nOutputs)
genesis 723 {
genesis 724 pos = posIn;
genesis 725 vSpent.resize(nOutputs);
genesis 726 }
genesis 727
genesis 728 IMPLEMENT_SERIALIZE
genesis 729 (
genesis 730 if (!(nType & SER_GETHASH))
genesis 731 READWRITE(nVersion);
genesis 732 READWRITE(pos);
genesis 733 READWRITE(vSpent);
genesis 734 )
genesis 735
genesis 736 void SetNull()
genesis 737 {
genesis 738 pos.SetNull();
genesis 739 vSpent.clear();
genesis 740 }
genesis 741
genesis 742 bool IsNull()
genesis 743 {
genesis 744 return pos.IsNull();
genesis 745 }
genesis 746
genesis 747 friend bool operator==(const CTxIndex& a, const CTxIndex& b)
genesis 748 {
genesis 749 return (a.pos == b.pos &&
genesis 750 a.vSpent == b.vSpent);
genesis 751 }
genesis 752
genesis 753 friend bool operator!=(const CTxIndex& a, const CTxIndex& b)
genesis 754 {
genesis 755 return !(a == b);
genesis 756 }
genesis 757 int GetDepthInMainChain() const;
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
genesis 775 class CBlock
genesis 776 {
genesis 777 public:
genesis 778
genesis 779 int nVersion;
genesis 780 uint256 hashPrevBlock;
genesis 781 uint256 hashMerkleRoot;
genesis 782 unsigned int nTime;
genesis 783 unsigned int nBits;
genesis 784 unsigned int nNonce;
genesis 785
genesis 786
genesis 787 std::vector<CTransaction> vtx;
genesis 788
genesis 789
genesis 790 mutable std::vector<uint256> vMerkleTree;
genesis 791
genesis 792
genesis 793 mutable int nDoS;
genesis 794 bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; }
genesis 795
genesis 796 CBlock()
genesis 797 {
genesis 798 SetNull();
genesis 799 }
genesis 800
genesis 801 IMPLEMENT_SERIALIZE
genesis 802 (
genesis 803 READWRITE(this->nVersion);
genesis 804 nVersion = this->nVersion;
genesis 805 READWRITE(hashPrevBlock);
genesis 806 READWRITE(hashMerkleRoot);
genesis 807 READWRITE(nTime);
genesis 808 READWRITE(nBits);
genesis 809 READWRITE(nNonce);
genesis 810
genesis 811
genesis 812 if (!(nType & (SER_GETHASH|SER_BLOCKHEADERONLY)))
genesis 813 READWRITE(vtx);
genesis 814 else if (fRead)
genesis 815 const_cast<CBlock*>(this)->vtx.clear();
genesis 816 )
genesis 817
genesis 818 void SetNull()
genesis 819 {
genesis 820 nVersion = 1;
genesis 821 hashPrevBlock = 0;
genesis 822 hashMerkleRoot = 0;
genesis 823 nTime = 0;
genesis 824 nBits = 0;
genesis 825 nNonce = 0;
genesis 826 vtx.clear();
genesis 827 vMerkleTree.clear();
genesis 828 nDoS = 0;
genesis 829 }
genesis 830
genesis 831 bool IsNull() const
genesis 832 {
genesis 833 return (nBits == 0);
genesis 834 }
genesis 835
genesis 836 uint256 GetHash() const
genesis 837 {
genesis 838 return Hash(BEGIN(nVersion), END(nNonce));
genesis 839 }
genesis 840
genesis 841 int64 GetBlockTime() const
genesis 842 {
genesis 843 return (int64)nTime;
genesis 844 }
genesis 845
genesis 846 int GetSigOpCount() const
genesis 847 {
genesis 848 int n = 0;
genesis 849 BOOST_FOREACH(const CTransaction& tx, vtx)
genesis 850 n += tx.GetSigOpCount();
genesis 851 return n;
genesis 852 }
genesis 853
genesis 854
genesis 855 uint256 BuildMerkleTree() const
genesis 856 {
genesis 857 vMerkleTree.clear();
genesis 858 BOOST_FOREACH(const CTransaction& tx, vtx)
genesis 859 vMerkleTree.push_back(tx.GetHash());
genesis 860 int j = 0;
genesis 861 for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
genesis 862 {
genesis 863 for (int i = 0; i < nSize; i += 2)
genesis 864 {
genesis 865 int i2 = std::min(i+1, nSize-1);
genesis 866 vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]), END(vMerkleTree[j+i]),
genesis 867 BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2])));
genesis 868 }
genesis 869 j += nSize;
genesis 870 }
genesis 871 return (vMerkleTree.empty() ? 0 : vMerkleTree.back());
genesis 872 }
genesis 873
genesis 874 std::vector<uint256> GetMerkleBranch(int nIndex) const
genesis 875 {
genesis 876 if (vMerkleTree.empty())
genesis 877 BuildMerkleTree();
genesis 878 std::vector<uint256> vMerkleBranch;
genesis 879 int j = 0;
genesis 880 for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
genesis 881 {
genesis 882 int i = std::min(nIndex^1, nSize-1);
genesis 883 vMerkleBranch.push_back(vMerkleTree[j+i]);
genesis 884 nIndex >>= 1;
genesis 885 j += nSize;
genesis 886 }
genesis 887 return vMerkleBranch;
genesis 888 }
genesis 889
genesis 890 static uint256 CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex)
genesis 891 {
genesis 892 if (nIndex == -1)
genesis 893 return 0;
genesis 894 BOOST_FOREACH(const uint256& otherside, vMerkleBranch)
genesis 895 {
genesis 896 if (nIndex & 1)
genesis 897 hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash));
genesis 898 else
genesis 899 hash = Hash(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside));
genesis 900 nIndex >>= 1;
genesis 901 }
genesis 902 return hash;
genesis 903 }
genesis 904
genesis 905
genesis 906 bool WriteToDisk(unsigned int& nFileRet, unsigned int& nBlockPosRet)
genesis 907 {
genesis 908
genesis 909 CAutoFile fileout = AppendBlockFile(nFileRet);
genesis 910 if (!fileout)
polarbeard_better... 911 return error(SBLK "failure wrting block file %d to disk", nFileRet);
genesis 912
genesis 913
genesis 914 unsigned int nSize = fileout.GetSerializeSize(*this);
genesis 915 fileout << FLATDATA(pchMessageStart) << nSize;
genesis 916
genesis 917
genesis 918 nBlockPosRet = ftell(fileout);
genesis 919 if (nBlockPosRet == -1)
genesis 920 return error("CBlock::WriteToDisk() : ftell failed");
genesis 921 fileout << *this;
genesis 922
genesis 923
genesis 924 fflush(fileout);
genesis 925 if (!IsInitialBlockDownload() || (nBestHeight+1) % 500 == 0)
genesis 926 {
genesis 927 fsync(fileno(fileout));
genesis 928 }
genesis 929
genesis 930 return true;
genesis 931 }
genesis 932
genesis 933 bool ReadFromDisk(unsigned int nFile, unsigned int nBlockPos, bool fReadTransactions=true)
genesis 934 {
genesis 935 SetNull();
genesis 936
genesis 937
genesis 938 CAutoFile filein = OpenBlockFile(nFile, nBlockPos, "rb");
genesis 939 if (!filein)
genesis 940 return error("CBlock::ReadFromDisk() : OpenBlockFile failed");
genesis 941 if (!fReadTransactions)
genesis 942 filein.nType |= SER_BLOCKHEADERONLY;
genesis 943
genesis 944
genesis 945 filein >> *this;
genesis 946
genesis 947
genesis 948 if (!CheckProofOfWork(GetHash(), nBits))
genesis 949 return error("CBlock::ReadFromDisk() : errors in block header");
genesis 950
genesis 951 return true;
genesis 952 }
genesis 953
genesis 954
genesis 955
genesis 956 void print() const
genesis 957 {
genesis 958 printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%d)\n",
genesis 959 GetHash().ToString().substr(0,20).c_str(),
genesis 960 nVersion,
genesis 961 hashPrevBlock.ToString().substr(0,20).c_str(),
genesis 962 hashMerkleRoot.ToString().substr(0,10).c_str(),
genesis 963 nTime, nBits, nNonce,
genesis 964 vtx.size());
genesis 965 for (int i = 0; i < vtx.size(); i++)
genesis 966 {
genesis 967 printf(" ");
genesis 968 vtx[i].print();
genesis 969 }
genesis 970 printf(" vMerkleTree: ");
genesis 971 for (int i = 0; i < vMerkleTree.size(); i++)
genesis 972 printf("%s ", vMerkleTree[i].ToString().substr(0,10).c_str());
genesis 973 printf("\n");
genesis 974 }
genesis 975
genesis 976
genesis 977 bool DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex);
genesis 978 bool ConnectBlock(CTxDB& txdb, CBlockIndex* pindex);
genesis 979 bool ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions=true);
genesis 980 bool SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew);
genesis 981 bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos);
genesis 982 bool CheckBlock() const;
genesis 983 bool AcceptBlock();
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
genesis 999 class CBlockIndex
genesis 1000 {
genesis 1001 public:
genesis 1002 const uint256* phashBlock;
genesis 1003 CBlockIndex* pprev;
genesis 1004 CBlockIndex* pnext;
genesis 1005 unsigned int nFile;
genesis 1006 unsigned int nBlockPos;
genesis 1007 int nHeight;
genesis 1008 CBigNum bnChainWork;
genesis 1009
genesis 1010
genesis 1011 int nVersion;
genesis 1012 uint256 hashMerkleRoot;
genesis 1013 unsigned int nTime;
genesis 1014 unsigned int nBits;
genesis 1015 unsigned int nNonce;
genesis 1016
genesis 1017
genesis 1018 CBlockIndex()
genesis 1019 {
genesis 1020 phashBlock = NULL;
genesis 1021 pprev = NULL;
genesis 1022 pnext = NULL;
genesis 1023 nFile = 0;
genesis 1024 nBlockPos = 0;
genesis 1025 nHeight = 0;
genesis 1026 bnChainWork = 0;
genesis 1027
genesis 1028 nVersion = 0;
genesis 1029 hashMerkleRoot = 0;
genesis 1030 nTime = 0;
genesis 1031 nBits = 0;
genesis 1032 nNonce = 0;
genesis 1033 }
genesis 1034
genesis 1035 CBlockIndex(unsigned int nFileIn, unsigned int nBlockPosIn, CBlock& block)
genesis 1036 {
genesis 1037 phashBlock = NULL;
genesis 1038 pprev = NULL;
genesis 1039 pnext = NULL;
genesis 1040 nFile = nFileIn;
genesis 1041 nBlockPos = nBlockPosIn;
genesis 1042 nHeight = 0;
genesis 1043 bnChainWork = 0;
genesis 1044
genesis 1045 nVersion = block.nVersion;
genesis 1046 hashMerkleRoot = block.hashMerkleRoot;
genesis 1047 nTime = block.nTime;
genesis 1048 nBits = block.nBits;
genesis 1049 nNonce = block.nNonce;
genesis 1050 }
genesis 1051
genesis 1052 CBlock GetBlockHeader() const
genesis 1053 {
genesis 1054 CBlock block;
genesis 1055 block.nVersion = nVersion;
genesis 1056 if (pprev)
genesis 1057 block.hashPrevBlock = pprev->GetBlockHash();
genesis 1058 block.hashMerkleRoot = hashMerkleRoot;
genesis 1059 block.nTime = nTime;
genesis 1060 block.nBits = nBits;
genesis 1061 block.nNonce = nNonce;
genesis 1062 return block;
genesis 1063 }
genesis 1064
genesis 1065 uint256 GetBlockHash() const
genesis 1066 {
genesis 1067 return *phashBlock;
genesis 1068 }
genesis 1069
genesis 1070 int64 GetBlockTime() const
genesis 1071 {
genesis 1072 return (int64)nTime;
genesis 1073 }
genesis 1074
genesis 1075 CBigNum GetBlockWork() const
genesis 1076 {
genesis 1077 CBigNum bnTarget;
genesis 1078 bnTarget.SetCompact(nBits);
genesis 1079 if (bnTarget <= 0)
genesis 1080 return 0;
genesis 1081 return (CBigNum(1)<<256) / (bnTarget+1);
genesis 1082 }
genesis 1083
genesis 1084 bool IsInMainChain() const
genesis 1085 {
genesis 1086 return (pnext || this == pindexBest);
genesis 1087 }
genesis 1088
genesis 1089 bool CheckIndex() const
genesis 1090 {
genesis 1091 return CheckProofOfWork(GetBlockHash(), nBits);
genesis 1092 }
genesis 1093
genesis 1094 bool EraseBlockFromDisk()
genesis 1095 {
genesis 1096
genesis 1097 CAutoFile fileout = OpenBlockFile(nFile, nBlockPos, "rb+");
genesis 1098 if (!fileout)
genesis 1099 return false;
genesis 1100
genesis 1101
genesis 1102 CBlock block;
genesis 1103 block.SetNull();
genesis 1104 fileout << block;
genesis 1105
genesis 1106 return true;
genesis 1107 }
genesis 1108
genesis 1109 enum { nMedianTimeSpan=11 };
genesis 1110
genesis 1111 int64 GetMedianTimePast() const
genesis 1112 {
genesis 1113 int64 pmedian[nMedianTimeSpan];
genesis 1114 int64* pbegin = &pmedian[nMedianTimeSpan];
genesis 1115 int64* pend = &pmedian[nMedianTimeSpan];
genesis 1116
genesis 1117 const CBlockIndex* pindex = this;
genesis 1118 for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev)
genesis 1119 *(--pbegin) = pindex->GetBlockTime();
genesis 1120
genesis 1121 std::sort(pbegin, pend);
genesis 1122 return pbegin[(pend - pbegin)/2];
genesis 1123 }
genesis 1124
genesis 1125 int64 GetMedianTime() const
genesis 1126 {
genesis 1127 const CBlockIndex* pindex = this;
genesis 1128 for (int i = 0; i < nMedianTimeSpan/2; i++)
genesis 1129 {
genesis 1130 if (!pindex->pnext)
genesis 1131 return GetBlockTime();
genesis 1132 pindex = pindex->pnext;
genesis 1133 }
genesis 1134 return pindex->GetMedianTimePast();
genesis 1135 }
genesis 1136
genesis 1137
genesis 1138
genesis 1139 std::string ToString() const
genesis 1140 {
genesis 1141 return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)",
genesis 1142 pprev, pnext, nFile, nBlockPos, nHeight,
genesis 1143 hashMerkleRoot.ToString().substr(0,10).c_str(),
genesis 1144 GetBlockHash().ToString().substr(0,20).c_str());
genesis 1145 }
genesis 1146
genesis 1147 void print() const
genesis 1148 {
genesis 1149 printf("%s\n", ToString().c_str());
genesis 1150 }
genesis 1151 };
genesis 1152
genesis 1153
genesis 1154
genesis 1155
genesis 1156
genesis 1157
genesis 1158 class CDiskBlockIndex : public CBlockIndex
genesis 1159 {
genesis 1160 public:
genesis 1161 uint256 hashPrev;
genesis 1162 uint256 hashNext;
genesis 1163
genesis 1164 CDiskBlockIndex()
genesis 1165 {
genesis 1166 hashPrev = 0;
genesis 1167 hashNext = 0;
genesis 1168 }
genesis 1169
genesis 1170 explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex)
genesis 1171 {
genesis 1172 hashPrev = (pprev ? pprev->GetBlockHash() : 0);
genesis 1173 hashNext = (pnext ? pnext->GetBlockHash() : 0);
genesis 1174 }
genesis 1175
genesis 1176 IMPLEMENT_SERIALIZE
genesis 1177 (
genesis 1178 if (!(nType & SER_GETHASH))
genesis 1179 READWRITE(nVersion);
genesis 1180
genesis 1181 READWRITE(hashNext);
genesis 1182 READWRITE(nFile);
genesis 1183 READWRITE(nBlockPos);
genesis 1184 READWRITE(nHeight);
genesis 1185
genesis 1186
genesis 1187 READWRITE(this->nVersion);
genesis 1188 READWRITE(hashPrev);
genesis 1189 READWRITE(hashMerkleRoot);
genesis 1190 READWRITE(nTime);
genesis 1191 READWRITE(nBits);
genesis 1192 READWRITE(nNonce);
genesis 1193 )
genesis 1194
genesis 1195 uint256 GetBlockHash() const
genesis 1196 {
genesis 1197 CBlock block;
genesis 1198 block.nVersion = nVersion;
genesis 1199 block.hashPrevBlock = hashPrev;
genesis 1200 block.hashMerkleRoot = hashMerkleRoot;
genesis 1201 block.nTime = nTime;
genesis 1202 block.nBits = nBits;
genesis 1203 block.nNonce = nNonce;
genesis 1204 return block.GetHash();
genesis 1205 }
genesis 1206
genesis 1207
genesis 1208 std::string ToString() const
genesis 1209 {
genesis 1210 std::string str = "CDiskBlockIndex(";
genesis 1211 str += CBlockIndex::ToString();
genesis 1212 str += strprintf("\n hashBlock=%s, hashPrev=%s, hashNext=%s)",
genesis 1213 GetBlockHash().ToString().c_str(),
genesis 1214 hashPrev.ToString().substr(0,20).c_str(),
genesis 1215 hashNext.ToString().substr(0,20).c_str());
genesis 1216 return str;
genesis 1217 }
genesis 1218
genesis 1219 void print() const
genesis 1220 {
genesis 1221 printf("%s\n", ToString().c_str());
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
genesis 1237 class CBlockLocator
genesis 1238 {
genesis 1239 protected:
genesis 1240 std::vector<uint256> vHave;
genesis 1241 public:
genesis 1242
genesis 1243 CBlockLocator()
genesis 1244 {
genesis 1245 }
genesis 1246
genesis 1247 explicit CBlockLocator(const CBlockIndex* pindex)
genesis 1248 {
genesis 1249 Set(pindex);
genesis 1250 }
genesis 1251
genesis 1252 explicit CBlockLocator(uint256 hashBlock)
genesis 1253 {
genesis 1254 std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
genesis 1255 if (mi != mapBlockIndex.end())
genesis 1256 Set((*mi).second);
genesis 1257 }
genesis 1258
genesis 1259 IMPLEMENT_SERIALIZE
genesis 1260 (
genesis 1261 if (!(nType & SER_GETHASH))
genesis 1262 READWRITE(nVersion);
genesis 1263 READWRITE(vHave);
genesis 1264 )
genesis 1265
genesis 1266 void SetNull()
genesis 1267 {
genesis 1268 vHave.clear();
genesis 1269 }
genesis 1270
genesis 1271 bool IsNull()
genesis 1272 {
genesis 1273 return vHave.empty();
genesis 1274 }
genesis 1275
genesis 1276 void Set(const CBlockIndex* pindex)
genesis 1277 {
genesis 1278 vHave.clear();
genesis 1279 int nStep = 1;
genesis 1280 while (pindex)
genesis 1281 {
genesis 1282 vHave.push_back(pindex->GetBlockHash());
genesis 1283
genesis 1284
genesis 1285 for (int i = 0; pindex && i < nStep; i++)
genesis 1286 pindex = pindex->pprev;
genesis 1287 if (vHave.size() > 10)
genesis 1288 nStep *= 2;
genesis 1289 }
genesis 1290 vHave.push_back(hashGenesisBlock);
genesis 1291 }
genesis 1292
genesis 1293 int GetDistanceBack()
genesis 1294 {
genesis 1295
genesis 1296 int nDistance = 0;
genesis 1297 int nStep = 1;
genesis 1298 BOOST_FOREACH(const uint256& hash, vHave)
genesis 1299 {
genesis 1300 std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
genesis 1301 if (mi != mapBlockIndex.end())
genesis 1302 {
genesis 1303 CBlockIndex* pindex = (*mi).second;
genesis 1304 if (pindex->IsInMainChain())
genesis 1305 return nDistance;
genesis 1306 }
genesis 1307 nDistance += nStep;
genesis 1308 if (nDistance > 10)
genesis 1309 nStep *= 2;
genesis 1310 }
genesis 1311 return nDistance;
genesis 1312 }
genesis 1313
genesis 1314 CBlockIndex* GetBlockIndex()
genesis 1315 {
genesis 1316
genesis 1317 BOOST_FOREACH(const uint256& hash, vHave)
genesis 1318 {
genesis 1319 std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
genesis 1320 if (mi != mapBlockIndex.end())
genesis 1321 {
genesis 1322 CBlockIndex* pindex = (*mi).second;
genesis 1323 if (pindex->IsInMainChain())
genesis 1324 return pindex;
genesis 1325 }
genesis 1326 }
genesis 1327 return pindexGenesisBlock;
genesis 1328 }
genesis 1329
genesis 1330 uint256 GetBlockHash()
genesis 1331 {
genesis 1332
genesis 1333 BOOST_FOREACH(const uint256& hash, vHave)
genesis 1334 {
genesis 1335 std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
genesis 1336 if (mi != mapBlockIndex.end())
genesis 1337 {
genesis 1338 CBlockIndex* pindex = (*mi).second;
genesis 1339 if (pindex->IsInMainChain())
genesis 1340 return hash;
genesis 1341 }
genesis 1342 }
genesis 1343 return hashGenesisBlock;
genesis 1344 }
genesis 1345
genesis 1346 int GetHeight()
genesis 1347 {
genesis 1348 CBlockIndex* pindex = GetBlockIndex();
genesis 1349 if (!pindex)
genesis 1350 return 0;
genesis 1351 return pindex->nHeight;
genesis 1352 }
genesis 1353 };
genesis 1354
genesis 1355 #endif