aboutsummaryrefslogtreecommitdiff
path: root/src/node
diff options
context:
space:
mode:
authorJames O'Beirne <james.obeirne@pm.me>2022-02-02 09:47:13 -0500
committerJames O'Beirne <james.obeirne@pm.me>2022-09-13 13:30:25 -0400
commit8153bd9247dad3982d54488bcdb3960470315290 (patch)
tree294d32393ae48eadc6238952ef8e2bfb38a03d0d /src/node
parentad67ff377c2b271cb4683da2fb25fd295557f731 (diff)
downloadbitcoin-8153bd9247dad3982d54488bcdb3960470315290.tar.xz
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>
Diffstat (limited to 'src/node')
-rw-r--r--src/node/blockstorage.cpp10
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.");