Bitcoin Core 31.99.0
P2P Digital Currency
utxo_snapshot.cpp
Go to the documentation of this file.
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
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
20namespace node {
21
22bool WriteSnapshotBaseBlockhash(Chainstate& snapshot_chainstate)
23{
25 assert(snapshot_chainstate.m_from_snapshot_blockhash);
26
27 const std::optional<fs::path> chaindir = snapshot_chainstate.StoragePath();
28 assert(chaindir); // Sanity check that chainstate isn't in-memory.
29 const fs::path write_to = *chaindir / node::SNAPSHOT_BLOCKHASH_FILENAME;
30
31 FILE* file{fsbridge::fopen(write_to, "wb")};
32 AutoFile afile{file};
33 if (afile.IsNull()) {
34 LogError("[snapshot] failed to open base blockhash file for writing: %s",
35 fs::PathToString(write_to));
36 return false;
37 }
38 afile << *snapshot_chainstate.m_from_snapshot_blockhash;
39
40 if (afile.fclose() != 0) {
41 LogError("[snapshot] failed to close base blockhash file %s after writing",
42 fs::PathToString(write_to));
43 return false;
44 }
45 return true;
46}
47
48std::optional<uint256> ReadSnapshotBaseBlockhash(fs::path chaindir)
49{
50 if (!fs::exists(chaindir)) {
51 LogWarning("[snapshot] cannot read base blockhash: no chainstate dir "
52 "exists at path %s", fs::PathToString(chaindir));
53 return std::nullopt;
54 }
55 const fs::path read_from = chaindir / node::SNAPSHOT_BLOCKHASH_FILENAME;
56 const std::string read_from_str = fs::PathToString(read_from);
57
58 if (!fs::exists(read_from)) {
59 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 return std::nullopt;
63 }
64
65 uint256 base_blockhash;
66 FILE* file{fsbridge::fopen(read_from, "rb")};
67 AutoFile afile{file};
68 if (afile.IsNull()) {
69 LogWarning("[snapshot] failed to open base blockhash file for reading: %s",
70 read_from_str);
71 return std::nullopt;
72 }
73 afile >> base_blockhash;
74
75 int64_t position = afile.tell();
76 afile.seek(0, SEEK_END);
77 if (position != afile.tell()) {
78 LogWarning("[snapshot] unexpected trailing data in %s", read_from_str);
79 }
80 return base_blockhash;
81}
82
83std::optional<fs::path> FindAssumeutxoChainstateDir(const fs::path& data_dir)
84{
85 fs::path possible_dir =
86 data_dir / fs::u8path(strprintf("chainstate%s", SNAPSHOT_CHAINSTATE_SUFFIX));
87
88 if (fs::exists(possible_dir)) {
89 return possible_dir;
90 }
91 return std::nullopt;
92}
93
94} // namespace node
Non-refcounted RAII wrapper for FILE*.
Definition: streams.h:373
Chainstate stores and provides an API to update our local knowledge of the current best chain.
Definition: validation.h:551
const std::optional< uint256 > m_from_snapshot_blockhash
The blockhash which is the base of the snapshot this chainstate was created from.
Definition: validation.h:637
fs::path StoragePath() const
Return path to chainstate leveldb directory.
256-bit opaque blob.
Definition: uint256.h:195
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
Definition: cs_main.cpp:8
static path u8path(std::string_view utf8_str)
Definition: fs.h:81
static bool exists(const path &p)
Definition: fs.h:95
static std::string PathToString(const path &path)
Convert path object to a byte string.
Definition: fs.h:161
#define LogWarning(...)
Definition: log.h:98
#define LogError(...)
Definition: log.h:99
FILE * fopen(const fs::path &p, const char *mode)
Definition: fs.cpp:25
Definition: messages.h:21
const fs::path SNAPSHOT_BLOCKHASH_FILENAME
The file in the snapshot chainstate dir which stores the base blockhash.
bool WriteSnapshotBaseBlockhash(Chainstate &snapshot_chainstate)
std::optional< fs::path > FindAssumeutxoChainstateDir(const fs::path &data_dir)
Return a path to the snapshot-based chainstate dir, if one exists.
bool WriteSnapshotBaseBlockhash(Chainstate &snapshot_chainstate) EXCLUSIVE_LOCKS_REQUIRED(std::optional< uint256 > ReadSnapshotBaseBlockhash(fs::path chaindir) EXCLUSIVE_LOCKS_REQUIRED(constexpr std::string_view SNAPSHOT_CHAINSTATE_SUFFIX
Write out the blockhash of the snapshot base block that was used to construct this chainstate.
std::optional< uint256 > ReadSnapshotBaseBlockhash(fs::path chaindir)
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1172
AssertLockHeld(pool.cs)
assert(!tx.IsCoinBase())