-
+ 06542E40FA8B01BBFE6964E46B6FFDF605E42F2DAAD2A14A64C3D70FD72A3ADDA5ADE3ADAE4D5016397F2C98249583D9B72462FF66E7EA4704E20083A639094A
bitcoin/src/main.h
(0 . 0)(1 . 1571)
12560 // Copyright (c) 2009-2010 Satoshi Nakamoto
12561 // Copyright (c) 2009-2012 The Bitcoin developers
12562 // Distributed under the MIT/X11 software license, see the accompanying
12563 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
12564 #ifndef BITCOIN_MAIN_H
12565 #define BITCOIN_MAIN_H
12566
12567 #include "bignum.h"
12568 #include "net.h"
12569 #include "key.h"
12570 #include "script.h"
12571 #include "db.h"
12572
12573 #include <list>
12574
12575 class CBlock;
12576 class CBlockIndex;
12577 class CWalletTx;
12578 class CWallet;
12579 class CKeyItem;
12580 class CReserveKey;
12581 class CWalletDB;
12582
12583 class CAddress;
12584 class CInv;
12585 class CRequestTracker;
12586 class CNode;
12587 class CBlockIndex;
12588
12589 static const unsigned int MAX_BLOCK_SIZE = 1000000;
12590 static const unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE/2;
12591 static const int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
12592 static const int MAX_ORPHAN_TRANSACTIONS = MAX_BLOCK_SIZE/100;
12593 static const int64 COIN = 100000000;
12594 static const int64 CENT = 1000000;
12595 static const int64 MIN_TX_FEE = 50000;
12596 static const int64 MIN_RELAY_TX_FEE = 10000;
12597 static const int64 MAX_MONEY = 21000000 * COIN;
12598 inline bool MoneyRange(int64 nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); }
12599 static const int COINBASE_MATURITY = 100;
12600 // Threshold for nLockTime: below this value it is interpreted as block number, otherwise as UNIX timestamp.
12601 static const int LOCKTIME_THRESHOLD = 500000000; // Tue Nov 5 00:53:20 1985 UTC
12602 #ifdef USE_UPNP
12603 static const int fHaveUPnP = true;
12604 #else
12605 static const int fHaveUPnP = false;
12606 #endif
12607
12608
12609
12610
12611
12612
12613 extern CCriticalSection cs_main;
12614 extern std::map<uint256, CBlockIndex*> mapBlockIndex;
12615 extern uint256 hashGenesisBlock;
12616 extern CBlockIndex* pindexGenesisBlock;
12617 extern int nBestHeight;
12618 extern CBigNum bnBestChainWork;
12619 extern CBigNum bnBestInvalidWork;
12620 extern uint256 hashBestChain;
12621 extern CBlockIndex* pindexBest;
12622 extern unsigned int nTransactionsUpdated;
12623 extern double dHashesPerSec;
12624 extern int64 nHPSTimerStart;
12625 extern int64 nTimeBestReceived;
12626 extern CCriticalSection cs_setpwalletRegistered;
12627 extern std::set<CWallet*> setpwalletRegistered;
12628
12629 // Settings
12630 extern int fGenerateBitcoins;
12631 extern int64 nTransactionFee;
12632 extern int fLimitProcessors;
12633 extern int nLimitProcessors;
12634 extern int fMinimizeToTray;
12635 extern int fMinimizeOnClose;
12636 extern int fUseUPnP;
12637
12638
12639
12640
12641
12642 class CReserveKey;
12643 class CTxDB;
12644 class CTxIndex;
12645
12646 void RegisterWallet(CWallet* pwalletIn);
12647 void UnregisterWallet(CWallet* pwalletIn);
12648 bool ProcessBlock(CNode* pfrom, CBlock* pblock);
12649 bool CheckDiskSpace(uint64 nAdditionalBytes=0);
12650 FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb");
12651 FILE* AppendBlockFile(unsigned int& nFileRet);
12652 bool LoadBlockIndex(bool fAllowNew=true);
12653 void PrintBlockTree();
12654 bool ProcessMessages(CNode* pfrom);
12655 bool SendMessages(CNode* pto, bool fSendTrickle);
12656 void GenerateBitcoins(bool fGenerate, CWallet* pwallet);
12657 CBlock* CreateNewBlock(CReserveKey& reservekey);
12658 void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
12659 void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1);
12660 bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey);
12661 bool CheckProofOfWork(uint256 hash, unsigned int nBits);
12662 unsigned int ComputeMinWork(unsigned int nBase, int64 nTime);
12663 int GetNumBlocksOfPeers();
12664 bool IsInitialBlockDownload();
12665 std::string GetWarnings(std::string strFor);
12666
12667
12668
12669
12670
12671
12672
12673
12674
12675
12676
12677
12678 bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut);
12679
12680 template<typename T>
12681 bool WriteSetting(const std::string& strKey, const T& value)
12682 {
12683 bool fOk = false;
12684 BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
12685 {
12686 std::string strWalletFile;
12687 if (!GetWalletFile(pwallet, strWalletFile))
12688 continue;
12689 fOk |= CWalletDB(strWalletFile).WriteSetting(strKey, value);
12690 }
12691 return fOk;
12692 }
12693
12694
12695 class CDiskTxPos
12696 {
12697 public:
12698 unsigned int nFile;
12699 unsigned int nBlockPos;
12700 unsigned int nTxPos;
12701
12702 CDiskTxPos()
12703 {
12704 SetNull();
12705 }
12706
12707 CDiskTxPos(unsigned int nFileIn, unsigned int nBlockPosIn, unsigned int nTxPosIn)
12708 {
12709 nFile = nFileIn;
12710 nBlockPos = nBlockPosIn;
12711 nTxPos = nTxPosIn;
12712 }
12713
12714 IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); )
12715 void SetNull() { nFile = -1; nBlockPos = 0; nTxPos = 0; }
12716 bool IsNull() const { return (nFile == -1); }
12717
12718 friend bool operator==(const CDiskTxPos& a, const CDiskTxPos& b)
12719 {
12720 return (a.nFile == b.nFile &&
12721 a.nBlockPos == b.nBlockPos &&
12722 a.nTxPos == b.nTxPos);
12723 }
12724
12725 friend bool operator!=(const CDiskTxPos& a, const CDiskTxPos& b)
12726 {
12727 return !(a == b);
12728 }
12729
12730 std::string ToString() const
12731 {
12732 if (IsNull())
12733 return strprintf("null");
12734 else
12735 return strprintf("(nFile=%d, nBlockPos=%d, nTxPos=%d)", nFile, nBlockPos, nTxPos);
12736 }
12737
12738 void print() const
12739 {
12740 printf("%s", ToString().c_str());
12741 }
12742 };
12743
12744
12745
12746
12747 class CInPoint
12748 {
12749 public:
12750 CTransaction* ptx;
12751 unsigned int n;
12752
12753 CInPoint() { SetNull(); }
12754 CInPoint(CTransaction* ptxIn, unsigned int nIn) { ptx = ptxIn; n = nIn; }
12755 void SetNull() { ptx = NULL; n = -1; }
12756 bool IsNull() const { return (ptx == NULL && n == -1); }
12757 };
12758
12759
12760
12761
12762 class COutPoint
12763 {
12764 public:
12765 uint256 hash;
12766 unsigned int n;
12767
12768 COutPoint() { SetNull(); }
12769 COutPoint(uint256 hashIn, unsigned int nIn) { hash = hashIn; n = nIn; }
12770 IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); )
12771 void SetNull() { hash = 0; n = -1; }
12772 bool IsNull() const { return (hash == 0 && n == -1); }
12773
12774 friend bool operator<(const COutPoint& a, const COutPoint& b)
12775 {
12776 return (a.hash < b.hash || (a.hash == b.hash && a.n < b.n));
12777 }
12778
12779 friend bool operator==(const COutPoint& a, const COutPoint& b)
12780 {
12781 return (a.hash == b.hash && a.n == b.n);
12782 }
12783
12784 friend bool operator!=(const COutPoint& a, const COutPoint& b)
12785 {
12786 return !(a == b);
12787 }
12788
12789 std::string ToString() const
12790 {
12791 return strprintf("COutPoint(%s, %d)", hash.ToString().substr(0,10).c_str(), n);
12792 }
12793
12794 void print() const
12795 {
12796 printf("%s\n", ToString().c_str());
12797 }
12798 };
12799
12800
12801
12802
12803 //
12804 // An input of a transaction. It contains the location of the previous
12805 // transaction's output that it claims and a signature that matches the
12806 // output's public key.
12807 //
12808 class CTxIn
12809 {
12810 public:
12811 COutPoint prevout;
12812 CScript scriptSig;
12813 unsigned int nSequence;
12814
12815 CTxIn()
12816 {
12817 nSequence = UINT_MAX;
12818 }
12819
12820 explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX)
12821 {
12822 prevout = prevoutIn;
12823 scriptSig = scriptSigIn;
12824 nSequence = nSequenceIn;
12825 }
12826
12827 CTxIn(uint256 hashPrevTx, unsigned int nOut, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX)
12828 {
12829 prevout = COutPoint(hashPrevTx, nOut);
12830 scriptSig = scriptSigIn;
12831 nSequence = nSequenceIn;
12832 }
12833
12834 IMPLEMENT_SERIALIZE
12835 (
12836 READWRITE(prevout);
12837 READWRITE(scriptSig);
12838 READWRITE(nSequence);
12839 )
12840
12841 bool IsFinal() const
12842 {
12843 return (nSequence == UINT_MAX);
12844 }
12845
12846 friend bool operator==(const CTxIn& a, const CTxIn& b)
12847 {
12848 return (a.prevout == b.prevout &&
12849 a.scriptSig == b.scriptSig &&
12850 a.nSequence == b.nSequence);
12851 }
12852
12853 friend bool operator!=(const CTxIn& a, const CTxIn& b)
12854 {
12855 return !(a == b);
12856 }
12857
12858 std::string ToString() const
12859 {
12860 std::string str;
12861 str += strprintf("CTxIn(");
12862 str += prevout.ToString();
12863 if (prevout.IsNull())
12864 str += strprintf(", coinbase %s", HexStr(scriptSig).c_str());
12865 else
12866 str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24).c_str());
12867 if (nSequence != UINT_MAX)
12868 str += strprintf(", nSequence=%u", nSequence);
12869 str += ")";
12870 return str;
12871 }
12872
12873 void print() const
12874 {
12875 printf("%s\n", ToString().c_str());
12876 }
12877 };
12878
12879
12880
12881
12882 //
12883 // An output of a transaction. It contains the public key that the next input
12884 // must be able to sign with to claim it.
12885 //
12886 class CTxOut
12887 {
12888 public:
12889 int64 nValue;
12890 CScript scriptPubKey;
12891
12892 CTxOut()
12893 {
12894 SetNull();
12895 }
12896
12897 CTxOut(int64 nValueIn, CScript scriptPubKeyIn)
12898 {
12899 nValue = nValueIn;
12900 scriptPubKey = scriptPubKeyIn;
12901 }
12902
12903 IMPLEMENT_SERIALIZE
12904 (
12905 READWRITE(nValue);
12906 READWRITE(scriptPubKey);
12907 )
12908
12909 void SetNull()
12910 {
12911 nValue = -1;
12912 scriptPubKey.clear();
12913 }
12914
12915 bool IsNull()
12916 {
12917 return (nValue == -1);
12918 }
12919
12920 uint256 GetHash() const
12921 {
12922 return SerializeHash(*this);
12923 }
12924
12925 friend bool operator==(const CTxOut& a, const CTxOut& b)
12926 {
12927 return (a.nValue == b.nValue &&
12928 a.scriptPubKey == b.scriptPubKey);
12929 }
12930
12931 friend bool operator!=(const CTxOut& a, const CTxOut& b)
12932 {
12933 return !(a == b);
12934 }
12935
12936 std::string ToString() const
12937 {
12938 if (scriptPubKey.size() < 6)
12939 return "CTxOut(error)";
12940 return strprintf("CTxOut(nValue=%"PRI64d".%08"PRI64d", scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,30).c_str());
12941 }
12942
12943 void print() const
12944 {
12945 printf("%s\n", ToString().c_str());
12946 }
12947 };
12948
12949
12950
12951
12952 //
12953 // The basic transaction that is broadcasted on the network and contained in
12954 // blocks. A transaction can contain multiple inputs and outputs.
12955 //
12956 class CTransaction
12957 {
12958 public:
12959 int nVersion;
12960 std::vector<CTxIn> vin;
12961 std::vector<CTxOut> vout;
12962 unsigned int nLockTime;
12963
12964 // Denial-of-service detection:
12965 mutable int nDoS;
12966 bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; }
12967
12968 CTransaction()
12969 {
12970 SetNull();
12971 }
12972
12973 IMPLEMENT_SERIALIZE
12974 (
12975 READWRITE(this->nVersion);
12976 nVersion = this->nVersion;
12977 READWRITE(vin);
12978 READWRITE(vout);
12979 READWRITE(nLockTime);
12980 )
12981
12982 void SetNull()
12983 {
12984 nVersion = 1;
12985 vin.clear();
12986 vout.clear();
12987 nLockTime = 0;
12988 nDoS = 0; // Denial-of-service prevention
12989 }
12990
12991 bool IsNull() const
12992 {
12993 return (vin.empty() && vout.empty());
12994 }
12995
12996 uint256 GetHash() const
12997 {
12998 return SerializeHash(*this);
12999 }
13000
13001 bool IsFinal(int nBlockHeight=0, int64 nBlockTime=0) const
13002 {
13003 // Time based nLockTime implemented in 0.1.6
13004 if (nLockTime == 0)
13005 return true;
13006 if (nBlockHeight == 0)
13007 nBlockHeight = nBestHeight;
13008 if (nBlockTime == 0)
13009 nBlockTime = GetAdjustedTime();
13010 if ((int64)nLockTime < (nLockTime < LOCKTIME_THRESHOLD ? (int64)nBlockHeight : nBlockTime))
13011 return true;
13012 BOOST_FOREACH(const CTxIn& txin, vin)
13013 if (!txin.IsFinal())
13014 return false;
13015 return true;
13016 }
13017
13018 bool IsNewerThan(const CTransaction& old) const
13019 {
13020 if (vin.size() != old.vin.size())
13021 return false;
13022 for (int i = 0; i < vin.size(); i++)
13023 if (vin[i].prevout != old.vin[i].prevout)
13024 return false;
13025
13026 bool fNewer = false;
13027 unsigned int nLowest = UINT_MAX;
13028 for (int i = 0; i < vin.size(); i++)
13029 {
13030 if (vin[i].nSequence != old.vin[i].nSequence)
13031 {
13032 if (vin[i].nSequence <= nLowest)
13033 {
13034 fNewer = false;
13035 nLowest = vin[i].nSequence;
13036 }
13037 if (old.vin[i].nSequence < nLowest)
13038 {
13039 fNewer = true;
13040 nLowest = old.vin[i].nSequence;
13041 }
13042 }
13043 }
13044 return fNewer;
13045 }
13046
13047 bool IsCoinBase() const
13048 {
13049 return (vin.size() == 1 && vin[0].prevout.IsNull());
13050 }
13051
13052 int GetSigOpCount() const
13053 {
13054 int n = 0;
13055 BOOST_FOREACH(const CTxIn& txin, vin)
13056 n += txin.scriptSig.GetSigOpCount();
13057 BOOST_FOREACH(const CTxOut& txout, vout)
13058 n += txout.scriptPubKey.GetSigOpCount();
13059 return n;
13060 }
13061
13062 bool IsStandard() const
13063 {
13064 BOOST_FOREACH(const CTxIn& txin, vin)
13065 if (!txin.scriptSig.IsPushOnly())
13066 return error("nonstandard txin: %s", txin.scriptSig.ToString().c_str());
13067 BOOST_FOREACH(const CTxOut& txout, vout)
13068 if (!::IsStandard(txout.scriptPubKey))
13069 return error("nonstandard txout: %s", txout.scriptPubKey.ToString().c_str());
13070 return true;
13071 }
13072
13073 int64 GetValueOut() const
13074 {
13075 int64 nValueOut = 0;
13076 BOOST_FOREACH(const CTxOut& txout, vout)
13077 {
13078 nValueOut += txout.nValue;
13079 if (!MoneyRange(txout.nValue) || !MoneyRange(nValueOut))
13080 throw std::runtime_error("CTransaction::GetValueOut() : value out of range");
13081 }
13082 return nValueOut;
13083 }
13084
13085 static bool AllowFree(double dPriority)
13086 {
13087 // Large (in bytes) low-priority (new, small-coin) transactions
13088 // need a fee.
13089 return dPriority > COIN * 144 / 250;
13090 }
13091
13092 int64 GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=true, bool fForRelay=false) const
13093 {
13094 // Base fee is either MIN_TX_FEE or MIN_RELAY_TX_FEE
13095 int64 nBaseFee = fForRelay ? MIN_RELAY_TX_FEE : MIN_TX_FEE;
13096
13097 unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK);
13098 unsigned int nNewBlockSize = nBlockSize + nBytes;
13099 int64 nMinFee = (1 + (int64)nBytes / 1000) * nBaseFee;
13100
13101 if (fAllowFree)
13102 {
13103 if (nBlockSize == 1)
13104 {
13105 // Transactions under 10K are free
13106 // (about 4500bc if made of 50bc inputs)
13107 if (nBytes < 10000)
13108 nMinFee = 0;
13109 }
13110 else
13111 {
13112 // Free transaction area
13113 if (nNewBlockSize < 27000)
13114 nMinFee = 0;
13115 }
13116 }
13117
13118 // To limit dust spam, require MIN_TX_FEE/MIN_RELAY_TX_FEE if any output is less than 0.01
13119 if (nMinFee < nBaseFee)
13120 BOOST_FOREACH(const CTxOut& txout, vout)
13121 if (txout.nValue < CENT)
13122 nMinFee = nBaseFee;
13123
13124 // Raise the price as the block approaches full
13125 if (nBlockSize != 1 && nNewBlockSize >= MAX_BLOCK_SIZE_GEN/2)
13126 {
13127 if (nNewBlockSize >= MAX_BLOCK_SIZE_GEN)
13128 return MAX_MONEY;
13129 nMinFee *= MAX_BLOCK_SIZE_GEN / (MAX_BLOCK_SIZE_GEN - nNewBlockSize);
13130 }
13131
13132 if (!MoneyRange(nMinFee))
13133 nMinFee = MAX_MONEY;
13134 return nMinFee;
13135 }
13136
13137
13138 bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL)
13139 {
13140 CAutoFile filein = OpenBlockFile(pos.nFile, 0, pfileRet ? "rb+" : "rb");
13141 if (!filein)
13142 return error("CTransaction::ReadFromDisk() : OpenBlockFile failed");
13143
13144 // Read transaction
13145 if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)
13146 return error("CTransaction::ReadFromDisk() : fseek failed");
13147 filein >> *this;
13148
13149 // Return file pointer
13150 if (pfileRet)
13151 {
13152 if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)
13153 return error("CTransaction::ReadFromDisk() : second fseek failed");
13154 *pfileRet = filein.release();
13155 }
13156 return true;
13157 }
13158
13159 friend bool operator==(const CTransaction& a, const CTransaction& b)
13160 {
13161 return (a.nVersion == b.nVersion &&
13162 a.vin == b.vin &&
13163 a.vout == b.vout &&
13164 a.nLockTime == b.nLockTime);
13165 }
13166
13167 friend bool operator!=(const CTransaction& a, const CTransaction& b)
13168 {
13169 return !(a == b);
13170 }
13171
13172
13173 std::string ToString() const
13174 {
13175 std::string str;
13176 str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%d, vout.size=%d, nLockTime=%d)\n",
13177 GetHash().ToString().substr(0,10).c_str(),
13178 nVersion,
13179 vin.size(),
13180 vout.size(),
13181 nLockTime);
13182 for (int i = 0; i < vin.size(); i++)
13183 str += " " + vin[i].ToString() + "\n";
13184 for (int i = 0; i < vout.size(); i++)
13185 str += " " + vout[i].ToString() + "\n";
13186 return str;
13187 }
13188
13189 void print() const
13190 {
13191 printf("%s", ToString().c_str());
13192 }
13193
13194
13195 bool ReadFromDisk(CTxDB& txdb, COutPoint prevout, CTxIndex& txindexRet);
13196 bool ReadFromDisk(CTxDB& txdb, COutPoint prevout);
13197 bool ReadFromDisk(COutPoint prevout);
13198 bool DisconnectInputs(CTxDB& txdb);
13199 bool ConnectInputs(CTxDB& txdb, std::map<uint256, CTxIndex>& mapTestPool, CDiskTxPos posThisTx,
13200 CBlockIndex* pindexBlock, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee,
13201 bool& fInvalid);
13202 bool ClientConnectInputs();
13203 bool CheckTransaction() const;
13204 bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL);
13205 bool AcceptToMemoryPool(bool fCheckInputs=true, bool* pfMissingInputs=NULL);
13206 protected:
13207 bool AddToMemoryPoolUnchecked();
13208 public:
13209 bool RemoveFromMemoryPool();
13210 };
13211
13212
13213
13214
13215
13216 //
13217 // A transaction with a merkle branch linking it to the block chain
13218 //
13219 class CMerkleTx : public CTransaction
13220 {
13221 public:
13222 uint256 hashBlock;
13223 std::vector<uint256> vMerkleBranch;
13224 int nIndex;
13225
13226 // memory only
13227 mutable char fMerkleVerified;
13228
13229
13230 CMerkleTx()
13231 {
13232 Init();
13233 }
13234
13235 CMerkleTx(const CTransaction& txIn) : CTransaction(txIn)
13236 {
13237 Init();
13238 }
13239
13240 void Init()
13241 {
13242 hashBlock = 0;
13243 nIndex = -1;
13244 fMerkleVerified = false;
13245 }
13246
13247
13248 IMPLEMENT_SERIALIZE
13249 (
13250 nSerSize += SerReadWrite(s, *(CTransaction*)this, nType, nVersion, ser_action);
13251 nVersion = this->nVersion;
13252 READWRITE(hashBlock);
13253 READWRITE(vMerkleBranch);
13254 READWRITE(nIndex);
13255 )
13256
13257
13258 int SetMerkleBranch(const CBlock* pblock=NULL);
13259 int GetDepthInMainChain(int& nHeightRet) const;
13260 int GetDepthInMainChain() const { int nHeight; return GetDepthInMainChain(nHeight); }
13261 bool IsInMainChain() const { return GetDepthInMainChain() > 0; }
13262 int GetBlocksToMaturity() const;
13263 bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true);
13264 bool AcceptToMemoryPool();
13265 };
13266
13267
13268
13269
13270 //
13271 // A txdb record that contains the disk location of a transaction and the
13272 // locations of transactions that spend its outputs. vSpent is really only
13273 // used as a flag, but having the location is very helpful for debugging.
13274 //
13275 class CTxIndex
13276 {
13277 public:
13278 CDiskTxPos pos;
13279 std::vector<CDiskTxPos> vSpent;
13280
13281 CTxIndex()
13282 {
13283 SetNull();
13284 }
13285
13286 CTxIndex(const CDiskTxPos& posIn, unsigned int nOutputs)
13287 {
13288 pos = posIn;
13289 vSpent.resize(nOutputs);
13290 }
13291
13292 IMPLEMENT_SERIALIZE
13293 (
13294 if (!(nType & SER_GETHASH))
13295 READWRITE(nVersion);
13296 READWRITE(pos);
13297 READWRITE(vSpent);
13298 )
13299
13300 void SetNull()
13301 {
13302 pos.SetNull();
13303 vSpent.clear();
13304 }
13305
13306 bool IsNull()
13307 {
13308 return pos.IsNull();
13309 }
13310
13311 friend bool operator==(const CTxIndex& a, const CTxIndex& b)
13312 {
13313 return (a.pos == b.pos &&
13314 a.vSpent == b.vSpent);
13315 }
13316
13317 friend bool operator!=(const CTxIndex& a, const CTxIndex& b)
13318 {
13319 return !(a == b);
13320 }
13321 int GetDepthInMainChain() const;
13322 };
13323
13324
13325
13326
13327
13328 //
13329 // Nodes collect new transactions into a block, hash them into a hash tree,
13330 // and scan through nonce values to make the block's hash satisfy proof-of-work
13331 // requirements. When they solve the proof-of-work, they broadcast the block
13332 // to everyone and the block is added to the block chain. The first transaction
13333 // in the block is a special one that creates a new coin owned by the creator
13334 // of the block.
13335 //
13336 // Blocks are appended to blk0001.dat files on disk. Their location on disk
13337 // is indexed by CBlockIndex objects in memory.
13338 //
13339 class CBlock
13340 {
13341 public:
13342 // header
13343 int nVersion;
13344 uint256 hashPrevBlock;
13345 uint256 hashMerkleRoot;
13346 unsigned int nTime;
13347 unsigned int nBits;
13348 unsigned int nNonce;
13349
13350 // network and disk
13351 std::vector<CTransaction> vtx;
13352
13353 // memory only
13354 mutable std::vector<uint256> vMerkleTree;
13355
13356 // Denial-of-service detection:
13357 mutable int nDoS;
13358 bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; }
13359
13360 CBlock()
13361 {
13362 SetNull();
13363 }
13364
13365 IMPLEMENT_SERIALIZE
13366 (
13367 READWRITE(this->nVersion);
13368 nVersion = this->nVersion;
13369 READWRITE(hashPrevBlock);
13370 READWRITE(hashMerkleRoot);
13371 READWRITE(nTime);
13372 READWRITE(nBits);
13373 READWRITE(nNonce);
13374
13375 // ConnectBlock depends on vtx being last so it can calculate offset
13376 if (!(nType & (SER_GETHASH|SER_BLOCKHEADERONLY)))
13377 READWRITE(vtx);
13378 else if (fRead)
13379 const_cast<CBlock*>(this)->vtx.clear();
13380 )
13381
13382 void SetNull()
13383 {
13384 nVersion = 1;
13385 hashPrevBlock = 0;
13386 hashMerkleRoot = 0;
13387 nTime = 0;
13388 nBits = 0;
13389 nNonce = 0;
13390 vtx.clear();
13391 vMerkleTree.clear();
13392 nDoS = 0;
13393 }
13394
13395 bool IsNull() const
13396 {
13397 return (nBits == 0);
13398 }
13399
13400 uint256 GetHash() const
13401 {
13402 return Hash(BEGIN(nVersion), END(nNonce));
13403 }
13404
13405 int64 GetBlockTime() const
13406 {
13407 return (int64)nTime;
13408 }
13409
13410 int GetSigOpCount() const
13411 {
13412 int n = 0;
13413 BOOST_FOREACH(const CTransaction& tx, vtx)
13414 n += tx.GetSigOpCount();
13415 return n;
13416 }
13417
13418
13419 uint256 BuildMerkleTree() const
13420 {
13421 vMerkleTree.clear();
13422 BOOST_FOREACH(const CTransaction& tx, vtx)
13423 vMerkleTree.push_back(tx.GetHash());
13424 int j = 0;
13425 for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
13426 {
13427 for (int i = 0; i < nSize; i += 2)
13428 {
13429 int i2 = std::min(i+1, nSize-1);
13430 vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]), END(vMerkleTree[j+i]),
13431 BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2])));
13432 }
13433 j += nSize;
13434 }
13435 return (vMerkleTree.empty() ? 0 : vMerkleTree.back());
13436 }
13437
13438 std::vector<uint256> GetMerkleBranch(int nIndex) const
13439 {
13440 if (vMerkleTree.empty())
13441 BuildMerkleTree();
13442 std::vector<uint256> vMerkleBranch;
13443 int j = 0;
13444 for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
13445 {
13446 int i = std::min(nIndex^1, nSize-1);
13447 vMerkleBranch.push_back(vMerkleTree[j+i]);
13448 nIndex >>= 1;
13449 j += nSize;
13450 }
13451 return vMerkleBranch;
13452 }
13453
13454 static uint256 CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex)
13455 {
13456 if (nIndex == -1)
13457 return 0;
13458 BOOST_FOREACH(const uint256& otherside, vMerkleBranch)
13459 {
13460 if (nIndex & 1)
13461 hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash));
13462 else
13463 hash = Hash(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside));
13464 nIndex >>= 1;
13465 }
13466 return hash;
13467 }
13468
13469
13470 bool WriteToDisk(unsigned int& nFileRet, unsigned int& nBlockPosRet)
13471 {
13472 // Open history file to append
13473 CAutoFile fileout = AppendBlockFile(nFileRet);
13474 if (!fileout)
13475 return error("CBlock::WriteToDisk() : AppendBlockFile failed");
13476
13477 // Write index header
13478 unsigned int nSize = fileout.GetSerializeSize(*this);
13479 fileout << FLATDATA(pchMessageStart) << nSize;
13480
13481 // Write block
13482 nBlockPosRet = ftell(fileout);
13483 if (nBlockPosRet == -1)
13484 return error("CBlock::WriteToDisk() : ftell failed");
13485 fileout << *this;
13486
13487 // Flush stdio buffers and commit to disk before returning
13488 fflush(fileout);
13489 if (!IsInitialBlockDownload() || (nBestHeight+1) % 500 == 0)
13490 {
13491 #ifdef WIN32
13492 _commit(_fileno(fileout));
13493 #else
13494 fsync(fileno(fileout));
13495 #endif
13496 }
13497
13498 return true;
13499 }
13500
13501 bool ReadFromDisk(unsigned int nFile, unsigned int nBlockPos, bool fReadTransactions=true)
13502 {
13503 SetNull();
13504
13505 // Open history file to read
13506 CAutoFile filein = OpenBlockFile(nFile, nBlockPos, "rb");
13507 if (!filein)
13508 return error("CBlock::ReadFromDisk() : OpenBlockFile failed");
13509 if (!fReadTransactions)
13510 filein.nType |= SER_BLOCKHEADERONLY;
13511
13512 // Read block
13513 filein >> *this;
13514
13515 // Check the header
13516 if (!CheckProofOfWork(GetHash(), nBits))
13517 return error("CBlock::ReadFromDisk() : errors in block header");
13518
13519 return true;
13520 }
13521
13522
13523
13524 void print() const
13525 {
13526 printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%d)\n",
13527 GetHash().ToString().substr(0,20).c_str(),
13528 nVersion,
13529 hashPrevBlock.ToString().substr(0,20).c_str(),
13530 hashMerkleRoot.ToString().substr(0,10).c_str(),
13531 nTime, nBits, nNonce,
13532 vtx.size());
13533 for (int i = 0; i < vtx.size(); i++)
13534 {
13535 printf(" ");
13536 vtx[i].print();
13537 }
13538 printf(" vMerkleTree: ");
13539 for (int i = 0; i < vMerkleTree.size(); i++)
13540 printf("%s ", vMerkleTree[i].ToString().substr(0,10).c_str());
13541 printf("\n");
13542 }
13543
13544
13545 bool DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex);
13546 bool ConnectBlock(CTxDB& txdb, CBlockIndex* pindex);
13547 bool ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions=true);
13548 bool SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew);
13549 bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos);
13550 bool CheckBlock() const;
13551 bool AcceptBlock();
13552 };
13553
13554
13555
13556
13557
13558
13559 //
13560 // The block chain is a tree shaped structure starting with the
13561 // genesis block at the root, with each block potentially having multiple
13562 // candidates to be the next block. pprev and pnext link a path through the
13563 // main/longest chain. A blockindex may have multiple pprev pointing back
13564 // to it, but pnext will only point forward to the longest branch, or will
13565 // be null if the block is not part of the longest chain.
13566 //
13567 class CBlockIndex
13568 {
13569 public:
13570 const uint256* phashBlock;
13571 CBlockIndex* pprev;
13572 CBlockIndex* pnext;
13573 unsigned int nFile;
13574 unsigned int nBlockPos;
13575 int nHeight;
13576 CBigNum bnChainWork;
13577
13578 // block header
13579 int nVersion;
13580 uint256 hashMerkleRoot;
13581 unsigned int nTime;
13582 unsigned int nBits;
13583 unsigned int nNonce;
13584
13585
13586 CBlockIndex()
13587 {
13588 phashBlock = NULL;
13589 pprev = NULL;
13590 pnext = NULL;
13591 nFile = 0;
13592 nBlockPos = 0;
13593 nHeight = 0;
13594 bnChainWork = 0;
13595
13596 nVersion = 0;
13597 hashMerkleRoot = 0;
13598 nTime = 0;
13599 nBits = 0;
13600 nNonce = 0;
13601 }
13602
13603 CBlockIndex(unsigned int nFileIn, unsigned int nBlockPosIn, CBlock& block)
13604 {
13605 phashBlock = NULL;
13606 pprev = NULL;
13607 pnext = NULL;
13608 nFile = nFileIn;
13609 nBlockPos = nBlockPosIn;
13610 nHeight = 0;
13611 bnChainWork = 0;
13612
13613 nVersion = block.nVersion;
13614 hashMerkleRoot = block.hashMerkleRoot;
13615 nTime = block.nTime;
13616 nBits = block.nBits;
13617 nNonce = block.nNonce;
13618 }
13619
13620 CBlock GetBlockHeader() const
13621 {
13622 CBlock block;
13623 block.nVersion = nVersion;
13624 if (pprev)
13625 block.hashPrevBlock = pprev->GetBlockHash();
13626 block.hashMerkleRoot = hashMerkleRoot;
13627 block.nTime = nTime;
13628 block.nBits = nBits;
13629 block.nNonce = nNonce;
13630 return block;
13631 }
13632
13633 uint256 GetBlockHash() const
13634 {
13635 return *phashBlock;
13636 }
13637
13638 int64 GetBlockTime() const
13639 {
13640 return (int64)nTime;
13641 }
13642
13643 CBigNum GetBlockWork() const
13644 {
13645 CBigNum bnTarget;
13646 bnTarget.SetCompact(nBits);
13647 if (bnTarget <= 0)
13648 return 0;
13649 return (CBigNum(1)<<256) / (bnTarget+1);
13650 }
13651
13652 bool IsInMainChain() const
13653 {
13654 return (pnext || this == pindexBest);
13655 }
13656
13657 bool CheckIndex() const
13658 {
13659 return CheckProofOfWork(GetBlockHash(), nBits);
13660 }
13661
13662 bool EraseBlockFromDisk()
13663 {
13664 // Open history file
13665 CAutoFile fileout = OpenBlockFile(nFile, nBlockPos, "rb+");
13666 if (!fileout)
13667 return false;
13668
13669 // Overwrite with empty null block
13670 CBlock block;
13671 block.SetNull();
13672 fileout << block;
13673
13674 return true;
13675 }
13676
13677 enum { nMedianTimeSpan=11 };
13678
13679 int64 GetMedianTimePast() const
13680 {
13681 int64 pmedian[nMedianTimeSpan];
13682 int64* pbegin = &pmedian[nMedianTimeSpan];
13683 int64* pend = &pmedian[nMedianTimeSpan];
13684
13685 const CBlockIndex* pindex = this;
13686 for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev)
13687 *(--pbegin) = pindex->GetBlockTime();
13688
13689 std::sort(pbegin, pend);
13690 return pbegin[(pend - pbegin)/2];
13691 }
13692
13693 int64 GetMedianTime() const
13694 {
13695 const CBlockIndex* pindex = this;
13696 for (int i = 0; i < nMedianTimeSpan/2; i++)
13697 {
13698 if (!pindex->pnext)
13699 return GetBlockTime();
13700 pindex = pindex->pnext;
13701 }
13702 return pindex->GetMedianTimePast();
13703 }
13704
13705
13706
13707 std::string ToString() const
13708 {
13709 return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)",
13710 pprev, pnext, nFile, nBlockPos, nHeight,
13711 hashMerkleRoot.ToString().substr(0,10).c_str(),
13712 GetBlockHash().ToString().substr(0,20).c_str());
13713 }
13714
13715 void print() const
13716 {
13717 printf("%s\n", ToString().c_str());
13718 }
13719 };
13720
13721
13722
13723 //
13724 // Used to marshal pointers into hashes for db storage.
13725 //
13726 class CDiskBlockIndex : public CBlockIndex
13727 {
13728 public:
13729 uint256 hashPrev;
13730 uint256 hashNext;
13731
13732 CDiskBlockIndex()
13733 {
13734 hashPrev = 0;
13735 hashNext = 0;
13736 }
13737
13738 explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex)
13739 {
13740 hashPrev = (pprev ? pprev->GetBlockHash() : 0);
13741 hashNext = (pnext ? pnext->GetBlockHash() : 0);
13742 }
13743
13744 IMPLEMENT_SERIALIZE
13745 (
13746 if (!(nType & SER_GETHASH))
13747 READWRITE(nVersion);
13748
13749 READWRITE(hashNext);
13750 READWRITE(nFile);
13751 READWRITE(nBlockPos);
13752 READWRITE(nHeight);
13753
13754 // block header
13755 READWRITE(this->nVersion);
13756 READWRITE(hashPrev);
13757 READWRITE(hashMerkleRoot);
13758 READWRITE(nTime);
13759 READWRITE(nBits);
13760 READWRITE(nNonce);
13761 )
13762
13763 uint256 GetBlockHash() const
13764 {
13765 CBlock block;
13766 block.nVersion = nVersion;
13767 block.hashPrevBlock = hashPrev;
13768 block.hashMerkleRoot = hashMerkleRoot;
13769 block.nTime = nTime;
13770 block.nBits = nBits;
13771 block.nNonce = nNonce;
13772 return block.GetHash();
13773 }
13774
13775
13776 std::string ToString() const
13777 {
13778 std::string str = "CDiskBlockIndex(";
13779 str += CBlockIndex::ToString();
13780 str += strprintf("\n hashBlock=%s, hashPrev=%s, hashNext=%s)",
13781 GetBlockHash().ToString().c_str(),
13782 hashPrev.ToString().substr(0,20).c_str(),
13783 hashNext.ToString().substr(0,20).c_str());
13784 return str;
13785 }
13786
13787 void print() const
13788 {
13789 printf("%s\n", ToString().c_str());
13790 }
13791 };
13792
13793
13794
13795
13796
13797
13798
13799
13800 //
13801 // Describes a place in the block chain to another node such that if the
13802 // other node doesn't have the same branch, it can find a recent common trunk.
13803 // The further back it is, the further before the fork it may be.
13804 //
13805 class CBlockLocator
13806 {
13807 protected:
13808 std::vector<uint256> vHave;
13809 public:
13810
13811 CBlockLocator()
13812 {
13813 }
13814
13815 explicit CBlockLocator(const CBlockIndex* pindex)
13816 {
13817 Set(pindex);
13818 }
13819
13820 explicit CBlockLocator(uint256 hashBlock)
13821 {
13822 std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
13823 if (mi != mapBlockIndex.end())
13824 Set((*mi).second);
13825 }
13826
13827 IMPLEMENT_SERIALIZE
13828 (
13829 if (!(nType & SER_GETHASH))
13830 READWRITE(nVersion);
13831 READWRITE(vHave);
13832 )
13833
13834 void SetNull()
13835 {
13836 vHave.clear();
13837 }
13838
13839 bool IsNull()
13840 {
13841 return vHave.empty();
13842 }
13843
13844 void Set(const CBlockIndex* pindex)
13845 {
13846 vHave.clear();
13847 int nStep = 1;
13848 while (pindex)
13849 {
13850 vHave.push_back(pindex->GetBlockHash());
13851
13852 // Exponentially larger steps back
13853 for (int i = 0; pindex && i < nStep; i++)
13854 pindex = pindex->pprev;
13855 if (vHave.size() > 10)
13856 nStep *= 2;
13857 }
13858 vHave.push_back(hashGenesisBlock);
13859 }
13860
13861 int GetDistanceBack()
13862 {
13863 // Retrace how far back it was in the sender's branch
13864 int nDistance = 0;
13865 int nStep = 1;
13866 BOOST_FOREACH(const uint256& hash, vHave)
13867 {
13868 std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
13869 if (mi != mapBlockIndex.end())
13870 {
13871 CBlockIndex* pindex = (*mi).second;
13872 if (pindex->IsInMainChain())
13873 return nDistance;
13874 }
13875 nDistance += nStep;
13876 if (nDistance > 10)
13877 nStep *= 2;
13878 }
13879 return nDistance;
13880 }
13881
13882 CBlockIndex* GetBlockIndex()
13883 {
13884 // Find the first block the caller has in the main chain
13885 BOOST_FOREACH(const uint256& hash, vHave)
13886 {
13887 std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
13888 if (mi != mapBlockIndex.end())
13889 {
13890 CBlockIndex* pindex = (*mi).second;
13891 if (pindex->IsInMainChain())
13892 return pindex;
13893 }
13894 }
13895 return pindexGenesisBlock;
13896 }
13897
13898 uint256 GetBlockHash()
13899 {
13900 // Find the first block the caller has in the main chain
13901 BOOST_FOREACH(const uint256& hash, vHave)
13902 {
13903 std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
13904 if (mi != mapBlockIndex.end())
13905 {
13906 CBlockIndex* pindex = (*mi).second;
13907 if (pindex->IsInMainChain())
13908 return hash;
13909 }
13910 }
13911 return hashGenesisBlock;
13912 }
13913
13914 int GetHeight()
13915 {
13916 CBlockIndex* pindex = GetBlockIndex();
13917 if (!pindex)
13918 return 0;
13919 return pindex->nHeight;
13920 }
13921 };
13922
13923
13924
13925
13926
13927
13928
13929
13930
13931 //
13932 // Alerts are for notifying old versions if they become too obsolete and
13933 // need to upgrade. The message is displayed in the status bar.
13934 // Alert messages are broadcast as a vector of signed data. Unserializing may
13935 // not read the entire buffer if the alert is for a newer version, but older
13936 // versions can still relay the original data.
13937 //
13938 class CUnsignedAlert
13939 {
13940 public:
13941 int nVersion;
13942 int64 nRelayUntil; // when newer nodes stop relaying to newer nodes
13943 int64 nExpiration;
13944 int nID;
13945 int nCancel;
13946 std::set<int> setCancel;
13947 int nMinVer; // lowest version inclusive
13948 int nMaxVer; // highest version inclusive
13949 std::set<std::string> setSubVer; // empty matches all
13950 int nPriority;
13951
13952 // Actions
13953 std::string strComment;
13954 std::string strStatusBar;
13955 std::string strReserved;
13956
13957 IMPLEMENT_SERIALIZE
13958 (
13959 READWRITE(this->nVersion);
13960 nVersion = this->nVersion;
13961 READWRITE(nRelayUntil);
13962 READWRITE(nExpiration);
13963 READWRITE(nID);
13964 READWRITE(nCancel);
13965 READWRITE(setCancel);
13966 READWRITE(nMinVer);
13967 READWRITE(nMaxVer);
13968 READWRITE(setSubVer);
13969 READWRITE(nPriority);
13970
13971 READWRITE(strComment);
13972 READWRITE(strStatusBar);
13973 READWRITE(strReserved);
13974 )
13975
13976 void SetNull()
13977 {
13978 nVersion = 1;
13979 nRelayUntil = 0;
13980 nExpiration = 0;
13981 nID = 0;
13982 nCancel = 0;
13983 setCancel.clear();
13984 nMinVer = 0;
13985 nMaxVer = 0;
13986 setSubVer.clear();
13987 nPriority = 0;
13988
13989 strComment.clear();
13990 strStatusBar.clear();
13991 strReserved.clear();
13992 }
13993
13994 std::string ToString() const
13995 {
13996 std::string strSetCancel;
13997 BOOST_FOREACH(int n, setCancel)
13998 strSetCancel += strprintf("%d ", n);
13999 std::string strSetSubVer;
14000 BOOST_FOREACH(std::string str, setSubVer)
14001 strSetSubVer += "\"" + str + "\" ";
14002 return strprintf(
14003 "CAlert(\n"
14004 " nVersion = %d\n"
14005 " nRelayUntil = %"PRI64d"\n"
14006 " nExpiration = %"PRI64d"\n"
14007 " nID = %d\n"
14008 " nCancel = %d\n"
14009 " setCancel = %s\n"
14010 " nMinVer = %d\n"
14011 " nMaxVer = %d\n"
14012 " setSubVer = %s\n"
14013 " nPriority = %d\n"
14014 " strComment = \"%s\"\n"
14015 " strStatusBar = \"%s\"\n"
14016 ")\n",
14017 nVersion,
14018 nRelayUntil,
14019 nExpiration,
14020 nID,
14021 nCancel,
14022 strSetCancel.c_str(),
14023 nMinVer,
14024 nMaxVer,
14025 strSetSubVer.c_str(),
14026 nPriority,
14027 strComment.c_str(),
14028 strStatusBar.c_str());
14029 }
14030
14031 void print() const
14032 {
14033 printf("%s", ToString().c_str());
14034 }
14035 };
14036
14037 class CAlert : public CUnsignedAlert
14038 {
14039 public:
14040 std::vector<unsigned char> vchMsg;
14041 std::vector<unsigned char> vchSig;
14042
14043 CAlert()
14044 {
14045 SetNull();
14046 }
14047
14048 IMPLEMENT_SERIALIZE
14049 (
14050 READWRITE(vchMsg);
14051 READWRITE(vchSig);
14052 )
14053
14054 void SetNull()
14055 {
14056 CUnsignedAlert::SetNull();
14057 vchMsg.clear();
14058 vchSig.clear();
14059 }
14060
14061 bool IsNull() const
14062 {
14063 return (nExpiration == 0);
14064 }
14065
14066 uint256 GetHash() const
14067 {
14068 return SerializeHash(*this);
14069 }
14070
14071 bool IsInEffect() const
14072 {
14073 return (GetAdjustedTime() < nExpiration);
14074 }
14075
14076 bool Cancels(const CAlert& alert) const
14077 {
14078 if (!IsInEffect())
14079 return false; // this was a no-op before 31403
14080 return (alert.nID <= nCancel || setCancel.count(alert.nID));
14081 }
14082
14083 bool AppliesTo(int nVersion, std::string strSubVerIn) const
14084 {
14085 return (IsInEffect() &&
14086 nMinVer <= nVersion && nVersion <= nMaxVer &&
14087 (setSubVer.empty() || setSubVer.count(strSubVerIn)));
14088 }
14089
14090 bool AppliesToMe() const
14091 {
14092 return AppliesTo(VERSION, ::pszSubVer);
14093 }
14094
14095 bool RelayTo(CNode* pnode) const
14096 {
14097 if (!IsInEffect())
14098 return false;
14099 // returns true if wasn't already contained in the set
14100 if (pnode->setKnown.insert(GetHash()).second)
14101 {
14102 if (AppliesTo(pnode->nVersion, pnode->strSubVer) ||
14103 AppliesToMe() ||
14104 GetAdjustedTime() < nRelayUntil)
14105 {
14106 pnode->PushMessage("alert", *this);
14107 return true;
14108 }
14109 }
14110 return false;
14111 }
14112
14113 bool CheckSignature()
14114 {
14115 CKey key;
14116 if (!key.SetPubKey(ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284")))
14117 return error("CAlert::CheckSignature() : SetPubKey failed");
14118 if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig))
14119 return error("CAlert::CheckSignature() : verify signature failed");
14120
14121 // Now unserialize the data
14122 CDataStream sMsg(vchMsg);
14123 sMsg >> *(CUnsignedAlert*)this;
14124 return true;
14125 }
14126
14127 bool ProcessAlert();
14128 };
14129
14130 #endif