Skip to content

Commit fe86a7c

Browse files
committed
Explicitly track maximum block height stored in undo files
When writing a new block to disk, if we have filled up the current block file, then we flush and truncate that block file (to free allocated but unused space) before advancing to the next one. When this happens, we have to determine whether to also flush and truncate the corresponding undo file. Undo data is only written when blocks are connected, not when blocks are received. Thus it's possible that the corresponding undo file already has all the data it will ever have, and we should flush/truncate it as we advance files; or it's possible that there is more data we expect to write, and should therefore defer flush/truncation until undo data is later written. Prior to this commit, we made the determination of whether the undo file was full of all requisite data by comparing against the chain tip. This patch replaces that dependence on validation data structures by instead just tracking the highest height of any block written in the undo file as we go.
1 parent 01e5d6b commit fe86a7c

File tree

2 files changed

+17
-2
lines changed

2 files changed

+17
-2
lines changed

src/node/blockstorage.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -644,7 +644,7 @@ bool BlockManager::FindBlockPos(FlatFilePos& pos, unsigned int nAddSize, unsigne
644644
// when the undo file is keeping up with the block file, we want to flush it explicitly
645645
// when it is lagging behind (more blocks arrive than are being connected), we let the
646646
// undo block write case handle it
647-
finalize_undo = (m_blockfile_info[nFile].nHeightLast == (unsigned int)active_chain.Tip()->nHeight);
647+
finalize_undo = (m_blockfile_info[nFile].nHeightLast == m_undo_height_in_last_blockfile);
648648
nFile++;
649649
if (m_blockfile_info.size() <= nFile) {
650650
m_blockfile_info.resize(nFile + 1);
@@ -660,6 +660,7 @@ bool BlockManager::FindBlockPos(FlatFilePos& pos, unsigned int nAddSize, unsigne
660660
}
661661
FlushBlockFile(!fKnown, finalize_undo);
662662
m_last_blockfile = nFile;
663+
m_undo_height_in_last_blockfile = 0; // No undo data yet in the new file, so reset our undo-height tracking.
663664
}
664665

665666
m_blockfile_info[nFile].AddBlock(nHeight, nTime);
@@ -749,8 +750,9 @@ bool BlockManager::WriteUndoDataForBlock(const CBlockUndo& blockundo, BlockValid
749750
// the FindBlockPos function
750751
if (_pos.nFile < m_last_blockfile && static_cast<uint32_t>(block.nHeight) == m_blockfile_info[_pos.nFile].nHeightLast) {
751752
FlushUndoFile(_pos.nFile, true);
753+
} else if (_pos.nFile == m_last_blockfile && static_cast<uint32_t>(block.nHeight) > m_undo_height_in_last_blockfile) {
754+
m_undo_height_in_last_blockfile = block.nHeight;
752755
}
753-
754756
// update nUndoPos in block index
755757
block.nUndoPos = _pos.nPos;
756758
block.nStatus |= BLOCK_HAVE_UNDO;

src/node/blockstorage.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,19 @@ class BlockManager
128128
RecursiveMutex cs_LastBlockFile;
129129
std::vector<CBlockFileInfo> m_blockfile_info;
130130
int m_last_blockfile = 0;
131+
132+
// Track the height of the highest block in m_last_blockfile whose undo
133+
// data has been written. Block data is written to block files in download
134+
// order, but is written to undo files in validation order, which is
135+
// usually in order by height. To avoid wasting disk space, undo files will
136+
// be trimmed whenever the corresponding block file is finalized and
137+
// the height of the highest block written to the block file equals the
138+
// height of the highest block written to the undo file. This is a
139+
// heuristic and can sometimes preemptively trim undo files that will write
140+
// more data later, and sometimes fail to trim undo files that can't have
141+
// more data written later.
142+
unsigned int m_undo_height_in_last_blockfile = 0;
143+
131144
/** Global flag to indicate we should check to see if there are
132145
* block/undo files that should be deleted. Set on startup
133146
* or if we allocate more file space when we're in prune mode

0 commit comments

Comments
 (0)