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