fuzz coverage

Coverage Report

Created: 2026-04-24 13:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/root/bitcoin/src/node/utxo_snapshot.cpp
Line
Count
Source
1
// Copyright (c) 2022-present The Bitcoin Core developers
2
// Distributed under the MIT software license, see the accompanying
3
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5
#include <node/utxo_snapshot.h>
6
7
#include <streams.h>
8
#include <sync.h>
9
#include <tinyformat.h>
10
#include <uint256.h>
11
#include <util/fs.h>
12
#include <util/log.h>
13
#include <validation.h>
14
15
#include <cassert>
16
#include <cstdio>
17
#include <optional>
18
#include <string>
19
20
namespace node {
21
22
bool WriteSnapshotBaseBlockhash(Chainstate& snapshot_chainstate)
23
0
{
24
0
    AssertLockHeld(::cs_main);
Line
Count
Source
144
0
#define AssertLockHeld(cs) AssertLockHeldInternal(#cs, __FILE__, __LINE__, &cs)
25
0
    assert(snapshot_chainstate.m_from_snapshot_blockhash);
26
27
0
    const std::optional<fs::path> chaindir = snapshot_chainstate.StoragePath();
28
0
    assert(chaindir); // Sanity check that chainstate isn't in-memory.
29
0
    const fs::path write_to = *chaindir / node::SNAPSHOT_BLOCKHASH_FILENAME;
30
31
0
    FILE* file{fsbridge::fopen(write_to, "wb")};
32
0
    AutoFile afile{file};
33
0
    if (afile.IsNull()) {
34
0
        LogError("[snapshot] failed to open base blockhash file for writing: %s",
Line
Count
Source
99
0
#define LogError(...) LogPrintLevel_(BCLog::LogFlags::ALL, BCLog::Level::Error, /*should_ratelimit=*/true, __VA_ARGS__)
Line
Count
Source
91
0
#define LogPrintLevel_(category, level, should_ratelimit, ...) LogPrintFormatInternal(SourceLocation{__func__}, category, level, should_ratelimit, __VA_ARGS__)
35
0
                  fs::PathToString(write_to));
36
0
        return false;
37
0
    }
38
0
    afile << *snapshot_chainstate.m_from_snapshot_blockhash;
39
40
0
    if (afile.fclose() != 0) {
41
0
        LogError("[snapshot] failed to close base blockhash file %s after writing",
Line
Count
Source
99
0
#define LogError(...) LogPrintLevel_(BCLog::LogFlags::ALL, BCLog::Level::Error, /*should_ratelimit=*/true, __VA_ARGS__)
Line
Count
Source
91
0
#define LogPrintLevel_(category, level, should_ratelimit, ...) LogPrintFormatInternal(SourceLocation{__func__}, category, level, should_ratelimit, __VA_ARGS__)
42
0
                  fs::PathToString(write_to));
43
0
        return false;
44
0
    }
45
0
    return true;
46
0
}
47
48
std::optional<uint256> ReadSnapshotBaseBlockhash(fs::path chaindir)
49
0
{
50
0
    if (!fs::exists(chaindir)) {
51
0
        LogWarning("[snapshot] cannot read base blockhash: no chainstate dir "
Line
Count
Source
98
0
#define LogWarning(...) LogPrintLevel_(BCLog::LogFlags::ALL, BCLog::Level::Warning, /*should_ratelimit=*/true, __VA_ARGS__)
Line
Count
Source
91
0
#define LogPrintLevel_(category, level, should_ratelimit, ...) LogPrintFormatInternal(SourceLocation{__func__}, category, level, should_ratelimit, __VA_ARGS__)
52
0
            "exists at path %s", fs::PathToString(chaindir));
53
0
        return std::nullopt;
54
0
    }
55
0
    const fs::path read_from = chaindir / node::SNAPSHOT_BLOCKHASH_FILENAME;
56
0
    const std::string read_from_str = fs::PathToString(read_from);
57
58
0
    if (!fs::exists(read_from)) {
59
0
        LogWarning("[snapshot] snapshot chainstate dir is malformed! no base blockhash file "
Line
Count
Source
98
0
#define LogWarning(...) LogPrintLevel_(BCLog::LogFlags::ALL, BCLog::Level::Warning, /*should_ratelimit=*/true, __VA_ARGS__)
Line
Count
Source
91
0
#define LogPrintLevel_(category, level, should_ratelimit, ...) LogPrintFormatInternal(SourceLocation{__func__}, category, level, should_ratelimit, __VA_ARGS__)
60
0
            "exists at path %s. Try deleting %s and calling loadtxoutset again?",
61
0
            fs::PathToString(chaindir), read_from_str);
62
0
        return std::nullopt;
63
0
    }
64
65
0
    uint256 base_blockhash;
66
0
    FILE* file{fsbridge::fopen(read_from, "rb")};
67
0
    AutoFile afile{file};
68
0
    if (afile.IsNull()) {
69
0
        LogWarning("[snapshot] failed to open base blockhash file for reading: %s",
Line
Count
Source
98
0
#define LogWarning(...) LogPrintLevel_(BCLog::LogFlags::ALL, BCLog::Level::Warning, /*should_ratelimit=*/true, __VA_ARGS__)
Line
Count
Source
91
0
#define LogPrintLevel_(category, level, should_ratelimit, ...) LogPrintFormatInternal(SourceLocation{__func__}, category, level, should_ratelimit, __VA_ARGS__)
70
0
            read_from_str);
71
0
        return std::nullopt;
72
0
    }
73
0
    afile >> base_blockhash;
74
75
0
    int64_t position = afile.tell();
76
0
    afile.seek(0, SEEK_END);
77
0
    if (position != afile.tell()) {
78
0
        LogWarning("[snapshot] unexpected trailing data in %s", read_from_str);
Line
Count
Source
98
0
#define LogWarning(...) LogPrintLevel_(BCLog::LogFlags::ALL, BCLog::Level::Warning, /*should_ratelimit=*/true, __VA_ARGS__)
Line
Count
Source
91
0
#define LogPrintLevel_(category, level, should_ratelimit, ...) LogPrintFormatInternal(SourceLocation{__func__}, category, level, should_ratelimit, __VA_ARGS__)
79
0
    }
80
0
    return base_blockhash;
81
0
}
82
83
std::optional<fs::path> FindAssumeutxoChainstateDir(const fs::path& data_dir)
84
147k
{
85
147k
    fs::path possible_dir =
86
147k
        data_dir / fs::u8path(strprintf("chainstate%s", SNAPSHOT_CHAINSTATE_SUFFIX));
Line
Count
Source
1172
147k
#define strprintf tfm::format
87
88
147k
    if (fs::exists(possible_dir)) {
89
0
        return possible_dir;
90
0
    }
91
147k
    return std::nullopt;
92
147k
}
93
94
} // namespace node