Skip to content

Commit 056cb3c

Browse files
l0rincmaflcko
andcommitted
refactor: clear up blockstorage/streams in preparation for optimization
Made every OpenBlockFile#fReadOnly value explicit. Replaced hard-coded values in ReadRawBlock with STORAGE_HEADER_BYTES. Changed `STORAGE_HEADER_BYTES` and `UNDO_DATA_DISK_OVERHEAD` to `uint32_t` to avoid casts. Also added `LIFETIMEBOUND` to the `AutoFile` parameter of `BufferedFile`, which stores a reference to the underlying `AutoFile`, allowing Clang to emit warnings if the referenced `AutoFile` might be destroyed while `BufferedFile` still exists. Without this attribute, code with lifetime violations wouldn't trigger compiler warnings. Co-authored-by: maflcko <[email protected]>
1 parent 67fcc64 commit 056cb3c

File tree

3 files changed

+15
-16
lines changed

3 files changed

+15
-16
lines changed

src/node/blockstorage.cpp

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,7 @@ bool BlockManager::LoadBlockIndexDB(const std::optional<uint256>& snapshot_block
529529
}
530530
for (std::set<int>::iterator it = setBlkDataFiles.begin(); it != setBlkDataFiles.end(); it++) {
531531
FlatFilePos pos(*it, 0);
532-
if (OpenBlockFile(pos, true).IsNull()) {
532+
if (OpenBlockFile(pos, /*fReadOnly=*/true).IsNull()) {
533533
return false;
534534
}
535535
}
@@ -933,7 +933,7 @@ bool BlockManager::WriteBlockUndo(const CBlockUndo& blockundo, BlockValidationSt
933933
// Write undo information to disk
934934
if (block.GetUndoPos().IsNull()) {
935935
FlatFilePos pos;
936-
const unsigned int blockundo_size{static_cast<unsigned int>(GetSerializeSize(blockundo))};
936+
const auto blockundo_size{static_cast<uint32_t>(GetSerializeSize(blockundo))};
937937
if (!FindUndoPos(state, block.nFile, pos, blockundo_size + UNDO_DATA_DISK_OVERHEAD)) {
938938
LogError("FindUndoPos failed for %s while writing block undo", pos.ToString());
939939
return false;
@@ -996,7 +996,7 @@ bool BlockManager::ReadBlock(CBlock& block, const FlatFilePos& pos) const
996996
block.SetNull();
997997

998998
// Open history file to read
999-
AutoFile filein{OpenBlockFile(pos, true)};
999+
AutoFile filein{OpenBlockFile(pos, /*fReadOnly=*/true)};
10001000
if (filein.IsNull()) {
10011001
LogError("OpenBlockFile failed for %s while reading block", pos.ToString());
10021002
return false;
@@ -1041,15 +1041,14 @@ bool BlockManager::ReadBlock(CBlock& block, const CBlockIndex& index) const
10411041

10421042
bool BlockManager::ReadRawBlock(std::vector<uint8_t>& block, const FlatFilePos& pos) const
10431043
{
1044-
FlatFilePos hpos = pos;
1045-
// If nPos is less than 8 the pos is null and we don't have the block data
1046-
// Return early to prevent undefined behavior of unsigned int underflow
1047-
if (hpos.nPos < 8) {
1048-
LogError("Failed for %s while reading raw block", pos.ToString());
1044+
if (pos.nPos < STORAGE_HEADER_BYTES) {
1045+
// If nPos is less than STORAGE_HEADER_BYTES, we can't read the header that precedes the block data
1046+
// This would cause an unsigned integer underflow when trying to position the file cursor
1047+
// This can happen after pruning or default constructed positions
1048+
LogError("Failed for %s while reading raw block storage header", pos.ToString());
10491049
return false;
10501050
}
1051-
hpos.nPos -= 8; // Seek back 8 bytes for meta header
1052-
AutoFile filein{OpenBlockFile(hpos, true)};
1051+
AutoFile filein{OpenBlockFile({pos.nFile, pos.nPos - STORAGE_HEADER_BYTES}, /*fReadOnly=*/true)};
10531052
if (filein.IsNull()) {
10541053
LogError("OpenBlockFile failed for %s while reading raw block", pos.ToString());
10551054
return false;
@@ -1091,7 +1090,7 @@ FlatFilePos BlockManager::WriteBlock(const CBlock& block, int nHeight)
10911090
LogError("FindNextBlockPos failed for %s while writing block", pos.ToString());
10921091
return FlatFilePos();
10931092
}
1094-
AutoFile fileout{OpenBlockFile(pos)};
1093+
AutoFile fileout{OpenBlockFile(pos, /*fReadOnly=*/false)};
10951094
if (fileout.IsNull()) {
10961095
LogError("OpenBlockFile failed for %s while writing block", pos.ToString());
10971096
m_opts.notifications.fatalError(_("Failed to write block."));
@@ -1210,7 +1209,7 @@ void ImportBlocks(ChainstateManager& chainman, std::span<const fs::path> import_
12101209
if (!fs::exists(chainman.m_blockman.GetBlockPosFilename(pos))) {
12111210
break; // No block files left to reindex
12121211
}
1213-
AutoFile file{chainman.m_blockman.OpenBlockFile(pos, true)};
1212+
AutoFile file{chainman.m_blockman.OpenBlockFile(pos, /*fReadOnly=*/true)};
12141213
if (file.IsNull()) {
12151214
break; // This error is logged in OpenBlockFile
12161215
}

src/node/blockstorage.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,10 @@ static const unsigned int UNDOFILE_CHUNK_SIZE = 0x100000; // 1 MiB
7575
static const unsigned int MAX_BLOCKFILE_SIZE = 0x8000000; // 128 MiB
7676

7777
/** Size of header written by WriteBlock before a serialized CBlock (8 bytes) */
78-
static constexpr size_t STORAGE_HEADER_BYTES{std::tuple_size_v<MessageStartChars> + sizeof(unsigned int)};
78+
static constexpr uint32_t STORAGE_HEADER_BYTES{std::tuple_size_v<MessageStartChars> + sizeof(unsigned int)};
7979

8080
/** Total overhead when writing undo data: header (8 bytes) plus checksum (32 bytes) */
81-
static constexpr size_t UNDO_DATA_DISK_OVERHEAD{STORAGE_HEADER_BYTES + uint256::size()};
81+
static constexpr uint32_t UNDO_DATA_DISK_OVERHEAD{STORAGE_HEADER_BYTES + uint256::size()};
8282

8383
// Because validation code takes pointers to the map's CBlockIndex objects, if
8484
// we ever switch to another associative container, we need to either use a
@@ -400,7 +400,7 @@ class BlockManager
400400
void UpdatePruneLock(const std::string& name, const PruneLockInfo& lock_info) EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
401401

402402
/** Open a block file (blk?????.dat) */
403-
AutoFile OpenBlockFile(const FlatFilePos& pos, bool fReadOnly = false) const;
403+
AutoFile OpenBlockFile(const FlatFilePos& pos, bool fReadOnly) const;
404404

405405
/** Translation to a filesystem path */
406406
fs::path GetBlockPosFilename(const FlatFilePos& pos) const;

src/streams.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,7 @@ class BufferedFile
523523
}
524524

525525
public:
526-
BufferedFile(AutoFile& file, uint64_t nBufSize, uint64_t nRewindIn)
526+
BufferedFile(AutoFile& file LIFETIMEBOUND, uint64_t nBufSize, uint64_t nRewindIn)
527527
: m_src{file}, nReadLimit{std::numeric_limits<uint64_t>::max()}, nRewind{nRewindIn}, vchBuf(nBufSize, std::byte{0})
528528
{
529529
if (nRewindIn >= nBufSize)

0 commit comments

Comments
 (0)