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