Repository: bitcoin/bitcoin
File: src/node/blockstorage.cpp (C++)

Code before:
        )};
        xor_key_file << xor_key;
    }
    // If the user disabled the key, it must be zero.
    if (!opts.use_xor && xor_key != decltype(xor_key){}) {
        throw std::runtime_error{
            strprintf("The blocksdir XOR-key can not be disabled when a random key was already stored! "
                      "Stored key: '%s', stored path: '%s'.",
                      HexStr(xor_key), fs::PathToString(xor_key_path)),
        };
    }
    LogInfo("Using obfuscation key for blocksdir *.dat files (%s): '%s'\n", fs::PathToString(opts.blocks_dir), HexStr(xor_key));
    return std::vector<std::byte>{xor_key.begin(), xor_key.end()};
}

BlockManager::BlockManager(const util::SignalInterrupt& interrupt, Options opts)
    : m_prune_mode{opts.prune_target > 0},
      m_xor_key{InitBlocksdirXorKey(opts)},
      m_opts{std::move(opts)},
      m_block_file_seq{FlatFileSeq{m_opts.blocks_dir, "blk", m_opts.fast_prune ? 0x4000 /* 16kB */ : BLOCKFILE_CHUNK_SIZE}},
      m_undo_file_seq{FlatFileSeq{m_opts.blocks_dir, "rev", UNDOFILE_CHUNK_SIZE}},
      m_interrupt{interrupt}
{
    m_block_tree_db = std::make_unique<BlockTreeDB>(m_opts.block_tree_db_params);

    if (m_opts.block_tree_db_params.wipe_data) {
        m_block_tree_db->WriteReindexing(true);
        m_blockfiles_indexed = false;
        // If we're reindexing in prune mode, wipe away unusable block files and all undo data files
        if (m_prune_mode) {
            CleanupBlockRevFiles();
        }
    }
}

class ImportingNow
{
    std::atomic<bool>& m_importing;

public:
    ImportingNow(std::atomic<bool>& importing) : m_importing{importing}
    {
        assert(m_importing == false);
        m_importing = true;
    }
    ~ImportingNow()
    {
        assert(m_importing == true);
        m_importing = false;
    }
};

Review comment (suggestion):
nit:
```suggestion
            throw std::runtime_error{strprintf("Error closing XOR key file %s: %s",
```

Code after:
    }

    const fs::path xor_key_path{opts.blocks_dir / "xor.dat"};
    if (fs::exists(xor_key_path)) {
        // A pre-existing xor key file has priority.
        AutoFile xor_key_file{fsbridge::fopen(xor_key_path, "rb")};
        xor_key_file >> xor_key;
    } else {
        // Create initial or missing xor key file
        AutoFile xor_key_file{fsbridge::fopen(xor_key_path,
#ifdef __MINGW64__
            "wb" // Temporary workaround for https://github.com/bitcoin/bitcoin/issues/30210
#else
            "wbx"
#endif
        )};
        xor_key_file << xor_key;
        if (xor_key_file.fclose() != 0) {
            throw std::runtime_error{strprintf("Error closing XOR key file %s: %s",
                                               fs::PathToString(xor_key_path),
                                               SysErrorString(errno))};
        }
    }
    // If the user disabled the key, it must be zero.
    if (!opts.use_xor && xor_key != decltype(xor_key){}) {
        throw std::runtime_error{
            strprintf("The blocksdir XOR-key can not be disabled when a random key was already stored! "
                      "Stored key: '%s', stored path: '%s'.",
                      HexStr(xor_key), fs::PathToString(xor_key_path)),
        };
    }
    LogInfo("Using obfuscation key for blocksdir *.dat files (%s): '%s'\n", fs::PathToString(opts.blocks_dir), HexStr(xor_key));
    return std::vector<std::byte>{xor_key.begin(), xor_key.end()};
}

BlockManager::BlockManager(const util::SignalInterrupt& interrupt, Options opts)
    : m_prune_mode{opts.prune_target > 0},
      m_xor_key{InitBlocksdirXorKey(opts)},
      m_opts{std::move(opts)},
      m_block_file_seq{FlatFileSeq{m_opts.blocks_dir, "blk", m_opts.fast_prune ? 0x4000 /* 16kB */ : BLOCKFILE_CHUNK_SIZE}},
      m_undo_file_seq{FlatFileSeq{m_opts.blocks_dir, "rev", UNDOFILE_CHUNK_SIZE}},
      m_interrupt{interrupt}
{
    m_block_tree_db = std::make_unique<BlockTreeDB>(m_opts.block_tree_db_params);

    if (m_opts.block_tree_db_params.wipe_data) {
        m_block_tree_db->WriteReindexing(true);
        m_blockfiles_indexed = false;
        // If we're reindexing in prune mode, wipe away unusable block files and all undo data files
        if (m_prune_mode) {
            CleanupBlockRevFiles();