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