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