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())
polarbeard_fix_in... 167 return strprintf("");
genesis 168 else
polarbeard_fix_in... 169 return strprintf("nFile=%d,nBlockPos=%d,nTxPos=%d", nFile, nBlockPos, nTxPos);
genesis 170 }
genesis 171
genesis 172 void print() const
genesis 173 {
polarbeard_fix_in... 174 printf(SINF SMEM "CDiskTxPos<%s>\n", 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 {
polarbeard_fix_in... 225 return strprintf("hash=%s,n=%d", hash.ToString().c_str(), n);
genesis 226 }
genesis 227
genesis 228 void print() const
genesis 229 {
polarbeard_fix_in... 230 printf(SINF SMEM "COutPoint<%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;
polarbeard_fix_in... 295 str += strprintf("prevout=%s", prevout.ToString().c_str());
genesis 296 if (prevout.IsNull())
polarbeard_fix_in... 297 str += strprintf(",coinbase=%s", HexStr(scriptSig).c_str());
genesis 298 else
polarbeard_fix_in... 299 str += strprintf(",scriptSig=%s", scriptSig.ToString().c_str());
genesis 300 if (nSequence != UINT_MAX)
polarbeard_fix_in... 301 str += strprintf(",nSequence=%u", nSequence);
genesis 302 return str;
genesis 303 }
genesis 304
genesis 305 void print() const
genesis 306 {
polarbeard_fix_in... 307 printf(SINF SMEM "CTxIn<%s>\n", ToString().c_str());
genesis 308 }
genesis 309 };
genesis 310
genesis 311
genesis 312
genesis 313
genesis 314
genesis 315
genesis 316
genesis 317
genesis 318 class CTxOut
genesis 319 {
genesis 320 public:
genesis 321 int64 nValue;
genesis 322 CScript scriptPubKey;
genesis 323
genesis 324 CTxOut()
genesis 325 {
genesis 326 SetNull();
genesis 327 }
genesis 328
genesis 329 CTxOut(int64 nValueIn, CScript scriptPubKeyIn)
genesis 330 {
genesis 331 nValue = nValueIn;
genesis 332 scriptPubKey = scriptPubKeyIn;
genesis 333 }
genesis 334
genesis 335 IMPLEMENT_SERIALIZE
genesis 336 (
genesis 337 READWRITE(nValue);
genesis 338 READWRITE(scriptPubKey);
genesis 339 )
genesis 340
genesis 341 void SetNull()
genesis 342 {
genesis 343 nValue = -1;
genesis 344 scriptPubKey.clear();
genesis 345 }
genesis 346
genesis 347 bool IsNull()
genesis 348 {
genesis 349 return (nValue == -1);
genesis 350 }
genesis 351
genesis 352 uint256 GetHash() const
genesis 353 {
genesis 354 return SerializeHash(*this);
genesis 355 }
genesis 356
genesis 357 friend bool operator==(const CTxOut& a, const CTxOut& b)
genesis 358 {
genesis 359 return (a.nValue == b.nValue &&
genesis 360 a.scriptPubKey == b.scriptPubKey);
genesis 361 }
genesis 362
genesis 363 friend bool operator!=(const CTxOut& a, const CTxOut& b)
genesis 364 {
genesis 365 return !(a == b);
genesis 366 }
genesis 367
genesis 368 std::string ToString() const
genesis 369 {
genesis 370 if (scriptPubKey.size() < 6)
polarbeard_fix_in... 371 return "error";
polarbeard_fix_in... 372 return strprintf("nValue=%"PRI64d".%08"PRI64d",scriptPubKey=%s",
polarbeard_fix_in... 373 nValue / COIN, nValue % COIN, scriptPubKey.ToString().c_str());
genesis 374 }
genesis 375
genesis 376 void print() const
genesis 377 {
polarbeard_fix_in... 378 printf(SINF SMEM "CTxOut<%s>\n", ToString().c_str());
genesis 379 }
genesis 380 };
genesis 381
genesis 382
genesis 383
genesis 384
genesis 385
genesis 386
genesis 387
genesis 388
genesis 389 class CTransaction
genesis 390 {
genesis 391 public:
genesis 392 int nVersion;
genesis 393 std::vector<CTxIn> vin;
genesis 394 std::vector<CTxOut> vout;
genesis 395 unsigned int nLockTime;
genesis 396
genesis 397
genesis 398 mutable int nDoS;
genesis 399 bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; }
genesis 400
genesis 401 CTransaction()
genesis 402 {
genesis 403 SetNull();
genesis 404 }
genesis 405
genesis 406 IMPLEMENT_SERIALIZE
genesis 407 (
genesis 408 READWRITE(this->nVersion);
genesis 409 nVersion = this->nVersion;
genesis 410 READWRITE(vin);
genesis 411 READWRITE(vout);
genesis 412 READWRITE(nLockTime);
genesis 413 )
genesis 414
genesis 415 void SetNull()
genesis 416 {
genesis 417 nVersion = 1;
genesis 418 vin.clear();
genesis 419 vout.clear();
genesis 420 nLockTime = 0;
genesis 421 nDoS = 0;
genesis 422 }
genesis 423
genesis 424 bool IsNull() const
genesis 425 {
genesis 426 return (vin.empty() && vout.empty());
genesis 427 }
genesis 428
genesis 429 uint256 GetHash() const
genesis 430 {
genesis 431 return SerializeHash(*this);
genesis 432 }
genesis 433
genesis 434 bool IsFinal(int nBlockHeight=0, int64 nBlockTime=0) const
genesis 435 {
genesis 436
genesis 437 if (nLockTime == 0)
genesis 438 return true;
genesis 439 if (nBlockHeight == 0)
genesis 440 nBlockHeight = nBestHeight;
genesis 441 if (nBlockTime == 0)
genesis 442 nBlockTime = GetAdjustedTime();
genesis 443 if ((int64)nLockTime < (nLockTime < LOCKTIME_THRESHOLD ? (int64)nBlockHeight : nBlockTime))
genesis 444 return true;
genesis 445 BOOST_FOREACH(const CTxIn& txin, vin)
genesis 446 if (!txin.IsFinal())
genesis 447 return false;
genesis 448 return true;
genesis 449 }
genesis 450
genesis 451 bool IsNewerThan(const CTransaction& old) const
genesis 452 {
genesis 453 if (vin.size() != old.vin.size())
genesis 454 return false;
genesis 455 for (int i = 0; i < vin.size(); i++)
genesis 456 if (vin[i].prevout != old.vin[i].prevout)
genesis 457 return false;
genesis 458
genesis 459 bool fNewer = false;
genesis 460 unsigned int nLowest = UINT_MAX;
genesis 461 for (int i = 0; i < vin.size(); i++)
genesis 462 {
genesis 463 if (vin[i].nSequence != old.vin[i].nSequence)
genesis 464 {
genesis 465 if (vin[i].nSequence <= nLowest)
genesis 466 {
genesis 467 fNewer = false;
genesis 468 nLowest = vin[i].nSequence;
genesis 469 }
genesis 470 if (old.vin[i].nSequence < nLowest)
genesis 471 {
genesis 472 fNewer = true;
genesis 473 nLowest = old.vin[i].nSequence;
genesis 474 }
genesis 475 }
genesis 476 }
genesis 477 return fNewer;
genesis 478 }
genesis 479
genesis 480 bool IsCoinBase() const
genesis 481 {
genesis 482 return (vin.size() == 1 && vin[0].prevout.IsNull());
genesis 483 }
genesis 484
genesis 485 int GetSigOpCount() const
genesis 486 {
genesis 487 int n = 0;
genesis 488 BOOST_FOREACH(const CTxIn& txin, vin)
genesis 489 n += txin.scriptSig.GetSigOpCount();
genesis 490 BOOST_FOREACH(const CTxOut& txout, vout)
genesis 491 n += txout.scriptPubKey.GetSigOpCount();
genesis 492 return n;
genesis 493 }
genesis 494
genesis 495 bool IsStandard() const
genesis 496 {
genesis 497 BOOST_FOREACH(const CTxIn& txin, vin)
genesis 498 if (!txin.scriptSig.IsPushOnly())
polarbeard_better... 499 return error(SMEM "non-standard input %s", txin.scriptSig.ToString().c_str());
genesis 500 BOOST_FOREACH(const CTxOut& txout, vout)
genesis 501 if (!::IsStandard(txout.scriptPubKey))
polarbeard_better... 502 return error(SMEM "non-standard output %s", txout.scriptPubKey.ToString().c_str());
genesis 503 return true;
genesis 504 }
genesis 505
genesis 506 int64 GetValueOut() const
genesis 507 {
genesis 508 int64 nValueOut = 0;
genesis 509 BOOST_FOREACH(const CTxOut& txout, vout)
genesis 510 {
genesis 511 nValueOut += txout.nValue;
genesis 512 if (!MoneyRange(txout.nValue) || !MoneyRange(nValueOut))
genesis 513 throw std::runtime_error("CTransaction::GetValueOut() : value out of range");
genesis 514 }
genesis 515 return nValueOut;
genesis 516 }
genesis 517
genesis 518 static bool AllowFree(double dPriority)
genesis 519 {
genesis 520
genesis 521
genesis 522 return dPriority > COIN * 144 / 250;
genesis 523 }
genesis 524
genesis 525 int64 GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=true, bool fForRelay=false) const
genesis 526 {
genesis 527
genesis 528 int64 nBaseFee = fForRelay ? MIN_RELAY_TX_FEE : MIN_TX_FEE;
genesis 529
genesis 530 unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK);
genesis 531 unsigned int nNewBlockSize = nBlockSize + nBytes;
genesis 532 int64 nMinFee = (1 + (int64)nBytes / 1000) * nBaseFee;
genesis 533
genesis 534 if (fAllowFree)
genesis 535 {
genesis 536 if (nBlockSize == 1)
genesis 537 {
genesis 538
genesis 539
genesis 540 if (nBytes < 10000)
genesis 541 nMinFee = 0;
genesis 542 }
genesis 543 else
genesis 544 {
genesis 545
genesis 546 if (nNewBlockSize < 27000)
genesis 547 nMinFee = 0;
genesis 548 }
genesis 549 }
genesis 550
genesis 551
genesis 552 if (nMinFee < nBaseFee)
genesis 553 BOOST_FOREACH(const CTxOut& txout, vout)
genesis 554 if (txout.nValue < CENT)
genesis 555 nMinFee = nBaseFee;
genesis 556
genesis 557
genesis 558 if (nBlockSize != 1 && nNewBlockSize >= MAX_BLOCK_SIZE_GEN/2)
genesis 559 {
genesis 560 if (nNewBlockSize >= MAX_BLOCK_SIZE_GEN)
genesis 561 return MAX_MONEY;
genesis 562 nMinFee *= MAX_BLOCK_SIZE_GEN / (MAX_BLOCK_SIZE_GEN - nNewBlockSize);
genesis 563 }
genesis 564
genesis 565 if (!MoneyRange(nMinFee))
genesis 566 nMinFee = MAX_MONEY;
genesis 567 return nMinFee;
genesis 568 }
genesis 569
genesis 570
genesis 571 bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL)
genesis 572 {
genesis 573 CAutoFile filein = OpenBlockFile(pos.nFile, 0, pfileRet ? "rb+" : "rb");
genesis 574 if (!filein)
polarbeard_better... 575 return error(SBLK "failure reading block file %d from disk", pos.nFile);
genesis 576
genesis 577
genesis 578 if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)
polarbeard_better... 579 return error(SBLK "failure reading block file %d from disk at position %d",
polarbeard_better... 580 pos.nFile, pos.nTxPos);
genesis 581 filein >> *this;
genesis 582
genesis 583
genesis 584 if (pfileRet)
genesis 585 {
genesis 586 if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)
polarbeard_better... 587 return error(SBLK "second failure reading block file %d from disk at position %d",
polarbeard_better... 588 pos.nFile, pos.nTxPos);
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;
polarbeard_fix_in... 611 str += strprintf("hash=%s,ver=%d,vin.size=%d,vout.size=%d,nLockTime=%d,vin={",
polarbeard_fix_in... 612 GetHash().ToString().c_str(), nVersion, vin.size(), vout.size(), nLockTime);
genesis 613 for (int i = 0; i < vin.size(); i++)
polarbeard_fix_in... 614 str += "CTxIn<" + vin[i].ToString() + ">" + (i == vin.size() - 1 ? "" : ",");
polarbeard_fix_in... 615 str += "},vout={";
genesis 616 for (int i = 0; i < vout.size(); i++)
polarbeard_fix_in... 617 str += "CTxOut<" + vout[i].ToString() + ">" + (i == vout.size() - 1 ? "" : ",");
polarbeard_fix_in... 618 str += "}";
genesis 619 return str;
genesis 620 }
genesis 621
genesis 622 void print() const
genesis 623 {
polarbeard_fix_in... 624 printf(SINF SMEM "CTransaction<%s>\n", ToString().c_str());
genesis 625 }
genesis 626
genesis 627
genesis 628 bool ReadFromDisk(CTxDB& txdb, COutPoint prevout, CTxIndex& txindexRet);
genesis 629 bool ReadFromDisk(CTxDB& txdb, COutPoint prevout);
genesis 630 bool ReadFromDisk(COutPoint prevout);
genesis 631 bool DisconnectInputs(CTxDB& txdb);
genesis 632 bool ConnectInputs(CTxDB& txdb, std::map<uint256, CTxIndex>& mapTestPool, CDiskTxPos posThisTx,
genesis 633 CBlockIndex* pindexBlock, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee,
genesis 634 bool& fInvalid);
genesis 635 bool ClientConnectInputs();
genesis 636 bool CheckTransaction() const;
genesis 637 bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL);
genesis 638 bool AcceptToMemoryPool(bool fCheckInputs=true, bool* pfMissingInputs=NULL);
genesis 639 protected:
genesis 640 bool AddToMemoryPoolUnchecked();
genesis 641 public:
genesis 642 bool RemoveFromMemoryPool();
genesis 643 };
genesis 644
genesis 645
genesis 646
genesis 647
genesis 648
genesis 649
genesis 650
genesis 651
genesis 652 class CMerkleTx : public CTransaction
genesis 653 {
genesis 654 public:
genesis 655 uint256 hashBlock;
genesis 656 std::vector<uint256> vMerkleBranch;
genesis 657 int nIndex;
genesis 658
genesis 659
genesis 660 mutable char fMerkleVerified;
genesis 661
genesis 662
genesis 663 CMerkleTx()
genesis 664 {
genesis 665 Init();
genesis 666 }
genesis 667
genesis 668 CMerkleTx(const CTransaction& txIn) : CTransaction(txIn)
genesis 669 {
genesis 670 Init();
genesis 671 }
genesis 672
genesis 673 void Init()
genesis 674 {
genesis 675 hashBlock = 0;
genesis 676 nIndex = -1;
genesis 677 fMerkleVerified = false;
genesis 678 }
genesis 679
genesis 680
genesis 681 IMPLEMENT_SERIALIZE
genesis 682 (
genesis 683 nSerSize += SerReadWrite(s, *(CTransaction*)this, nType, nVersion, ser_action);
genesis 684 nVersion = this->nVersion;
genesis 685 READWRITE(hashBlock);
genesis 686 READWRITE(vMerkleBranch);
genesis 687 READWRITE(nIndex);
genesis 688 )
genesis 689
genesis 690
genesis 691 int SetMerkleBranch(const CBlock* pblock=NULL);
genesis 692 int GetDepthInMainChain(int& nHeightRet) const;
genesis 693 int GetDepthInMainChain() const { int nHeight; return GetDepthInMainChain(nHeight); }
genesis 694 bool IsInMainChain() const { return GetDepthInMainChain() > 0; }
genesis 695 int GetBlocksToMaturity() const;
genesis 696 bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true);
genesis 697 bool AcceptToMemoryPool();
genesis 698 };
genesis 699
genesis 700
genesis 701
genesis 702
genesis 703
genesis 704
genesis 705
genesis 706
genesis 707
genesis 708 class CTxIndex
genesis 709 {
genesis 710 public:
genesis 711 CDiskTxPos pos;
genesis 712 std::vector<CDiskTxPos> vSpent;
genesis 713
genesis 714 CTxIndex()
genesis 715 {
genesis 716 SetNull();
genesis 717 }
genesis 718
genesis 719 CTxIndex(const CDiskTxPos& posIn, unsigned int nOutputs)
genesis 720 {
genesis 721 pos = posIn;
genesis 722 vSpent.resize(nOutputs);
genesis 723 }
genesis 724
genesis 725 IMPLEMENT_SERIALIZE
genesis 726 (
genesis 727 if (!(nType & SER_GETHASH))
genesis 728 READWRITE(nVersion);
genesis 729 READWRITE(pos);
genesis 730 READWRITE(vSpent);
genesis 731 )
genesis 732
genesis 733 void SetNull()
genesis 734 {
genesis 735 pos.SetNull();
genesis 736 vSpent.clear();
genesis 737 }
genesis 738
genesis 739 bool IsNull()
genesis 740 {
genesis 741 return pos.IsNull();
genesis 742 }
genesis 743
genesis 744 friend bool operator==(const CTxIndex& a, const CTxIndex& b)
genesis 745 {
genesis 746 return (a.pos == b.pos &&
genesis 747 a.vSpent == b.vSpent);
genesis 748 }
genesis 749
genesis 750 friend bool operator!=(const CTxIndex& a, const CTxIndex& b)
genesis 751 {
genesis 752 return !(a == b);
genesis 753 }
genesis 754 int GetDepthInMainChain() const;
genesis 755 };
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 class CBlock
genesis 773 {
genesis 774 public:
genesis 775
genesis 776 int nVersion;
genesis 777 uint256 hashPrevBlock;
genesis 778 uint256 hashMerkleRoot;
genesis 779 unsigned int nTime;
genesis 780 unsigned int nBits;
genesis 781 unsigned int nNonce;
genesis 782
genesis 783
genesis 784 std::vector<CTransaction> vtx;
genesis 785
genesis 786
genesis 787 mutable std::vector<uint256> vMerkleTree;
genesis 788
genesis 789
genesis 790 mutable int nDoS;
genesis 791 bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; }
genesis 792
genesis 793 CBlock()
genesis 794 {
genesis 795 SetNull();
genesis 796 }
genesis 797
genesis 798 IMPLEMENT_SERIALIZE
genesis 799 (
genesis 800 READWRITE(this->nVersion);
genesis 801 nVersion = this->nVersion;
genesis 802 READWRITE(hashPrevBlock);
genesis 803 READWRITE(hashMerkleRoot);
genesis 804 READWRITE(nTime);
genesis 805 READWRITE(nBits);
genesis 806 READWRITE(nNonce);
genesis 807
genesis 808
genesis 809 if (!(nType & (SER_GETHASH|SER_BLOCKHEADERONLY)))
genesis 810 READWRITE(vtx);
genesis 811 else if (fRead)
genesis 812 const_cast<CBlock*>(this)->vtx.clear();
genesis 813 )
genesis 814
genesis 815 void SetNull()
genesis 816 {
genesis 817 nVersion = 1;
genesis 818 hashPrevBlock = 0;
genesis 819 hashMerkleRoot = 0;
genesis 820 nTime = 0;
genesis 821 nBits = 0;
genesis 822 nNonce = 0;
genesis 823 vtx.clear();
genesis 824 vMerkleTree.clear();
genesis 825 nDoS = 0;
genesis 826 }
genesis 827
genesis 828 bool IsNull() const
genesis 829 {
genesis 830 return (nBits == 0);
genesis 831 }
genesis 832
genesis 833 uint256 GetHash() const
genesis 834 {
genesis 835 return Hash(BEGIN(nVersion), END(nNonce));
genesis 836 }
genesis 837
genesis 838 int64 GetBlockTime() const
genesis 839 {
genesis 840 return (int64)nTime;
genesis 841 }
genesis 842
genesis 843 int GetSigOpCount() const
genesis 844 {
genesis 845 int n = 0;
genesis 846 BOOST_FOREACH(const CTransaction& tx, vtx)
genesis 847 n += tx.GetSigOpCount();
genesis 848 return n;
genesis 849 }
genesis 850
genesis 851
genesis 852 uint256 BuildMerkleTree() const
genesis 853 {
genesis 854 vMerkleTree.clear();
genesis 855 BOOST_FOREACH(const CTransaction& tx, vtx)
genesis 856 vMerkleTree.push_back(tx.GetHash());
genesis 857 int j = 0;
genesis 858 for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
genesis 859 {
genesis 860 for (int i = 0; i < nSize; i += 2)
genesis 861 {
genesis 862 int i2 = std::min(i+1, nSize-1);
genesis 863 vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]), END(vMerkleTree[j+i]),
genesis 864 BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2])));
genesis 865 }
genesis 866 j += nSize;
genesis 867 }
genesis 868 return (vMerkleTree.empty() ? 0 : vMerkleTree.back());
genesis 869 }
genesis 870
genesis 871 std::vector<uint256> GetMerkleBranch(int nIndex) const
genesis 872 {
genesis 873 if (vMerkleTree.empty())
genesis 874 BuildMerkleTree();
genesis 875 std::vector<uint256> vMerkleBranch;
genesis 876 int j = 0;
genesis 877 for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
genesis 878 {
genesis 879 int i = std::min(nIndex^1, nSize-1);
genesis 880 vMerkleBranch.push_back(vMerkleTree[j+i]);
genesis 881 nIndex >>= 1;
genesis 882 j += nSize;
genesis 883 }
genesis 884 return vMerkleBranch;
genesis 885 }
genesis 886
genesis 887 static uint256 CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex)
genesis 888 {
genesis 889 if (nIndex == -1)
genesis 890 return 0;
genesis 891 BOOST_FOREACH(const uint256& otherside, vMerkleBranch)
genesis 892 {
genesis 893 if (nIndex & 1)
genesis 894 hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash));
genesis 895 else
genesis 896 hash = Hash(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside));
genesis 897 nIndex >>= 1;
genesis 898 }
genesis 899 return hash;
genesis 900 }
genesis 901
genesis 902
genesis 903 bool WriteToDisk(unsigned int& nFileRet, unsigned int& nBlockPosRet)
genesis 904 {
genesis 905
genesis 906 CAutoFile fileout = AppendBlockFile(nFileRet);
genesis 907 if (!fileout)
polarbeard_better... 908 return error(SBLK "failure wrting block file %d to disk", nFileRet);
genesis 909
genesis 910
genesis 911 unsigned int nSize = fileout.GetSerializeSize(*this);
genesis 912 fileout << FLATDATA(pchMessageStart) << nSize;
genesis 913
genesis 914
genesis 915 nBlockPosRet = ftell(fileout);
genesis 916 if (nBlockPosRet == -1)
genesis 917 return error("CBlock::WriteToDisk() : ftell failed");
genesis 918 fileout << *this;
genesis 919
genesis 920
genesis 921 fflush(fileout);
genesis 922 if (!IsInitialBlockDownload() || (nBestHeight+1) % 500 == 0)
genesis 923 {
genesis 924 fsync(fileno(fileout));
genesis 925 }
genesis 926
genesis 927 return true;
genesis 928 }
genesis 929
genesis 930 bool ReadFromDisk(unsigned int nFile, unsigned int nBlockPos, bool fReadTransactions=true)
genesis 931 {
genesis 932 SetNull();
genesis 933
genesis 934
genesis 935 CAutoFile filein = OpenBlockFile(nFile, nBlockPos, "rb");
genesis 936 if (!filein)
genesis 937 return error("CBlock::ReadFromDisk() : OpenBlockFile failed");
genesis 938 if (!fReadTransactions)
genesis 939 filein.nType |= SER_BLOCKHEADERONLY;
genesis 940
genesis 941
genesis 942 filein >> *this;
genesis 943
genesis 944
genesis 945 if (!CheckProofOfWork(GetHash(), nBits))
polarbeard_fix_in... 946 return error(SBLK "failure reading block file %d from disk due errors on block header", nFile);
genesis 947
genesis 948 return true;
genesis 949 }
genesis 950
polarbeard_fix_in... 951 std::string ToString() const
polarbeard_fix_in... 952 {
polarbeard_fix_in... 953 std::string str;
polarbeard_fix_in... 954 str += strprintf("hash=%s,ver=%d,hashPrevBlock=%s,hashMerkleRoot=%s,nTime=%u,nBits=%08x,nNonce=%u,vtx={",
polarbeard_fix_in... 955 GetHash().ToString().c_str(), nVersion, hashPrevBlock.ToString().c_str(),
polarbeard_fix_in... 956 hashMerkleRoot.ToString().c_str(), nTime, nBits, nNonce, vtx.size());
polarbeard_fix_in... 957 for (int i = 0; i < vtx.size(); i++)
polarbeard_fix_in... 958 str += strprintf("CTransaction<%s>%s", vtx[i].ToString().c_str(), i == vtx.size() - 1 ? "" : ",");
polarbeard_fix_in... 959 str += "}";
polarbeard_fix_in... 960 return str;
polarbeard_fix_in... 961 }
genesis 962
genesis 963 void print() const
genesis 964 {
polarbeard_fix_in... 965 printf(SINF SBLK "CBlock<%s>\n", ToString().c_str());
genesis 966 }
genesis 967
genesis 968
genesis 969 bool DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex);
genesis 970 bool ConnectBlock(CTxDB& txdb, CBlockIndex* pindex);
genesis 971 bool ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions=true);
genesis 972 bool SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew);
genesis 973 bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos);
genesis 974 bool CheckBlock() const;
genesis 975 bool AcceptBlock();
genesis 976 };
genesis 977
genesis 978
genesis 979
genesis 980
genesis 981
genesis 982
genesis 983
genesis 984
genesis 985
genesis 986
genesis 987
genesis 988
genesis 989
genesis 990
genesis 991 class CBlockIndex
genesis 992 {
genesis 993 public:
genesis 994 const uint256* phashBlock;
genesis 995 CBlockIndex* pprev;
genesis 996 CBlockIndex* pnext;
genesis 997 unsigned int nFile;
genesis 998 unsigned int nBlockPos;
genesis 999 int nHeight;
genesis 1000 CBigNum bnChainWork;
genesis 1001
genesis 1002
genesis 1003 int nVersion;
genesis 1004 uint256 hashMerkleRoot;
genesis 1005 unsigned int nTime;
genesis 1006 unsigned int nBits;
genesis 1007 unsigned int nNonce;
genesis 1008
genesis 1009
genesis 1010 CBlockIndex()
genesis 1011 {
genesis 1012 phashBlock = NULL;
genesis 1013 pprev = NULL;
genesis 1014 pnext = NULL;
genesis 1015 nFile = 0;
genesis 1016 nBlockPos = 0;
genesis 1017 nHeight = 0;
genesis 1018 bnChainWork = 0;
genesis 1019
genesis 1020 nVersion = 0;
genesis 1021 hashMerkleRoot = 0;
genesis 1022 nTime = 0;
genesis 1023 nBits = 0;
genesis 1024 nNonce = 0;
genesis 1025 }
genesis 1026
genesis 1027 CBlockIndex(unsigned int nFileIn, unsigned int nBlockPosIn, CBlock& block)
genesis 1028 {
genesis 1029 phashBlock = NULL;
genesis 1030 pprev = NULL;
genesis 1031 pnext = NULL;
genesis 1032 nFile = nFileIn;
genesis 1033 nBlockPos = nBlockPosIn;
genesis 1034 nHeight = 0;
genesis 1035 bnChainWork = 0;
genesis 1036
genesis 1037 nVersion = block.nVersion;
genesis 1038 hashMerkleRoot = block.hashMerkleRoot;
genesis 1039 nTime = block.nTime;
genesis 1040 nBits = block.nBits;
genesis 1041 nNonce = block.nNonce;
genesis 1042 }
genesis 1043
genesis 1044 CBlock GetBlockHeader() const
genesis 1045 {
genesis 1046 CBlock block;
genesis 1047 block.nVersion = nVersion;
genesis 1048 if (pprev)
genesis 1049 block.hashPrevBlock = pprev->GetBlockHash();
genesis 1050 block.hashMerkleRoot = hashMerkleRoot;
genesis 1051 block.nTime = nTime;
genesis 1052 block.nBits = nBits;
genesis 1053 block.nNonce = nNonce;
genesis 1054 return block;
genesis 1055 }
genesis 1056
genesis 1057 uint256 GetBlockHash() const
genesis 1058 {
genesis 1059 return *phashBlock;
genesis 1060 }
genesis 1061
genesis 1062 int64 GetBlockTime() const
genesis 1063 {
genesis 1064 return (int64)nTime;
genesis 1065 }
genesis 1066
genesis 1067 CBigNum GetBlockWork() const
genesis 1068 {
genesis 1069 CBigNum bnTarget;
genesis 1070 bnTarget.SetCompact(nBits);
genesis 1071 if (bnTarget <= 0)
genesis 1072 return 0;
genesis 1073 return (CBigNum(1)<<256) / (bnTarget+1);
genesis 1074 }
genesis 1075
genesis 1076 bool IsInMainChain() const
genesis 1077 {
genesis 1078 return (pnext || this == pindexBest);
genesis 1079 }
genesis 1080
genesis 1081 bool CheckIndex() const
genesis 1082 {
genesis 1083 return CheckProofOfWork(GetBlockHash(), nBits);
genesis 1084 }
genesis 1085
genesis 1086 bool EraseBlockFromDisk()
genesis 1087 {
genesis 1088
genesis 1089 CAutoFile fileout = OpenBlockFile(nFile, nBlockPos, "rb+");
genesis 1090 if (!fileout)
genesis 1091 return false;
genesis 1092
genesis 1093
genesis 1094 CBlock block;
genesis 1095 block.SetNull();
genesis 1096 fileout << block;
genesis 1097
genesis 1098 return true;
genesis 1099 }
genesis 1100
genesis 1101 enum { nMedianTimeSpan=11 };
genesis 1102
genesis 1103 int64 GetMedianTimePast() const
genesis 1104 {
genesis 1105 int64 pmedian[nMedianTimeSpan];
genesis 1106 int64* pbegin = &pmedian[nMedianTimeSpan];
genesis 1107 int64* pend = &pmedian[nMedianTimeSpan];
genesis 1108
genesis 1109 const CBlockIndex* pindex = this;
genesis 1110 for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev)
genesis 1111 *(--pbegin) = pindex->GetBlockTime();
genesis 1112
genesis 1113 std::sort(pbegin, pend);
genesis 1114 return pbegin[(pend - pbegin)/2];
genesis 1115 }
genesis 1116
genesis 1117 int64 GetMedianTime() const
genesis 1118 {
genesis 1119 const CBlockIndex* pindex = this;
genesis 1120 for (int i = 0; i < nMedianTimeSpan/2; i++)
genesis 1121 {
genesis 1122 if (!pindex->pnext)
genesis 1123 return GetBlockTime();
genesis 1124 pindex = pindex->pnext;
genesis 1125 }
genesis 1126 return pindex->GetMedianTimePast();
genesis 1127 }
genesis 1128
genesis 1129
genesis 1130
genesis 1131 std::string ToString() const
genesis 1132 {
polarbeard_fix_in... 1133 return strprintf("nprev=%08x,pnext=%08x,nFile=%d,nBlockPos=%-6d,nHeight=%d,merkle=%s,hashBlock=%s",
polarbeard_fix_in... 1134 pprev, pnext, nFile, nBlockPos, nHeight, hashMerkleRoot.ToString().c_str(),
polarbeard_fix_in... 1135 GetBlockHash().ToString().c_str());
genesis 1136 }
genesis 1137
genesis 1138 void print() const
genesis 1139 {
polarbeard_fix_in... 1140 printf(SINF SBLK "CBlockIndex<%s>\n", ToString().c_str());
genesis 1141 }
genesis 1142 };
genesis 1143
genesis 1144
genesis 1145
genesis 1146
genesis 1147
genesis 1148
genesis 1149 class CDiskBlockIndex : public CBlockIndex
genesis 1150 {
genesis 1151 public:
genesis 1152 uint256 hashPrev;
genesis 1153 uint256 hashNext;
genesis 1154
genesis 1155 CDiskBlockIndex()
genesis 1156 {
genesis 1157 hashPrev = 0;
genesis 1158 hashNext = 0;
genesis 1159 }
genesis 1160
genesis 1161 explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex)
genesis 1162 {
genesis 1163 hashPrev = (pprev ? pprev->GetBlockHash() : 0);
genesis 1164 hashNext = (pnext ? pnext->GetBlockHash() : 0);
genesis 1165 }
genesis 1166
genesis 1167 IMPLEMENT_SERIALIZE
genesis 1168 (
genesis 1169 if (!(nType & SER_GETHASH))
genesis 1170 READWRITE(nVersion);
genesis 1171
genesis 1172 READWRITE(hashNext);
genesis 1173 READWRITE(nFile);
genesis 1174 READWRITE(nBlockPos);
genesis 1175 READWRITE(nHeight);
genesis 1176
genesis 1177
genesis 1178 READWRITE(this->nVersion);
genesis 1179 READWRITE(hashPrev);
genesis 1180 READWRITE(hashMerkleRoot);
genesis 1181 READWRITE(nTime);
genesis 1182 READWRITE(nBits);
genesis 1183 READWRITE(nNonce);
genesis 1184 )
genesis 1185
genesis 1186 uint256 GetBlockHash() const
genesis 1187 {
genesis 1188 CBlock block;
genesis 1189 block.nVersion = nVersion;
genesis 1190 block.hashPrevBlock = hashPrev;
genesis 1191 block.hashMerkleRoot = hashMerkleRoot;
genesis 1192 block.nTime = nTime;
genesis 1193 block.nBits = nBits;
genesis 1194 block.nNonce = nNonce;
genesis 1195 return block.GetHash();
genesis 1196 }
genesis 1197
genesis 1198
genesis 1199 std::string ToString() const
genesis 1200 {
polarbeard_fix_in... 1201 std::string str;
genesis 1202 str += CBlockIndex::ToString();
polarbeard_fix_in... 1203 str += strprintf("%s,hashBlock=%s,hashPrev=%s,hashNext=%s",
polarbeard_fix_in... 1204 CBlockIndex::ToString().c_str(), GetBlockHash().ToString().c_str(),
polarbeard_fix_in... 1205 hashPrev.ToString().c_str(), hashNext.ToString().c_str());
genesis 1206 return str;
genesis 1207 }
genesis 1208
genesis 1209 void print() const
genesis 1210 {
polarbeard_fix_in... 1211 printf(SINF SBLK "CDiskBlockIndex<%s>\n", ToString().c_str());
genesis 1212 }
genesis 1213 };
genesis 1214
genesis 1215
genesis 1216
genesis 1217
genesis 1218
genesis 1219
genesis 1220
genesis 1221
genesis 1222
genesis 1223
genesis 1224
genesis 1225
genesis 1226
genesis 1227 class CBlockLocator
genesis 1228 {
genesis 1229 protected:
genesis 1230 std::vector<uint256> vHave;
genesis 1231 public:
genesis 1232
genesis 1233 CBlockLocator()
genesis 1234 {
genesis 1235 }
genesis 1236
genesis 1237 explicit CBlockLocator(const CBlockIndex* pindex)
genesis 1238 {
genesis 1239 Set(pindex);
genesis 1240 }
genesis 1241
genesis 1242 explicit CBlockLocator(uint256 hashBlock)
genesis 1243 {
genesis 1244 std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
genesis 1245 if (mi != mapBlockIndex.end())
genesis 1246 Set((*mi).second);
genesis 1247 }
genesis 1248
genesis 1249 IMPLEMENT_SERIALIZE
genesis 1250 (
genesis 1251 if (!(nType & SER_GETHASH))
genesis 1252 READWRITE(nVersion);
genesis 1253 READWRITE(vHave);
genesis 1254 )
genesis 1255
genesis 1256 void SetNull()
genesis 1257 {
genesis 1258 vHave.clear();
genesis 1259 }
genesis 1260
genesis 1261 bool IsNull()
genesis 1262 {
genesis 1263 return vHave.empty();
genesis 1264 }
genesis 1265
genesis 1266 void Set(const CBlockIndex* pindex)
genesis 1267 {
genesis 1268 vHave.clear();
genesis 1269 int nStep = 1;
genesis 1270 while (pindex)
genesis 1271 {
genesis 1272 vHave.push_back(pindex->GetBlockHash());
genesis 1273
genesis 1274
genesis 1275 for (int i = 0; pindex && i < nStep; i++)
genesis 1276 pindex = pindex->pprev;
genesis 1277 if (vHave.size() > 10)
genesis 1278 nStep *= 2;
genesis 1279 }
genesis 1280 vHave.push_back(hashGenesisBlock);
genesis 1281 }
genesis 1282
genesis 1283 int GetDistanceBack()
genesis 1284 {
genesis 1285
genesis 1286 int nDistance = 0;
genesis 1287 int nStep = 1;
genesis 1288 BOOST_FOREACH(const uint256& hash, vHave)
genesis 1289 {
genesis 1290 std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
genesis 1291 if (mi != mapBlockIndex.end())
genesis 1292 {
genesis 1293 CBlockIndex* pindex = (*mi).second;
genesis 1294 if (pindex->IsInMainChain())
genesis 1295 return nDistance;
genesis 1296 }
genesis 1297 nDistance += nStep;
genesis 1298 if (nDistance > 10)
genesis 1299 nStep *= 2;
genesis 1300 }
genesis 1301 return nDistance;
genesis 1302 }
genesis 1303
genesis 1304 CBlockIndex* GetBlockIndex()
genesis 1305 {
genesis 1306
genesis 1307 BOOST_FOREACH(const uint256& hash, vHave)
genesis 1308 {
genesis 1309 std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
genesis 1310 if (mi != mapBlockIndex.end())
genesis 1311 {
genesis 1312 CBlockIndex* pindex = (*mi).second;
genesis 1313 if (pindex->IsInMainChain())
genesis 1314 return pindex;
genesis 1315 }
genesis 1316 }
genesis 1317 return pindexGenesisBlock;
genesis 1318 }
genesis 1319
genesis 1320 uint256 GetBlockHash()
genesis 1321 {
genesis 1322
genesis 1323 BOOST_FOREACH(const uint256& hash, vHave)
genesis 1324 {
genesis 1325 std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
genesis 1326 if (mi != mapBlockIndex.end())
genesis 1327 {
genesis 1328 CBlockIndex* pindex = (*mi).second;
genesis 1329 if (pindex->IsInMainChain())
genesis 1330 return hash;
genesis 1331 }
genesis 1332 }
genesis 1333 return hashGenesisBlock;
genesis 1334 }
genesis 1335
genesis 1336 int GetHeight()
genesis 1337 {
genesis 1338 CBlockIndex* pindex = GetBlockIndex();
genesis 1339 if (!pindex)
genesis 1340 return 0;
genesis 1341 return pindex->nHeight;
genesis 1342 }
genesis 1343 };
genesis 1344
genesis 1345 #endif