Branch data Line data Source code
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 : 5 : bool WriteSnapshotBaseBlockhash(Chainstate& snapshot_chainstate)
23 : : {
24 : 5 : AssertLockHeld(::cs_main);
25 [ - + ]: 5 : assert(snapshot_chainstate.m_from_snapshot_blockhash);
26 : :
27 : 5 : const std::optional<fs::path> chaindir = snapshot_chainstate.StoragePath();
28 [ - + ]: 5 : assert(chaindir); // Sanity check that chainstate isn't in-memory.
29 [ + - + - ]: 10 : const fs::path write_to = *chaindir / node::SNAPSHOT_BLOCKHASH_FILENAME;
30 : :
31 [ + - ]: 5 : FILE* file{fsbridge::fopen(write_to, "wb")};
32 [ + - ]: 10 : AutoFile afile{file};
33 [ - + ]: 5 : if (afile.IsNull()) {
34 [ # # # # ]: 0 : LogError("[snapshot] failed to open base blockhash file for writing: %s",
35 : : fs::PathToString(write_to));
36 : 0 : return false;
37 : : }
38 [ + - ]: 5 : afile << *snapshot_chainstate.m_from_snapshot_blockhash;
39 : :
40 [ + - - + ]: 10 : if (afile.fclose() != 0) {
41 [ # # # # ]: 0 : LogError("[snapshot] failed to close base blockhash file %s after writing",
42 : : fs::PathToString(write_to));
43 : 0 : return false;
44 : : }
45 : : return true;
46 [ + - ]: 15 : }
47 : :
48 : 6 : std::optional<uint256> ReadSnapshotBaseBlockhash(fs::path chaindir)
49 : : {
50 [ - + ]: 6 : if (!fs::exists(chaindir)) {
51 [ # # # # ]: 0 : LogWarning("[snapshot] cannot read base blockhash: no chainstate dir "
52 : : "exists at path %s", fs::PathToString(chaindir));
53 : 0 : return std::nullopt;
54 : : }
55 [ + - ]: 12 : const fs::path read_from = chaindir / node::SNAPSHOT_BLOCKHASH_FILENAME;
56 [ - + ]: 6 : const std::string read_from_str = fs::PathToString(read_from);
57 : :
58 [ + - - + ]: 6 : if (!fs::exists(read_from)) {
59 [ # # # # ]: 0 : LogWarning("[snapshot] snapshot chainstate dir is malformed! no base blockhash file "
60 : : "exists at path %s. Try deleting %s and calling loadtxoutset again?",
61 : : fs::PathToString(chaindir), read_from_str);
62 : 0 : return std::nullopt;
63 : : }
64 : :
65 : 6 : uint256 base_blockhash;
66 [ + - ]: 6 : FILE* file{fsbridge::fopen(read_from, "rb")};
67 [ + - ]: 12 : AutoFile afile{file};
68 [ - + ]: 6 : if (afile.IsNull()) {
69 [ # # ]: 0 : LogWarning("[snapshot] failed to open base blockhash file for reading: %s",
70 : : read_from_str);
71 : 0 : return std::nullopt;
72 : : }
73 [ + - ]: 6 : afile >> base_blockhash;
74 : :
75 [ + - ]: 6 : int64_t position = afile.tell();
76 [ + - ]: 6 : afile.seek(0, SEEK_END);
77 [ + - - + ]: 6 : if (position != afile.tell()) {
78 [ # # ]: 0 : LogWarning("[snapshot] unexpected trailing data in %s", read_from_str);
79 : : }
80 : 6 : return base_blockhash;
81 : 18 : }
82 : :
83 : 225 : std::optional<fs::path> FindAssumeutxoChainstateDir(const fs::path& data_dir)
84 : : {
85 : 225 : fs::path possible_dir =
86 [ - + + - : 1125 : data_dir / fs::u8path(strprintf("chainstate%s", SNAPSHOT_CHAINSTATE_SUFFIX));
+ - ]
87 : :
88 [ + - + + ]: 225 : if (fs::exists(possible_dir)) {
89 : 24 : return possible_dir;
90 : : }
91 : 201 : return std::nullopt;
92 : 225 : }
93 : :
94 : : } // namespace node
|