From 05454818dc7ed92f577a1a1ef6798049f17a52e7 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Thu, 19 Aug 2010 22:43:19 +0000 Subject: block index checking on load, extra redundant checks, misc refactoring git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@140 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- main.h | 68 +++++++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 47 insertions(+), 21 deletions(-) (limited to 'main.h') diff --git a/main.h b/main.h index 1cc410be61..474080c5e1 100644 --- a/main.h +++ b/main.h @@ -19,8 +19,8 @@ static const unsigned int MAX_BLOCK_SIZE = 1000000; static const int64 COIN = 100000000; static const int64 CENT = 1000000; static const int64 MAX_MONEY = 21000000 * COIN; +inline bool MoneyRange(int64 nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } static const int COINBASE_MATURITY = 100; - static const CBigNum bnProofOfWorkLimit(~uint256(0) >> 32); @@ -83,6 +83,7 @@ string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtx void GenerateBitcoins(bool fGenerate); void ThreadBitcoinMiner(void* parg); void BitcoinMiner(); +bool CheckProofOfWork(uint256 hash, unsigned int nBits); bool IsInitialBlockDownload(); bool IsLockdown(); @@ -338,6 +339,8 @@ public: int64 GetCredit() const { + if (!MoneyRange(nValue)) + throw runtime_error("CTxOut::GetCredit() : value out of range"); if (IsMine()) return nValue; return 0; @@ -424,7 +427,7 @@ public: nBlockHeight = nBestHeight; if (nBlockTime == 0) nBlockTime = GetAdjustedTime(); - if (nLockTime < (nLockTime < 500000000 ? nBlockHeight : nBlockTime)) + if ((int64)nLockTime < (nLockTime < 500000000 ? (int64)nBlockHeight : nBlockTime)) return true; foreach(const CTxIn& txin, vin) if (!txin.IsFinal()) @@ -481,8 +484,8 @@ public: if (txout.nValue > MAX_MONEY) return error("CTransaction::CheckTransaction() : txout.nValue too high"); nValueOut += txout.nValue; - if (nValueOut > MAX_MONEY) - return error("CTransaction::CheckTransaction() : txout total too high"); + if (!MoneyRange(nValueOut)) + return error("CTransaction::CheckTransaction() : txout total out of range"); } if (IsCoinBase()) @@ -512,7 +515,11 @@ public: { int64 nDebit = 0; foreach(const CTxIn& txin, vin) + { nDebit += txin.GetDebit(); + if (!MoneyRange(nDebit)) + throw runtime_error("CTransaction::GetDebit() : value out of range"); + } return nDebit; } @@ -520,7 +527,11 @@ public: { int64 nCredit = 0; foreach(const CTxOut& txout, vout) + { nCredit += txout.GetCredit(); + if (!MoneyRange(nCredit)) + throw runtime_error("CTransaction::GetCredit() : value out of range"); + } return nCredit; } @@ -529,9 +540,9 @@ public: int64 nValueOut = 0; foreach(const CTxOut& txout, vout) { - if (txout.nValue < 0) - throw runtime_error("CTransaction::GetValueOut() : negative value"); nValueOut += txout.nValue; + if (!MoneyRange(txout.nValue) || !MoneyRange(nValueOut)) + throw runtime_error("CTransaction::GetValueOut() : value out of range"); } return nValueOut; } @@ -930,6 +941,11 @@ public: return Hash(BEGIN(nVersion), END(nNonce)); } + int64 GetBlockTime() const + { + return (int64)nTime; + } + uint256 BuildMerkleTree() const { @@ -1030,10 +1046,8 @@ public: filein >> *this; // Check the header - if (CBigNum().SetCompact(nBits) > bnProofOfWorkLimit) - return error("CBlock::ReadFromDisk() : nBits errors in block header"); - if (GetHash() > CBigNum().SetCompact(nBits).getuint256()) - return error("CBlock::ReadFromDisk() : GetHash() errors in block header"); + if (!CheckProofOfWork(GetHash(), nBits)) + return error("CBlock::ReadFromDisk() : errors in block header"); return true; } @@ -1043,9 +1057,9 @@ public: void print() const { printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%d)\n", - GetHash().ToString().substr(0,16).c_str(), + GetHash().ToString().substr(0,20).c_str(), nVersion, - hashPrevBlock.ToString().substr(0,16).c_str(), + hashPrevBlock.ToString().substr(0,20).c_str(), hashMerkleRoot.ToString().substr(0,6).c_str(), nTime, nBits, nNonce, vtx.size()); @@ -1064,7 +1078,7 @@ public: int64 GetBlockValue(int nHeight, int64 nFees) const; bool DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex); bool ConnectBlock(CTxDB& txdb, CBlockIndex* pindex); - bool ReadFromDisk(const CBlockIndex* blockindex, bool fReadTransactions=true); + bool ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions=true); bool SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew); bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos); bool CheckBlock() const; @@ -1142,8 +1156,15 @@ public: return *phashBlock; } + int64 GetBlockTime() const + { + return (int64)nTime; + } + CBigNum GetBlockWork() const { + if (CBigNum().SetCompact(nBits) <= 0) + return 0; return (CBigNum(1)<<256) / (CBigNum().SetCompact(nBits)+1); } @@ -1152,6 +1173,11 @@ public: return (pnext || this == pindexBest); } + bool CheckIndex() const + { + return CheckProofOfWork(GetBlockHash(), nBits); + } + bool EraseBlockFromDisk() { // Open history file @@ -1171,13 +1197,13 @@ public: int64 GetMedianTimePast() const { - unsigned int pmedian[nMedianTimeSpan]; - unsigned int* pbegin = &pmedian[nMedianTimeSpan]; - unsigned int* pend = &pmedian[nMedianTimeSpan]; + int64 pmedian[nMedianTimeSpan]; + int64* pbegin = &pmedian[nMedianTimeSpan]; + int64* pend = &pmedian[nMedianTimeSpan]; const CBlockIndex* pindex = this; for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev) - *(--pbegin) = pindex->nTime; + *(--pbegin) = pindex->GetBlockTime(); sort(pbegin, pend); return pbegin[(pend - pbegin)/2]; @@ -1189,7 +1215,7 @@ public: for (int i = 0; i < nMedianTimeSpan/2; i++) { if (!pindex->pnext) - return nTime; + return GetBlockTime(); pindex = pindex->pnext; } return pindex->GetMedianTimePast(); @@ -1202,7 +1228,7 @@ public: return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)", pprev, pnext, nFile, nBlockPos, nHeight, hashMerkleRoot.ToString().substr(0,6).c_str(), - GetBlockHash().ToString().substr(0,16).c_str()); + GetBlockHash().ToString().substr(0,20).c_str()); } void print() const @@ -1272,8 +1298,8 @@ public: str += CBlockIndex::ToString(); str += strprintf("\n hashBlock=%s, hashPrev=%s, hashNext=%s)", GetBlockHash().ToString().c_str(), - hashPrev.ToString().substr(0,16).c_str(), - hashNext.ToString().substr(0,16).c_str()); + hashPrev.ToString().substr(0,20).c_str(), + hashNext.ToString().substr(0,20).c_str()); return str; } -- cgit v1.2.3