diff options
author | James O'Beirne <james.obeirne@pm.me> | 2022-02-02 09:47:13 -0500 |
---|---|---|
committer | James O'Beirne <james.obeirne@pm.me> | 2022-09-13 13:30:25 -0400 |
commit | 8153bd9247dad3982d54488bcdb3960470315290 (patch) | |
tree | 294d32393ae48eadc6238952ef8e2bfb38a03d0d | |
parent | ad67ff377c2b271cb4683da2fb25fd295557f731 (diff) |
blockmanager: avoid undefined behavior during FlushBlockFile
If we call FlushBlockFile() without having intitialized the block index
with LoadBlockIndexDB(), we may be indexing into an empty vector.
Specifically this is an issue when we call MaybeRebalanceCaches() during
chainstate init before the block index has been loaded, which calls
FlushBlockFile().
Also add an assert to avoid undefined behavior.
Co-authored-by: Russell Yanofsky <russ@yanofsky.org>
-rw-r--r-- | src/node/blockstorage.cpp | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/src/node/blockstorage.cpp b/src/node/blockstorage.cpp index 57f81e6bb6..9fea644f05 100644 --- a/src/node/blockstorage.cpp +++ b/src/node/blockstorage.cpp @@ -524,6 +524,16 @@ void BlockManager::FlushUndoFile(int block_file, bool finalize) void BlockManager::FlushBlockFile(bool fFinalize, bool finalize_undo) { LOCK(cs_LastBlockFile); + + if (m_blockfile_info.size() < 1) { + // Return if we haven't loaded any blockfiles yet. This happens during + // chainstate init, when we call ChainstateManager::MaybeRebalanceCaches() (which + // then calls FlushStateToDisk()), resulting in a call to this function before we + // have populated `m_blockfile_info` via LoadBlockIndexDB(). + return; + } + assert(static_cast<int>(m_blockfile_info.size()) > m_last_blockfile); + FlatFilePos block_pos_old(m_last_blockfile, m_blockfile_info[m_last_blockfile].nSize); if (!BlockFileSeq().Flush(block_pos_old, fFinalize)) { AbortNode("Flushing block file to disk failed. This is likely the result of an I/O error."); |