Coverage Report

Created: 2024-10-29 12:10

/root/bitcoin/src/node/utxo_snapshot.cpp
Line
Count
Source (jump to first uncovered line)
1
// Copyright (c) 2022 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 <logging.h>
8
#include <streams.h>
9
#include <sync.h>
10
#include <tinyformat.h>
11
#include <txdb.h>
12
#include <uint256.h>
13
#include <util/fs.h>
14
#include <validation.h>
15
16
#include <cassert>
17
#include <cstdio>
18
#include <optional>
19
#include <string>
20
21
namespace node {
22
23
bool WriteSnapshotBaseBlockhash(Chainstate& snapshot_chainstate)
24
0
{
25
0
    AssertLockHeld(::cs_main);
26
0
    assert(snapshot_chainstate.m_from_snapshot_blockhash);
27
28
0
    const std::optional<fs::path> chaindir = snapshot_chainstate.CoinsDB().StoragePath();
29
0
    assert(chaindir); // Sanity check that chainstate isn't in-memory.
30
0
    const fs::path write_to = *chaindir / node::SNAPSHOT_BLOCKHASH_FILENAME;
31
32
0
    FILE* file{fsbridge::fopen(write_to, "wb")};
33
0
    AutoFile afile{file};
34
0
    if (afile.IsNull()) {
35
0
        LogPrintf("[snapshot] failed to open base blockhash file for writing: %s\n",
36
0
                  fs::PathToString(write_to));
37
0
        return false;
38
0
    }
39
0
    afile << *snapshot_chainstate.m_from_snapshot_blockhash;
40
41
0
    if (afile.fclose() != 0) {
42
0
        LogPrintf("[snapshot] failed to close base blockhash file %s after writing\n",
43
0
                  fs::PathToString(write_to));
44
0
        return false;
45
0
    }
46
0
    return true;
47
0
}
48
49
std::optional<uint256> ReadSnapshotBaseBlockhash(fs::path chaindir)
50
0
{
51
0
    if (!fs::exists(chaindir)) {
52
0
        LogPrintf("[snapshot] cannot read base blockhash: no chainstate dir "
53
0
            "exists at path %s\n", fs::PathToString(chaindir));
54
0
        return std::nullopt;
55
0
    }
56
0
    const fs::path read_from = chaindir / node::SNAPSHOT_BLOCKHASH_FILENAME;
57
0
    const std::string read_from_str = fs::PathToString(read_from);
58
59
0
    if (!fs::exists(read_from)) {
60
0
        LogPrintf("[snapshot] snapshot chainstate dir is malformed! no base blockhash file "
61
0
            "exists at path %s. Try deleting %s and calling loadtxoutset again?\n",
62
0
            fs::PathToString(chaindir), read_from_str);
63
0
        return std::nullopt;
64
0
    }
65
66
0
    uint256 base_blockhash;
67
0
    FILE* file{fsbridge::fopen(read_from, "rb")};
68
0
    AutoFile afile{file};
69
0
    if (afile.IsNull()) {
70
0
        LogPrintf("[snapshot] failed to open base blockhash file for reading: %s\n",
71
0
            read_from_str);
72
0
        return std::nullopt;
73
0
    }
74
0
    afile >> base_blockhash;
75
76
0
    int64_t position = afile.tell();
77
0
    afile.seek(0, SEEK_END);
78
0
    if (position != afile.tell()) {
79
0
        LogPrintf("[snapshot] warning: unexpected trailing data in %s\n", read_from_str);
80
0
    }
81
0
    return base_blockhash;
82
0
}
83
84
std::optional<fs::path> FindSnapshotChainstateDir(const fs::path& data_dir)
85
0
{
86
0
    fs::path possible_dir =
87
0
        data_dir / fs::u8path(strprintf("chainstate%s", SNAPSHOT_CHAINSTATE_SUFFIX));
88
89
0
    if (fs::exists(possible_dir)) {
90
0
        return possible_dir;
91
0
    }
92
0
    return std::nullopt;
93
0
}
94
95
} // namespace node