From e754cf4133c9c97e320ae5dec394e338524e650b Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 14 Nov 2012 22:18:10 +0100 Subject: [PATCH] Split off CBlockHeader from CBlock Cleaner and removes the need for the application-specific flags in serialize.h. --- src/main.cpp | 16 ++++----- src/main.h | 77 ++++++++++++++++++++++++++----------------- src/rpcblockchain.cpp | 2 +- src/serialize.h | 4 --- src/wallet.cpp | 2 +- 5 files changed, 55 insertions(+), 46 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index f0bf4755..a75baf74 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -998,21 +998,16 @@ CBlockIndex* FindBlockByHeight(int nHeight) return pblockindex; } -bool CBlock::ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions) +bool CBlock::ReadFromDisk(const CBlockIndex* pindex) { - if (!fReadTransactions) - { - *this = pindex->GetBlockHeader(); - return true; - } - if (!ReadFromDisk(pindex->GetBlockPos(), fReadTransactions)) + if (!ReadFromDisk(pindex->GetBlockPos())) return false; if (GetHash() != pindex->GetBlockHash()) return error("CBlock::ReadFromDisk() : GetHash() doesn't match index"); return true; } -uint256 static GetOrphanRoot(const CBlock* pblock) +uint256 static GetOrphanRoot(const CBlockHeader* pblock) { // Work back to the first block in the orphan chain while (mapOrphanBlocks.count(pblock->hashPrevBlock)) @@ -1059,7 +1054,7 @@ unsigned int ComputeMinWork(unsigned int nBase, int64 nTime) return bnResult.GetCompact(); } -unsigned int static GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlock *pblock) +unsigned int static GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock) { unsigned int nProofOfWorkLimit = bnProofOfWorkLimit.GetCompact(); @@ -1233,7 +1228,7 @@ bool ConnectBestBlock() { } while(true); } -void CBlock::UpdateTime(const CBlockIndex* pindexPrev) +void CBlockHeader::UpdateTime(const CBlockIndex* pindexPrev) { nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); @@ -3072,6 +3067,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) pindex = pindex->pnext; } + // we must use CBlocks, as CBlockHeaders won't include the 0x00 nTx count at the end vector vHeaders; int nLimit = 2000; printf("getheaders %d to %s\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,20).c_str()); diff --git a/src/main.h b/src/main.h index 0ef192f9..994d0bfb 100644 --- a/src/main.h +++ b/src/main.h @@ -1068,7 +1068,7 @@ public: * in the block is a special one that creates a new coin owned by the creator * of the block. */ -class CBlock +class CBlockHeader { public: // header @@ -1080,17 +1080,7 @@ public: unsigned int nBits; unsigned int nNonce; - // network and disk - std::vector vtx; - - // memory only - mutable std::vector vMerkleTree; - - // Denial-of-service detection: - mutable int nDoS; - bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; } - - CBlock() + CBlockHeader() { SetNull(); } @@ -1104,25 +1094,16 @@ public: READWRITE(nTime); READWRITE(nBits); READWRITE(nNonce); - - // ConnectBlock depends on vtx being last so it can calculate offset - if (!(nType & (SER_GETHASH|SER_BLOCKHEADERONLY))) - READWRITE(vtx); - else if (fRead) - const_cast(this)->vtx.clear(); ) void SetNull() { - nVersion = CBlock::CURRENT_VERSION; + nVersion = CBlockHeader::CURRENT_VERSION; hashPrevBlock = 0; hashMerkleRoot = 0; nTime = 0; nBits = 0; nNonce = 0; - vtx.clear(); - vMerkleTree.clear(); - nDoS = 0; } bool IsNull() const @@ -1141,7 +1122,45 @@ public: } void UpdateTime(const CBlockIndex* pindexPrev); +}; + +class CBlock : public CBlockHeader +{ +public: + // network and disk + std::vector vtx; + + // memory only + mutable std::vector vMerkleTree; + // Denial-of-service detection: + mutable int nDoS; + bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; } + + CBlock() + { + SetNull(); + } + + CBlock(const CBlockHeader &header) + { + SetNull(); + *((CBlockHeader*)this) = header; + } + + IMPLEMENT_SERIALIZE + ( + READWRITE(*(CBlockHeader*)this); + READWRITE(vtx); + ) + + void SetNull() + { + CBlockHeader::SetNull(); + vtx.clear(); + vMerkleTree.clear(); + nDoS = 0; + } uint256 BuildMerkleTree() const { @@ -1226,7 +1245,7 @@ public: return true; } - bool ReadFromDisk(const CDiskBlockPos &pos, bool fReadTransactions = true) + bool ReadFromDisk(const CDiskBlockPos &pos) { SetNull(); @@ -1234,8 +1253,6 @@ public: CAutoFile filein = CAutoFile(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION); if (!filein) return error("CBlock::ReadFromDisk() : OpenBlockFile failed"); - if (!fReadTransactions) - filein.nType |= SER_BLOCKHEADERONLY; // Read block try { @@ -1282,7 +1299,7 @@ public: bool ConnectBlock(CBlockIndex *pindex, CCoinsViewCache &coins, bool fJustCheck=false); // Read a block from disk - bool ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions=true); + bool ReadFromDisk(const CBlockIndex* pindex); // Add this block to the block index, and if necessary, switch the active block chain to this bool AddToBlockIndex(const CDiskBlockPos &pos); @@ -1447,7 +1464,7 @@ public: nNonce = 0; } - CBlockIndex(CBlock& block) + CBlockIndex(CBlockHeader& block) { phashBlock = NULL; pprev = NULL; @@ -1488,9 +1505,9 @@ public: return ret; } - CBlock GetBlockHeader() const + CBlockHeader GetBlockHeader() const { - CBlock block; + CBlockHeader block; block.nVersion = nVersion; if (pprev) block.hashPrevBlock = pprev->GetBlockHash(); @@ -1634,7 +1651,7 @@ public: uint256 GetBlockHash() const { - CBlock block; + CBlockHeader block; block.nVersion = nVersion; block.hashPrevBlock = hashPrev; block.hashMerkleRoot = hashMerkleRoot; diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 3fde463c..5554f039 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -154,7 +154,7 @@ Value getblock(const Array& params, bool fHelp) CBlock block; CBlockIndex* pblockindex = mapBlockIndex[hash]; - block.ReadFromDisk(pblockindex, true); + block.ReadFromDisk(pblockindex); return blockToJSON(block, pblockindex); } diff --git a/src/serialize.h b/src/serialize.h index 9e14666f..f2626281 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -50,10 +50,6 @@ enum SER_NETWORK = (1 << 0), SER_DISK = (1 << 1), SER_GETHASH = (1 << 2), - - // modifiers - SER_SKIPSIG = (1 << 16), - SER_BLOCKHEADERONLY = (1 << 17), }; #define IMPLEMENT_SERIALIZE(statements) \ diff --git a/src/wallet.cpp b/src/wallet.cpp index 0115e56b..fdb03431 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -752,7 +752,7 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) while (pindex) { CBlock block; - block.ReadFromDisk(pindex, true); + block.ReadFromDisk(pindex); BOOST_FOREACH(CTransaction& tx, block.vtx) { if (AddToWalletIfInvolvingMe(tx.GetHash(), tx, &block, fUpdate))