Skip to content

Commit c09b41d

Browse files
author
MarcoFalke
committed
Merge bitcoin/bitcoin#23769: Disallow copies of CChain
faf2614 style: Use 4 spaces for indendation, not 5 (MarcoFalke) fada66f 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: * bitcoin/bitcoin#22677 (comment) Fix this by disallowing it. ACKs for top commit: jamesob: ACK faf2614 ([`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 faf2614, nice. prusnak: utACK faf2614 Tree-SHA512: 27b908c78842e4700e118adb876c09c3d1ec04662310e983309e2cd6fa8ad38c9359ff45f36a804359b9f117e351c4739e651b3e6754c14e6c6fcd7ae5e68342
2 parents b8cc754 + faf2614 commit c09b41d

File tree

1 file changed

+74
-56
lines changed

1 file changed

+74
-56
lines changed

src/chain.h

Lines changed: 74 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -59,37 +59,40 @@ class CBlockFileInfo
5959
READWRITE(VARINT(obj.nTimeLast));
6060
}
6161

62-
void SetNull() {
63-
nBlocks = 0;
64-
nSize = 0;
65-
nUndoSize = 0;
66-
nHeightFirst = 0;
67-
nHeightLast = 0;
68-
nTimeFirst = 0;
69-
nTimeLast = 0;
70-
}
71-
72-
CBlockFileInfo() {
73-
SetNull();
74-
}
75-
76-
std::string ToString() const;
77-
78-
/** update statistics (does not update nSize) */
79-
void AddBlock(unsigned int nHeightIn, uint64_t nTimeIn) {
80-
if (nBlocks==0 || nHeightFirst > nHeightIn)
81-
nHeightFirst = nHeightIn;
82-
if (nBlocks==0 || nTimeFirst > nTimeIn)
83-
nTimeFirst = nTimeIn;
84-
nBlocks++;
85-
if (nHeightIn > nHeightLast)
86-
nHeightLast = nHeightIn;
87-
if (nTimeIn > nTimeLast)
88-
nTimeLast = nTimeIn;
89-
}
62+
void SetNull()
63+
{
64+
nBlocks = 0;
65+
nSize = 0;
66+
nUndoSize = 0;
67+
nHeightFirst = 0;
68+
nHeightLast = 0;
69+
nTimeFirst = 0;
70+
nTimeLast = 0;
71+
}
72+
73+
CBlockFileInfo()
74+
{
75+
SetNull();
76+
}
77+
78+
std::string ToString() const;
79+
80+
/** update statistics (does not update nSize) */
81+
void AddBlock(unsigned int nHeightIn, uint64_t nTimeIn)
82+
{
83+
if (nBlocks == 0 || nHeightFirst > nHeightIn)
84+
nHeightFirst = nHeightIn;
85+
if (nBlocks == 0 || nTimeFirst > nTimeIn)
86+
nTimeFirst = nTimeIn;
87+
nBlocks++;
88+
if (nHeightIn > nHeightLast)
89+
nHeightLast = nHeightIn;
90+
if (nTimeIn > nTimeLast)
91+
nTimeLast = nTimeIn;
92+
}
9093
};
9194

92-
enum BlockStatus: uint32_t {
95+
enum BlockStatus : uint32_t {
9396
//! Unused.
9497
BLOCK_VALID_UNKNOWN = 0,
9598

@@ -220,34 +223,36 @@ class CBlockIndex
220223
{
221224
}
222225

223-
FlatFilePos GetBlockPos() const {
226+
FlatFilePos GetBlockPos() const
227+
{
224228
FlatFilePos ret;
225229
if (nStatus & BLOCK_HAVE_DATA) {
226230
ret.nFile = nFile;
227-
ret.nPos = nDataPos;
231+
ret.nPos = nDataPos;
228232
}
229233
return ret;
230234
}
231235

232-
FlatFilePos GetUndoPos() const {
236+
FlatFilePos GetUndoPos() const
237+
{
233238
FlatFilePos ret;
234239
if (nStatus & BLOCK_HAVE_UNDO) {
235240
ret.nFile = nFile;
236-
ret.nPos = nUndoPos;
241+
ret.nPos = nUndoPos;
237242
}
238243
return ret;
239244
}
240245

241246
CBlockHeader GetBlockHeader() const
242247
{
243248
CBlockHeader block;
244-
block.nVersion = nVersion;
249+
block.nVersion = nVersion;
245250
if (pprev)
246251
block.hashPrevBlock = pprev->GetBlockHash();
247252
block.hashMerkleRoot = hashMerkleRoot;
248-
block.nTime = nTime;
249-
block.nBits = nBits;
250-
block.nNonce = nNonce;
253+
block.nTime = nTime;
254+
block.nBits = nBits;
255+
block.nNonce = nNonce;
251256
return block;
252257
}
253258

@@ -288,7 +293,7 @@ class CBlockIndex
288293
*(--pbegin) = pindex->GetBlockTime();
289294

290295
std::sort(pbegin, pend);
291-
return pbegin[(pend - pbegin)/2];
296+
return pbegin[(pend - pbegin) / 2];
292297
}
293298

294299
std::string ToString() const
@@ -353,11 +358,13 @@ class CDiskBlockIndex : public CBlockIndex
353358
public:
354359
uint256 hashPrev;
355360

356-
CDiskBlockIndex() {
361+
CDiskBlockIndex()
362+
{
357363
hashPrev = uint256();
358364
}
359365

360-
explicit CDiskBlockIndex(const CBlockIndex* pindex) : CBlockIndex(*pindex) {
366+
explicit CDiskBlockIndex(const CBlockIndex* pindex) : CBlockIndex(*pindex)
367+
{
361368
hashPrev = (pprev ? pprev->GetBlockHash() : uint256());
362369
}
363370

@@ -385,12 +392,12 @@ class CDiskBlockIndex : public CBlockIndex
385392
uint256 GetBlockHash() const
386393
{
387394
CBlockHeader block;
388-
block.nVersion = nVersion;
389-
block.hashPrevBlock = hashPrev;
390-
block.hashMerkleRoot = hashMerkleRoot;
391-
block.nTime = nTime;
392-
block.nBits = nBits;
393-
block.nNonce = nNonce;
395+
block.nVersion = nVersion;
396+
block.hashPrevBlock = hashPrev;
397+
block.hashMerkleRoot = hashMerkleRoot;
398+
block.nTime = nTime;
399+
block.nBits = nBits;
400+
block.nNonce = nNonce;
394401
return block.GetHash();
395402
}
396403

@@ -407,54 +414,65 @@ class CDiskBlockIndex : public CBlockIndex
407414
};
408415

409416
/** An in-memory indexed chain of blocks. */
410-
class CChain {
417+
class CChain
418+
{
411419
private:
412420
std::vector<CBlockIndex*> vChain;
413421

414422
public:
423+
CChain() = default;
424+
CChain(const CChain&) = delete;
425+
CChain& operator=(const CChain&) = delete;
426+
415427
/** Returns the index entry for the genesis block of this chain, or nullptr if none. */
416-
CBlockIndex *Genesis() const {
428+
CBlockIndex* Genesis() const
429+
{
417430
return vChain.size() > 0 ? vChain[0] : nullptr;
418431
}
419432

420433
/** Returns the index entry for the tip of this chain, or nullptr if none. */
421-
CBlockIndex *Tip() const {
434+
CBlockIndex* Tip() const
435+
{
422436
return vChain.size() > 0 ? vChain[vChain.size() - 1] : nullptr;
423437
}
424438

425439
/** Returns the index entry at a particular height in this chain, or nullptr if no such height exists. */
426-
CBlockIndex *operator[](int nHeight) const {
440+
CBlockIndex* operator[](int nHeight) const
441+
{
427442
if (nHeight < 0 || nHeight >= (int)vChain.size())
428443
return nullptr;
429444
return vChain[nHeight];
430445
}
431446

432447
/** Efficiently check whether a block is present in this chain. */
433-
bool Contains(const CBlockIndex *pindex) const {
448+
bool Contains(const CBlockIndex* pindex) const
449+
{
434450
return (*this)[pindex->nHeight] == pindex;
435451
}
436452

437453
/** Find the successor of a block in this chain, or nullptr if the given index is not found or is the tip. */
438-
CBlockIndex *Next(const CBlockIndex *pindex) const {
454+
CBlockIndex* Next(const CBlockIndex* pindex) const
455+
{
439456
if (Contains(pindex))
440457
return (*this)[pindex->nHeight + 1];
441458
else
442459
return nullptr;
443460
}
444461

445462
/** Return the maximal height in the chain. Is equal to chain.Tip() ? chain.Tip()->nHeight : -1. */
446-
int Height() const {
463+
int Height() const
464+
{
447465
return vChain.size() - 1;
448466
}
449467

450468
/** Set/initialize a chain with a given tip. */
451-
void SetTip(CBlockIndex *pindex);
469+
void SetTip(CBlockIndex* pindex);
452470

453471
/** Return a CBlockLocator that refers to a block in this chain (by default the tip). */
454-
CBlockLocator GetLocator(const CBlockIndex *pindex = nullptr) const;
472+
CBlockLocator GetLocator(const CBlockIndex* pindex = nullptr) const;
455473

456474
/** Find the last common block between this chain and a block index entry. */
457-
const CBlockIndex *FindFork(const CBlockIndex *pindex) const;
475+
const CBlockIndex* FindFork(const CBlockIndex* pindex) const;
458476

459477
/** Find the earliest block with timestamp equal or greater than the given time and height equal or greater than the given height. */
460478
CBlockIndex* FindEarliestAtLeast(int64_t nTime, int height) const;

0 commit comments

Comments
 (0)