diff options
author | MarcoFalke <falke.marco@gmail.com> | 2021-12-15 16:10:17 +0100 |
---|---|---|
committer | MarcoFalke <falke.marco@gmail.com> | 2021-12-15 16:10:23 +0100 |
commit | c09b41dc665bcc7d6dcc464f1d279e8eca598c8d (patch) | |
tree | a7478b91241915b6b5300892bbf0a7e9f8d1cbd7 | |
parent | b8cc75435a0bcb6c62083ff134b1ba3d2ace50d1 (diff) | |
parent | faf2614f60efe972b47b6fa00cfbc22d04ea7239 (diff) | |
download | bitcoin-c09b41dc665bcc7d6dcc464f1d279e8eca598c8d.tar.xz |
Merge bitcoin/bitcoin#23769: Disallow copies of CChain
faf2614f60efe972b47b6fa00cfbc22d04ea7239 style: Use 4 spaces for indendation, not 5 (MarcoFalke)
fada66fc2c716fc148104b6180da12efc5d05e41 Disallow copies of CChain (MarcoFalke)
Pull request description:
Creating a copy of the chain is not a valid use case in normal operation. Also, it massively degrades performance.
However, it seems to be a mistake that no one looks out for during review:
* https://github.com/bitcoin/bitcoin/pull/22677#discussion_r760400537
Fix this by disallowing it.
ACKs for top commit:
jamesob:
ACK faf2614f60efe972b47b6fa00cfbc22d04ea7239 ([`jamesob/ackr/23769.1.MarcoFalke.disallow_copies_of_cchai`](https://github.com/jamesob/bitcoin/tree/ackr/23769.1.MarcoFalke.disallow_copies_of_cchai))
glozow:
utACK faf2614f60efe972b47b6fa00cfbc22d04ea7239, nice.
prusnak:
utACK faf2614
Tree-SHA512: 27b908c78842e4700e118adb876c09c3d1ec04662310e983309e2cd6fa8ad38c9359ff45f36a804359b9f117e351c4739e651b3e6754c14e6c6fcd7ae5e68342
-rw-r--r-- | src/chain.h | 130 |
1 files changed, 74 insertions, 56 deletions
diff --git a/src/chain.h b/src/chain.h index 15ca8f8750..8eafc5d588 100644 --- a/src/chain.h +++ b/src/chain.h @@ -59,37 +59,40 @@ public: READWRITE(VARINT(obj.nTimeLast)); } - void SetNull() { - nBlocks = 0; - nSize = 0; - nUndoSize = 0; - nHeightFirst = 0; - nHeightLast = 0; - nTimeFirst = 0; - nTimeLast = 0; - } - - CBlockFileInfo() { - SetNull(); - } - - std::string ToString() const; - - /** update statistics (does not update nSize) */ - void AddBlock(unsigned int nHeightIn, uint64_t nTimeIn) { - if (nBlocks==0 || nHeightFirst > nHeightIn) - nHeightFirst = nHeightIn; - if (nBlocks==0 || nTimeFirst > nTimeIn) - nTimeFirst = nTimeIn; - nBlocks++; - if (nHeightIn > nHeightLast) - nHeightLast = nHeightIn; - if (nTimeIn > nTimeLast) - nTimeLast = nTimeIn; - } + void SetNull() + { + nBlocks = 0; + nSize = 0; + nUndoSize = 0; + nHeightFirst = 0; + nHeightLast = 0; + nTimeFirst = 0; + nTimeLast = 0; + } + + CBlockFileInfo() + { + SetNull(); + } + + std::string ToString() const; + + /** update statistics (does not update nSize) */ + void AddBlock(unsigned int nHeightIn, uint64_t nTimeIn) + { + if (nBlocks == 0 || nHeightFirst > nHeightIn) + nHeightFirst = nHeightIn; + if (nBlocks == 0 || nTimeFirst > nTimeIn) + nTimeFirst = nTimeIn; + nBlocks++; + if (nHeightIn > nHeightLast) + nHeightLast = nHeightIn; + if (nTimeIn > nTimeLast) + nTimeLast = nTimeIn; + } }; -enum BlockStatus: uint32_t { +enum BlockStatus : uint32_t { //! Unused. BLOCK_VALID_UNKNOWN = 0, @@ -220,20 +223,22 @@ public: { } - FlatFilePos GetBlockPos() const { + FlatFilePos GetBlockPos() const + { FlatFilePos ret; if (nStatus & BLOCK_HAVE_DATA) { ret.nFile = nFile; - ret.nPos = nDataPos; + ret.nPos = nDataPos; } return ret; } - FlatFilePos GetUndoPos() const { + FlatFilePos GetUndoPos() const + { FlatFilePos ret; if (nStatus & BLOCK_HAVE_UNDO) { ret.nFile = nFile; - ret.nPos = nUndoPos; + ret.nPos = nUndoPos; } return ret; } @@ -241,13 +246,13 @@ public: CBlockHeader GetBlockHeader() const { CBlockHeader block; - block.nVersion = nVersion; + block.nVersion = nVersion; if (pprev) block.hashPrevBlock = pprev->GetBlockHash(); block.hashMerkleRoot = hashMerkleRoot; - block.nTime = nTime; - block.nBits = nBits; - block.nNonce = nNonce; + block.nTime = nTime; + block.nBits = nBits; + block.nNonce = nNonce; return block; } @@ -288,7 +293,7 @@ public: *(--pbegin) = pindex->GetBlockTime(); std::sort(pbegin, pend); - return pbegin[(pend - pbegin)/2]; + return pbegin[(pend - pbegin) / 2]; } std::string ToString() const @@ -353,11 +358,13 @@ class CDiskBlockIndex : public CBlockIndex public: uint256 hashPrev; - CDiskBlockIndex() { + CDiskBlockIndex() + { hashPrev = uint256(); } - explicit CDiskBlockIndex(const CBlockIndex* pindex) : CBlockIndex(*pindex) { + explicit CDiskBlockIndex(const CBlockIndex* pindex) : CBlockIndex(*pindex) + { hashPrev = (pprev ? pprev->GetBlockHash() : uint256()); } @@ -385,12 +392,12 @@ public: uint256 GetBlockHash() const { CBlockHeader block; - block.nVersion = nVersion; - block.hashPrevBlock = hashPrev; - block.hashMerkleRoot = hashMerkleRoot; - block.nTime = nTime; - block.nBits = nBits; - block.nNonce = nNonce; + block.nVersion = nVersion; + block.hashPrevBlock = hashPrev; + block.hashMerkleRoot = hashMerkleRoot; + block.nTime = nTime; + block.nBits = nBits; + block.nNonce = nNonce; return block.GetHash(); } @@ -407,35 +414,45 @@ public: }; /** An in-memory indexed chain of blocks. */ -class CChain { +class CChain +{ private: std::vector<CBlockIndex*> vChain; public: + CChain() = default; + CChain(const CChain&) = delete; + CChain& operator=(const CChain&) = delete; + /** Returns the index entry for the genesis block of this chain, or nullptr if none. */ - CBlockIndex *Genesis() const { + CBlockIndex* Genesis() const + { return vChain.size() > 0 ? vChain[0] : nullptr; } /** Returns the index entry for the tip of this chain, or nullptr if none. */ - CBlockIndex *Tip() const { + CBlockIndex* Tip() const + { return vChain.size() > 0 ? vChain[vChain.size() - 1] : nullptr; } /** Returns the index entry at a particular height in this chain, or nullptr if no such height exists. */ - CBlockIndex *operator[](int nHeight) const { + CBlockIndex* operator[](int nHeight) const + { if (nHeight < 0 || nHeight >= (int)vChain.size()) return nullptr; return vChain[nHeight]; } /** Efficiently check whether a block is present in this chain. */ - bool Contains(const CBlockIndex *pindex) const { + bool Contains(const CBlockIndex* pindex) const + { return (*this)[pindex->nHeight] == pindex; } /** Find the successor of a block in this chain, or nullptr if the given index is not found or is the tip. */ - CBlockIndex *Next(const CBlockIndex *pindex) const { + CBlockIndex* Next(const CBlockIndex* pindex) const + { if (Contains(pindex)) return (*this)[pindex->nHeight + 1]; else @@ -443,18 +460,19 @@ public: } /** Return the maximal height in the chain. Is equal to chain.Tip() ? chain.Tip()->nHeight : -1. */ - int Height() const { + int Height() const + { return vChain.size() - 1; } /** Set/initialize a chain with a given tip. */ - void SetTip(CBlockIndex *pindex); + void SetTip(CBlockIndex* pindex); /** Return a CBlockLocator that refers to a block in this chain (by default the tip). */ - CBlockLocator GetLocator(const CBlockIndex *pindex = nullptr) const; + CBlockLocator GetLocator(const CBlockIndex* pindex = nullptr) const; /** Find the last common block between this chain and a block index entry. */ - const CBlockIndex *FindFork(const CBlockIndex *pindex) const; + const CBlockIndex* FindFork(const CBlockIndex* pindex) const; /** Find the earliest block with timestamp equal or greater than the given time and height equal or greater than the given height. */ CBlockIndex* FindEarliestAtLeast(int64_t nTime, int height) const; |