aboutsummaryrefslogtreecommitdiff
path: root/src/chain.h
diff options
context:
space:
mode:
authorJames O'Beirne <james.obeirne@pm.me>2022-06-08 12:06:55 -0400
committerJames O'Beirne <james.obeirne@pm.me>2022-12-15 14:52:28 -0500
commit36c201feb74bbb87d22bd956373dbbb9c47fb7e7 (patch)
tree30162cdc904e53af1626400ca005827fbb8b6132 /src/chain.h
parentfc44d1796e4df5824423d7d13de3082fe204db7d (diff)
downloadbitcoin-36c201feb74bbb87d22bd956373dbbb9c47fb7e7.tar.xz
remove CBlockIndex copy construction
Copy construction of CBlockIndex objects is a footgun because of the wide use of equality-by-pointer comparison in the code base. There are also potential lifetime confusions of using copied instances, since there are recursive pointer references (e.g. pprev). We can't just delete the copy constructors because they are used for derived classes (CDiskBlockIndex), so we mark them protected. Delete move constructors and declare the destructor to satisfy the "rule of 5."
Diffstat (limited to 'src/chain.h')
-rw-r--r--src/chain.h22
1 files changed, 18 insertions, 4 deletions
diff --git a/src/chain.h b/src/chain.h
index 2d3b084b9b..e052b074a7 100644
--- a/src/chain.h
+++ b/src/chain.h
@@ -213,10 +213,6 @@ public:
//! (memory only) Maximum nTime in the chain up to and including this block.
unsigned int nTimeMax{0};
- CBlockIndex()
- {
- }
-
explicit CBlockIndex(const CBlockHeader& block)
: nVersion{block.nVersion},
hashMerkleRoot{block.hashMerkleRoot},
@@ -355,6 +351,24 @@ public:
//! Efficiently find an ancestor of this block.
CBlockIndex* GetAncestor(int height);
const CBlockIndex* GetAncestor(int height) const;
+
+ CBlockIndex() = default;
+ ~CBlockIndex() = default;
+
+protected:
+ //! CBlockIndex should not allow public copy construction because equality
+ //! comparison via pointer is very common throughout the codebase, making
+ //! use of copy a footgun. Also, use of copies do not have the benefit
+ //! of simplifying lifetime considerations due to attributes like pprev and
+ //! pskip, which are at risk of becoming dangling pointers in a copied
+ //! instance.
+ //!
+ //! We declare these protected instead of simply deleting them so that
+ //! CDiskBlockIndex can reuse copy construction.
+ CBlockIndex(const CBlockIndex&) = default;
+ CBlockIndex& operator=(const CBlockIndex&) = delete;
+ CBlockIndex(CBlockIndex&&) = delete;
+ CBlockIndex& operator=(CBlockIndex&&) = delete;
};
arith_uint256 GetBlockProof(const CBlockIndex& block);