/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 |